Merge "Fix the build" into klp-dev
diff --git a/Android.mk b/Android.mk
index 13b717a..49dc6af 100644
--- a/Android.mk
+++ b/Android.mk
@@ -433,6 +433,7 @@
 
 non_base_dirs := \
 	../../external/apache-http/src/org/apache/http \
+	../opt/telephony/src/java/android/provider \
 	../opt/telephony/src/java/android/telephony \
 	../opt/telephony/src/java/android/telephony/gsm \
 	../opt/net/voip/src/java/android/net/rtp \
diff --git a/api/current.txt b/api/current.txt
index 37881e6..ff72c4a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33,6 +33,7 @@
     field public static final java.lang.String BIND_WALLPAPER = "android.permission.BIND_WALLPAPER";
     field public static final java.lang.String BLUETOOTH = "android.permission.BLUETOOTH";
     field public static final java.lang.String BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";
+    field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
     field public static final java.lang.String BRICK = "android.permission.BRICK";
     field public static final java.lang.String BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";
     field public static final java.lang.String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
@@ -5103,6 +5104,7 @@
 
   public final class BluetoothDevice implements android.os.Parcelable {
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
+    method public boolean createBond();
     method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public int describeContents();
@@ -5113,6 +5115,8 @@
     method public java.lang.String getName();
     method public int getType();
     method public android.os.ParcelUuid[] getUuids();
+    method public boolean setPairingConfirmation(boolean);
+    method public boolean setPin(byte[]);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final java.lang.String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
     field public static final java.lang.String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED";
@@ -5121,6 +5125,7 @@
     field public static final java.lang.String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED";
     field public static final java.lang.String ACTION_FOUND = "android.bluetooth.device.action.FOUND";
     field public static final java.lang.String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
+    field public static final java.lang.String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
     field public static final java.lang.String ACTION_UUID = "android.bluetooth.device.action.UUID";
     field public static final int BOND_BONDED = 12; // 0xc
     field public static final int BOND_BONDING = 11; // 0xb
@@ -5135,9 +5140,13 @@
     field public static final java.lang.String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
     field public static final java.lang.String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
     field public static final java.lang.String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
+    field public static final java.lang.String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
+    field public static final java.lang.String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT";
     field public static final java.lang.String EXTRA_PREVIOUS_BOND_STATE = "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
     field public static final java.lang.String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
     field public static final java.lang.String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
+    field public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; // 0x2
+    field public static final int PAIRING_VARIANT_PIN = 0; // 0x0
   }
 
   public final class BluetoothGatt implements android.bluetooth.BluetoothProfile {
@@ -21727,6 +21736,277 @@
     method public static void update(android.content.ContentProviderClient, android.net.Uri, byte[]) throws android.os.RemoteException;
   }
 
+  public final class Telephony {
+  }
+
+  public static abstract interface Telephony.BaseMmsColumns implements android.provider.BaseColumns {
+    field public static final java.lang.String CONTENT_CLASS = "ct_cls";
+    field public static final java.lang.String CONTENT_LOCATION = "ct_l";
+    field public static final java.lang.String CONTENT_TYPE = "ct_t";
+    field public static final java.lang.String DATE = "date";
+    field public static final java.lang.String DATE_SENT = "date_sent";
+    field public static final java.lang.String DELIVERY_REPORT = "d_rpt";
+    field public static final java.lang.String DELIVERY_TIME = "d_tm";
+    field public static final java.lang.String EXPIRY = "exp";
+    field public static final java.lang.String LOCKED = "locked";
+    field public static final java.lang.String MESSAGE_BOX = "msg_box";
+    field public static final int MESSAGE_BOX_ALL = 0; // 0x0
+    field public static final int MESSAGE_BOX_DRAFTS = 3; // 0x3
+    field public static final int MESSAGE_BOX_INBOX = 1; // 0x1
+    field public static final int MESSAGE_BOX_OUTBOX = 4; // 0x4
+    field public static final int MESSAGE_BOX_SENT = 2; // 0x2
+    field public static final java.lang.String MESSAGE_CLASS = "m_cls";
+    field public static final java.lang.String MESSAGE_ID = "m_id";
+    field public static final java.lang.String MESSAGE_SIZE = "m_size";
+    field public static final java.lang.String MESSAGE_TYPE = "m_type";
+    field public static final java.lang.String MMS_VERSION = "v";
+    field public static final java.lang.String PRIORITY = "pri";
+    field public static final java.lang.String READ = "read";
+    field public static final java.lang.String READ_REPORT = "rr";
+    field public static final java.lang.String READ_STATUS = "read_status";
+    field public static final java.lang.String REPORT_ALLOWED = "rpt_a";
+    field public static final java.lang.String RESPONSE_STATUS = "resp_st";
+    field public static final java.lang.String RESPONSE_TEXT = "resp_txt";
+    field public static final java.lang.String RETRIEVE_STATUS = "retr_st";
+    field public static final java.lang.String RETRIEVE_TEXT = "retr_txt";
+    field public static final java.lang.String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
+    field public static final java.lang.String SEEN = "seen";
+    field public static final java.lang.String STATUS = "st";
+    field public static final java.lang.String SUBJECT = "sub";
+    field public static final java.lang.String SUBJECT_CHARSET = "sub_cs";
+    field public static final java.lang.String TEXT_ONLY = "text_only";
+    field public static final java.lang.String THREAD_ID = "thread_id";
+    field public static final java.lang.String TRANSACTION_ID = "tr_id";
+  }
+
+  public static abstract interface Telephony.CanonicalAddressesColumns implements android.provider.BaseColumns {
+    field public static final java.lang.String ADDRESS = "address";
+  }
+
+  public static final class Telephony.Carriers implements android.provider.BaseColumns {
+    field public static final java.lang.String APN = "apn";
+    field public static final java.lang.String AUTH_TYPE = "authtype";
+    field public static final java.lang.String BEARER = "bearer";
+    field public static final java.lang.String CARRIER_ENABLED = "carrier_enabled";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String CURRENT = "current";
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "name ASC";
+    field public static final java.lang.String MCC = "mcc";
+    field public static final java.lang.String MMSC = "mmsc";
+    field public static final java.lang.String MMSPORT = "mmsport";
+    field public static final java.lang.String MMSPROXY = "mmsproxy";
+    field public static final java.lang.String MNC = "mnc";
+    field public static final java.lang.String MVNO_MATCH_DATA = "mvno_match_data";
+    field public static final java.lang.String MVNO_TYPE = "mvno_type";
+    field public static final java.lang.String NAME = "name";
+    field public static final java.lang.String NUMERIC = "numeric";
+    field public static final java.lang.String PASSWORD = "password";
+    field public static final java.lang.String PORT = "port";
+    field public static final java.lang.String PROTOCOL = "protocol";
+    field public static final java.lang.String PROXY = "proxy";
+    field public static final java.lang.String ROAMING_PROTOCOL = "roaming_protocol";
+    field public static final java.lang.String SERVER = "server";
+    field public static final java.lang.String TYPE = "type";
+    field public static final java.lang.String USER = "user";
+  }
+
+  public static final class Telephony.Mms implements android.provider.Telephony.BaseMmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+    field public static final android.net.Uri REPORT_REQUEST_URI;
+    field public static final android.net.Uri REPORT_STATUS_URI;
+  }
+
+  public static final class Telephony.Mms.Addr implements android.provider.BaseColumns {
+    field public static final java.lang.String ADDRESS = "address";
+    field public static final java.lang.String CHARSET = "charset";
+    field public static final java.lang.String CONTACT_ID = "contact_id";
+    field public static final java.lang.String MSG_ID = "msg_id";
+    field public static final java.lang.String TYPE = "type";
+  }
+
+  public static final class Telephony.Mms.Draft implements android.provider.Telephony.BaseMmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.Mms.Inbox implements android.provider.Telephony.BaseMmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.Mms.Intents {
+    field public static final java.lang.String CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED";
+    field public static final java.lang.String DELETED_CONTENTS = "deleted_contents";
+  }
+
+  public static final class Telephony.Mms.Outbox implements android.provider.Telephony.BaseMmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.Mms.Part implements android.provider.BaseColumns {
+    field public static final java.lang.String CHARSET = "chset";
+    field public static final java.lang.String CONTENT_DISPOSITION = "cd";
+    field public static final java.lang.String CONTENT_ID = "cid";
+    field public static final java.lang.String CONTENT_LOCATION = "cl";
+    field public static final java.lang.String CONTENT_TYPE = "ct";
+    field public static final java.lang.String CT_START = "ctt_s";
+    field public static final java.lang.String CT_TYPE = "ctt_t";
+    field public static final java.lang.String FILENAME = "fn";
+    field public static final java.lang.String MSG_ID = "mid";
+    field public static final java.lang.String NAME = "name";
+    field public static final java.lang.String SEQ = "seq";
+    field public static final java.lang.String TEXT = "text";
+    field public static final java.lang.String _DATA = "_data";
+  }
+
+  public static final class Telephony.Mms.Rate {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String SENT_TIME = "sent_time";
+  }
+
+  public static final class Telephony.Mms.Sent implements android.provider.Telephony.BaseMmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.MmsSms implements android.provider.BaseColumns {
+    field public static final android.net.Uri CONTENT_CONVERSATIONS_URI;
+    field public static final android.net.Uri CONTENT_DRAFT_URI;
+    field public static final android.net.Uri CONTENT_FILTER_BYPHONE_URI;
+    field public static final android.net.Uri CONTENT_LOCKED_URI;
+    field public static final android.net.Uri CONTENT_UNDELIVERED_URI;
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final int ERR_TYPE_GENERIC = 1; // 0x1
+    field public static final int ERR_TYPE_GENERIC_PERMANENT = 10; // 0xa
+    field public static final int ERR_TYPE_MMS_PROTO_PERMANENT = 12; // 0xc
+    field public static final int ERR_TYPE_MMS_PROTO_TRANSIENT = 3; // 0x3
+    field public static final int ERR_TYPE_SMS_PROTO_PERMANENT = 11; // 0xb
+    field public static final int ERR_TYPE_SMS_PROTO_TRANSIENT = 2; // 0x2
+    field public static final int ERR_TYPE_TRANSPORT_FAILURE = 4; // 0x4
+    field public static final int MMS_PROTO = 1; // 0x1
+    field public static final int NO_ERROR = 0; // 0x0
+    field public static final android.net.Uri SEARCH_URI;
+    field public static final int SMS_PROTO = 0; // 0x0
+    field public static final java.lang.String TYPE_DISCRIMINATOR_COLUMN = "transport_type";
+  }
+
+  public static final class Telephony.MmsSms.PendingMessages implements android.provider.BaseColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DUE_TIME = "due_time";
+    field public static final java.lang.String ERROR_CODE = "err_code";
+    field public static final java.lang.String ERROR_TYPE = "err_type";
+    field public static final java.lang.String LAST_TRY = "last_try";
+    field public static final java.lang.String MSG_ID = "msg_id";
+    field public static final java.lang.String MSG_TYPE = "msg_type";
+    field public static final java.lang.String PROTO_TYPE = "proto_type";
+    field public static final java.lang.String RETRY_INDEX = "retry_index";
+  }
+
+  public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+    method public static java.lang.String getDefaultSmsPackage(android.content.Context);
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.Sms.Conversations implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+    field public static final java.lang.String MESSAGE_COUNT = "msg_count";
+    field public static final java.lang.String SNIPPET = "snippet";
+  }
+
+  public static final class Telephony.Sms.Draft implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.Sms.Inbox implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.Sms.Intents {
+    method public static android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent);
+    field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
+    field public static final java.lang.String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+    field public static final java.lang.String EXTRA_PACKAGE_NAME = "package";
+    field public static final int RESULT_SMS_DUPLICATED = 5; // 0x5
+    field public static final int RESULT_SMS_GENERIC_ERROR = 2; // 0x2
+    field public static final int RESULT_SMS_HANDLED = 1; // 0x1
+    field public static final int RESULT_SMS_OUT_OF_MEMORY = 3; // 0x3
+    field public static final int RESULT_SMS_UNSUPPORTED = 4; // 0x4
+    field public static final java.lang.String SIM_FULL_ACTION = "android.provider.Telephony.SIM_FULL";
+    field public static final java.lang.String SMS_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_CB_RECEIVED";
+    field public static final java.lang.String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER";
+    field public static final java.lang.String SMS_EMERGENCY_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
+    field public static final java.lang.String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
+    field public static final java.lang.String SMS_REJECTED_ACTION = "android.provider.Telephony.SMS_REJECTED";
+    field public static final java.lang.String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION = "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
+    field public static final java.lang.String WAP_PUSH_DELIVER_ACTION = "android.provider.Telephony.WAP_PUSH_DELIVER";
+    field public static final java.lang.String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
+  }
+
+  public static final class Telephony.Sms.Outbox implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static final class Telephony.Sms.Sent implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
+  }
+
+  public static abstract interface Telephony.TextBasedSmsColumns {
+    field public static final java.lang.String ADDRESS = "address";
+    field public static final java.lang.String BODY = "body";
+    field public static final java.lang.String DATE = "date";
+    field public static final java.lang.String DATE_SENT = "date_sent";
+    field public static final java.lang.String ERROR_CODE = "error_code";
+    field public static final java.lang.String LOCKED = "locked";
+    field public static final int MESSAGE_TYPE_ALL = 0; // 0x0
+    field public static final int MESSAGE_TYPE_DRAFT = 3; // 0x3
+    field public static final int MESSAGE_TYPE_FAILED = 5; // 0x5
+    field public static final int MESSAGE_TYPE_INBOX = 1; // 0x1
+    field public static final int MESSAGE_TYPE_OUTBOX = 4; // 0x4
+    field public static final int MESSAGE_TYPE_QUEUED = 6; // 0x6
+    field public static final int MESSAGE_TYPE_SENT = 2; // 0x2
+    field public static final java.lang.String PERSON = "person";
+    field public static final java.lang.String PROTOCOL = "protocol";
+    field public static final java.lang.String READ = "read";
+    field public static final java.lang.String REPLY_PATH_PRESENT = "reply_path_present";
+    field public static final java.lang.String SEEN = "seen";
+    field public static final java.lang.String SERVICE_CENTER = "service_center";
+    field public static final java.lang.String STATUS = "status";
+    field public static final int STATUS_COMPLETE = 0; // 0x0
+    field public static final int STATUS_FAILED = 64; // 0x40
+    field public static final int STATUS_NONE = -1; // 0xffffffff
+    field public static final int STATUS_PENDING = 32; // 0x20
+    field public static final java.lang.String SUBJECT = "subject";
+    field public static final java.lang.String THREAD_ID = "thread_id";
+    field public static final java.lang.String TYPE = "type";
+  }
+
+  public static final class Telephony.Threads implements android.provider.Telephony.ThreadsColumns {
+    field public static final int BROADCAST_THREAD = 1; // 0x1
+    field public static final int COMMON_THREAD = 0; // 0x0
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri OBSOLETE_THREADS_URI;
+  }
+
+  public static abstract interface Telephony.ThreadsColumns implements android.provider.BaseColumns {
+    field public static final java.lang.String DATE = "date";
+    field public static final java.lang.String ERROR = "error";
+    field public static final java.lang.String HAS_ATTACHMENT = "has_attachment";
+    field public static final java.lang.String MESSAGE_COUNT = "message_count";
+    field public static final java.lang.String READ = "read";
+    field public static final java.lang.String RECIPIENT_IDS = "recipient_ids";
+    field public static final java.lang.String SNIPPET = "snippet";
+    field public static final java.lang.String SNIPPET_CHARSET = "snippet_cs";
+    field public static final java.lang.String TYPE = "type";
+  }
+
   public class UserDictionary {
     ctor public UserDictionary();
     field public static final java.lang.String AUTHORITY = "user_dictionary";
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 2c85382..1efdc81 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -219,7 +219,7 @@
      * {@link #BOND_NONE},
      * {@link #BOND_BONDING},
      * {@link #BOND_BONDED}.
-      */
+     */
     public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
     /**
      * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
@@ -228,7 +228,7 @@
      * {@link #BOND_NONE},
      * {@link #BOND_BONDING},
      * {@link #BOND_BONDED}.
-      */
+     */
     public static final String EXTRA_PREVIOUS_BOND_STATE =
             "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
     /**
@@ -253,12 +253,26 @@
      */
     public static final int BOND_BONDED = 12;
 
-    /** @hide */
+    /**
+     * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
+     * intents for unbond reason.
+     * @hide
+     */
     public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
-    /** @hide */
+
+    /**
+     * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
+     * intents to indicate pairing method used. Possible values are:
+     * {@link #PAIRING_VARIANT_PIN},
+     * {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION},
+     */
     public static final String EXTRA_PAIRING_VARIANT =
             "android.bluetooth.device.extra.PAIRING_VARIANT";
-    /** @hide */
+
+    /**
+     * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
+     * intents as the value of passkey.
+     */
     public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
 
     /**
@@ -306,7 +320,10 @@
     public static final String ACTION_NAME_FAILED =
             "android.bluetooth.device.action.NAME_FAILED";
 
-    /** @hide */
+    /**
+     * Broadcast Action: This intent is used to broadcast PAIRING REQUEST
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PAIRING_REQUEST =
             "android.bluetooth.device.action.PAIRING_REQUEST";
@@ -446,8 +463,8 @@
     public static final int UNBOND_REASON_REMOVED = 9;
 
     /**
-     * The user will be prompted to enter a pin
-     * @hide
+     * The user will be prompted to enter a pin or
+     * a privileged app will enter a pin for user.
      */
     public static final int PAIRING_VARIANT_PIN = 0;
 
@@ -458,8 +475,8 @@
     public static final int PAIRING_VARIANT_PASSKEY = 1;
 
     /**
-     * The user will be prompted to confirm the passkey displayed on the screen
-     * @hide
+     * The user will be prompted to confirm the passkey displayed on the screen or
+     * a privileged app will confirm the passkey for the user.
      */
     public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
 
@@ -707,10 +724,9 @@
      * the bonding process completes, and its result.
      * <p>Android system services will handle the necessary user interactions
      * to confirm and complete the bonding process.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
      *
      * @return false on immediate error, true if bonding will begin
-     * @hide
      */
     public boolean createBond() {
         if (sService == null) {
@@ -946,7 +962,13 @@
          return BluetoothDevice.ERROR;
     }
 
-    /** @hide */
+    /**
+     * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
+     *
+     * @return true pin has been set
+     *         false for error
+     */
     public boolean setPin(byte[] pin) {
         if (sService == null) {
             Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
@@ -968,7 +990,13 @@
         return false;
     }
 
-    /** @hide */
+    /**
+     * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
+     *
+     * @return true confirmation has been sent out
+     *         false for error
+     */
     public boolean setPairingConfirmation(boolean confirm) {
         if (sService == null) {
             Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3334e28..3769e1e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2797,7 +2797,6 @@
             MOVED_TO_GLOBAL.add(Settings.Global.USB_MASS_STORAGE_ENABLED);
             MOVED_TO_GLOBAL.add(Settings.Global.USE_GOOGLE_MAIL);
             MOVED_TO_GLOBAL.add(Settings.Global.WEB_AUTOFILL_QUERY_URL);
-            MOVED_TO_GLOBAL.add(Settings.Global.WIFI_COUNTRY_CODE);
             MOVED_TO_GLOBAL.add(Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS);
             MOVED_TO_GLOBAL.add(Settings.Global.WIFI_FREQUENCY_BAND);
             MOVED_TO_GLOBAL.add(Settings.Global.WIFI_IDLE_MS);
@@ -5222,12 +5221,6 @@
                "wifi_networks_available_repeat_delay";
 
        /**
-        * 802.11 country code in ISO 3166 format
-        * @hide
-        */
-       public static final String WIFI_COUNTRY_CODE = "wifi_country_code";
-
-       /**
         * The interval in milliseconds to issue wake up scans when wifi needs
         * to connect. This is necessary to connect to an access point when
         * device is on the move and the screen is off.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c67e036..48f0f9e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -18725,6 +18725,11 @@
                 = new ViewTreeObserver.InternalInsetsInfo();
 
         /**
+         * Set to true when mGivenInternalInsets is non-empty.
+         */
+        boolean mHasNonEmptyGivenInternalInsets;
+
+        /**
          * All views in the window's hierarchy that serve as scroll containers,
          * used to determine if the window can be resized or must be panned
          * to adjust for a soft input area.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 28f7480..76ebb6f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1348,8 +1348,12 @@
                 || (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT &&
                         frame.height() < desiredWindowHeight && frame.height() != mHeight));
 
+        // Determine whether to compute insets.
+        // If there are no inset listeners remaining then we may still need to compute
+        // insets in case the old insets were non-empty and must be reset.
         final boolean computesInternalInsets =
-                attachInfo.mTreeObserver.hasComputeInternalInsetsListeners();
+                attachInfo.mTreeObserver.hasComputeInternalInsetsListeners()
+                || attachInfo.mHasNonEmptyGivenInternalInsets;
 
         boolean insetsPending = false;
         int relayoutResult = 0;
@@ -1764,6 +1768,7 @@
 
             // Compute new insets in place.
             attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
+            attachInfo.mHasNonEmptyGivenInternalInsets = !insets.isEmpty();
 
             // Tell the window manager.
             if (insetsPending || !mLastGivenInsets.equals(insets)) {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index f9298ea..a9444b4 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -241,6 +241,13 @@
             mTouchableInsets = TOUCHABLE_INSETS_FRAME;
         }
 
+        boolean isEmpty() {
+            return contentInsets.isEmpty()
+                    && visibleInsets.isEmpty()
+                    && touchableRegion.isEmpty()
+                    && mTouchableInsets == TOUCHABLE_INSETS_FRAME;
+        }
+
         @Override
         public int hashCode() {
             int result = contentInsets.hashCode();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 41a8fd1..6f832cfd 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2231,12 +2231,10 @@
         View scrapView;
 
         scrapView = mRecycler.getTransientStateView(position);
-        if (scrapView != null) {
-            return scrapView;
+        if (scrapView == null) {
+            scrapView = mRecycler.getScrapView(position);
         }
 
-        scrapView = mRecycler.getScrapView(position);
-
         View child;
         if (scrapView != null) {
             child = mAdapter.getView(position, scrapView, this);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b41b5b5..15e1d0f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -773,6 +773,13 @@
         android:description="@string/permdesc_bluetoothAdmin"
         android:label="@string/permlab_bluetoothAdmin" />
 
+    <!-- Allows applications to pair bluetooth devices without user interaction -->
+    <permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
+        android:permissionGroup="android.permission-group.BLUETOOTH_NETWORK"
+        android:protectionLevel="system|signature"
+        android:description="@string/permdesc_bluetoothPriv"
+        android:label="@string/permlab_bluetoothPriv" />
+
     <!-- Allows bluetooth stack to access files
          @hide This should only be used by Bluetooth apk.
     -->
@@ -2243,7 +2250,7 @@
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
         android:label="@string/permlab_batteryStats"
         android:description="@string/permdesc_batteryStats"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to control the backup and restore process.
     <p>Not for use by third-party applications.
diff --git a/core/res/res/drawable-hdpi/toast_frame_holo.9.png b/core/res/res/drawable-hdpi/toast_frame_holo.9.png
index f0d9b21..a804a8a 100644
--- a/core/res/res/drawable-hdpi/toast_frame_holo.9.png
+++ b/core/res/res/drawable-hdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/toast_frame_holo.9.png b/core/res/res/drawable-mdpi/toast_frame_holo.9.png
index 458137c..778e4e6 100644
--- a/core/res/res/drawable-mdpi/toast_frame_holo.9.png
+++ b/core/res/res/drawable-mdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/toast_frame_holo.9.png b/core/res/res/drawable-xhdpi/toast_frame_holo.9.png
index f1209a2..77e69c7 100644
--- a/core/res/res/drawable-xhdpi/toast_frame_holo.9.png
+++ b/core/res/res/drawable-xhdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/toast_frame_holo.9.png b/core/res/res/drawable-xxhdpi/toast_frame_holo.9.png
index 6c86258..edecb63 100644
--- a/core/res/res/drawable-xxhdpi/toast_frame_holo.9.png
+++ b/core/res/res/drawable-xxhdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6019e36..e39fd2a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -352,6 +352,10 @@
     <!-- Wifi driver supports batched scan -->
     <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
 
+    <!-- Default wifi country code.  If the device is going to be sold in the US this
+         needs to be US.  Uses ISO 3166 country code -->
+    <string translatable="false" name="config_wifi_default_country_code">US</string>
+
     <!-- Flag indicating whether the we should enable the automatic brightness in Settings.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d0c24e2..6c334e2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1801,6 +1801,15 @@
     <string name="permdesc_bluetoothAdmin" product="default">Allows the app to configure
       the local Bluetooth phone, and to discover and pair with remote devices.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bluetoothPriv">allow Bluetooth pairing by Application</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bluetoothPriv" product="tablet">Allows the app to
+      pair with remote devices without user interaction.</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bluetoothPriv" product="default">Allows the app to
+      pair with remote devices without user interaction.</string>
+
     <string name="permlab_accessWimaxState">connect and disconnect from WiMAX</string>
     <string name="permdesc_accessWimaxState">Allows the app to determine whether
      WiMAX is enabled and information about any WiMAX networks that are
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f739bed..c786888 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -817,6 +817,7 @@
   <java-symbol type="string" name="wifi_tether_configure_ssid_default" />
   <java-symbol type="string" name="wifi_watchdog_network_disabled" />
   <java-symbol type="string" name="wifi_watchdog_network_disabled_detailed" />
+  <java-symbol type="string" name="config_wifi_default_country_code" />
   <java-symbol type="string" name="imei" />
   <java-symbol type="string" name="meid" />
   <java-symbol type="string" name="granularity_label_character" />
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1941859..c8ee5ad 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2281,10 +2281,9 @@
         }
         IAudioService service = getService();
         try {
+            int[] artworkDimensions = rctlr.getArtworkSize();
             boolean reg = service.registerRemoteControlDisplay(rctlr.getRcDisplay(),
-                    // passing a negative value for art work width and height
-                    //   as they are still unknown at this stage
-                    /*w*/-1, /*h*/ -1);
+                    artworkDimensions[0]/*w*/, artworkDimensions[1]/*h*/);
             rctlr.setIsRegistered(reg);
             return reg;
         } catch (RemoteException e) {
diff --git a/media/java/android/media/IRemoteControlClient.aidl b/media/java/android/media/IRemoteControlClient.aidl
index 48079f2..999b8ba 100644
--- a/media/java/android/media/IRemoteControlClient.aidl
+++ b/media/java/android/media/IRemoteControlClient.aidl
@@ -41,6 +41,13 @@
     void onInformationRequested(int generationId, int infoFlags);
 
     /**
+     * Notifies a remote control client that information for the given generation ID is
+     * requested for the given IRemoteControlDisplay alone.
+     * @param rcd the display to which current info should be sent
+     */
+    void informationRequestForDisplay(IRemoteControlDisplay rcd, int w, int h);
+
+    /**
      * Sets the generation counter of the current client that is displayed on the remote control.
      */
     void setCurrentClientGenerationId(int clientGeneration);
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index cf5be1b..2a7a731 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -139,6 +139,7 @@
     private static final int MSG_RCC_NEW_PLAYBACK_STATE = 7;
     private static final int MSG_RCC_SEEK_REQUEST = 8;
     private static final int MSG_RCC_UPDATE_METADATA = 9;
+    private static final int MSG_RCDISPLAY_INIT_INFO = 10;
 
     // sendMsg() flags
     /** If the msg is already queued, replace it with this one. */
@@ -214,6 +215,12 @@
                 case MSG_PROMOTE_RCC:
                     onPromoteRcc(msg.arg1);
                     break;
+
+                case MSG_RCDISPLAY_INIT_INFO:
+                    // msg.obj is guaranteed to be non null
+                    onRcDisplayInitInfo((IRemoteControlDisplay)msg.obj /*newRcd*/,
+                            msg.arg1/*w*/, msg.arg2/*h*/);
+                    break;
             }
         }
     }
@@ -852,6 +859,11 @@
      * Access protected by mCurrentRcLock.
      */
     private IRemoteControlClient mCurrentRcClient = null;
+    /**
+     * The PendingIntent associated with mCurrentRcClient. Its value is irrelevant
+     * if mCurrentRcClient is null
+     */
+    private PendingIntent mCurrentRcClientIntent = null;
 
     private final static int RC_INFO_NONE = 0;
     private final static int RC_INFO_ALL =
@@ -1446,6 +1458,7 @@
 
                     // tell the current client that it needs to send info
                     try {
+                        //TODO change name to informationRequestForAllDisplays()
                         mCurrentRcClient.onInformationRequested(mCurrentRcClientGen, flags);
                     } catch (RemoteException e) {
                         Log.e(TAG, "Current valid remote client is dead: "+e);
@@ -1460,6 +1473,36 @@
         }
     }
 
+    /**
+     * Called when processing MSG_RCDISPLAY_INIT_INFO event
+     * Causes the current RemoteControlClient to send its info (metadata, playstate...) to
+     *   a single RemoteControlDisplay, NOT all of them, as with MSG_RCDISPLAY_UPDATE.
+     */
+    private void onRcDisplayInitInfo(IRemoteControlDisplay newRcd, int w, int h) {
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                if (mCurrentRcClient != null) {
+                    if (DEBUG_RC) { Log.i(TAG, "Init RCD with current info"); }
+                    try {
+                        // synchronously update the new RCD with the current client generation
+                        // and matching PendingIntent
+                        newRcd.setCurrentClientId(mCurrentRcClientGen, mCurrentRcClientIntent,
+                                false);
+
+                        // tell the current RCC that it needs to send info, but only to the new RCD
+                        try {
+                            mCurrentRcClient.informationRequestForDisplay(newRcd, w, h);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Current valid remote client is dead: ", e);
+                            mCurrentRcClient = null;
+                        }
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Dead display in onRcDisplayInitInfo()", e);
+                    }
+                }
+            }
+        }
+    }
 
     /**
      * Helper function:
@@ -1497,6 +1540,7 @@
                 infoFlagsAboutToBeUsed = RC_INFO_ALL;
             }
             mCurrentRcClient = rcse.mRcClient;
+            mCurrentRcClientIntent = rcse.mMediaIntent;
         }
         // will cause onRcDisplayUpdate() to be called in AudioService's handler thread
         mEventHandler.sendMessage( mEventHandler.obtainMessage(MSG_RCDISPLAY_UPDATE,
@@ -1923,8 +1967,12 @@
                     }
                 }
 
-                // we have a new display, of which all the clients are now aware: have it be updated
-                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+                // we have a new display, of which all the clients are now aware: have it be
+                // initialized wih the current gen ID and the current client info, do not
+                // reset the information for the other (existing) displays
+                sendMsg(mEventHandler, MSG_RCDISPLAY_INIT_INFO, SENDMSG_QUEUE,
+                        w /*arg1*/, h /*arg2*/,
+                        rcd /*obj*/, 0/*delay*/);
             }
         }
     }
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 7613c89..ab6bd70 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -515,13 +515,13 @@
                 mEditorArtwork = null;
                 if (mMetadataChanged & mArtworkChanged) {
                     // send to remote control display if conditions are met
-                    sendMetadataWithArtwork_syncCacheLock();
+                    sendMetadataWithArtwork_syncCacheLock(null, 0, 0);
                 } else if (mMetadataChanged) {
                     // send to remote control display if conditions are met
-                    sendMetadata_syncCacheLock();
+                    sendMetadata_syncCacheLock(null);
                 } else if (mArtworkChanged) {
                     // send to remote control display if conditions are met
-                    sendArtwork_syncCacheLock();
+                    sendArtwork_syncCacheLock(null, 0, 0);
                 }
                 mApplied = true;
             }
@@ -620,7 +620,7 @@
                 mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();
 
                 // send to remote control display if conditions are met
-                sendPlaybackState_syncCacheLock();
+                sendPlaybackState_syncCacheLock(null);
                 // update AudioService
                 sendAudioServiceNewPlaybackState_syncCacheLock();
 
@@ -705,7 +705,7 @@
             mTransportControlFlags = transportControlFlags;
 
             // send to remote control display if conditions are met
-            sendTransportControlInfo_syncCacheLock();
+            sendTransportControlInfo_syncCacheLock(null);
         }
     }
 
@@ -791,7 +791,7 @@
             mPositionUpdateListener = l;
             if (oldCapa != mPlaybackPositionCapabilities) {
                 // tell RCDs that this RCC's playback position capabilities have changed
-                sendTransportControlInfo_syncCacheLock();
+                sendTransportControlInfo_syncCacheLock(null);
             }
         }
     }
@@ -813,7 +813,7 @@
             mPositionProvider = l;
             if (oldCapa != mPlaybackPositionCapabilities) {
                 // tell RCDs that this RCC's playback position capabilities have changed
-                sendTransportControlInfo_syncCacheLock();
+                sendTransportControlInfo_syncCacheLock(null);
             }
             if ((mPositionProvider != null) && (mEventHandler != null)
                     && playbackPositionShouldMove(mPlaybackState)) {
@@ -1083,6 +1083,7 @@
      */
     private final IRemoteControlClient mIRCC = new IRemoteControlClient.Stub() {
 
+        //TODO change name to informationRequestForAllDisplays()
         public void onInformationRequested(int generationId, int infoFlags) {
             // only post messages, we can't block here
             if (mEventHandler != null) {
@@ -1096,12 +1097,30 @@
                 mEventHandler.removeMessages(MSG_REQUEST_METADATA);
                 mEventHandler.removeMessages(MSG_REQUEST_TRANSPORTCONTROL);
                 mEventHandler.removeMessages(MSG_REQUEST_ARTWORK);
+                mEventHandler.removeMessages(MSG_REQUEST_METADATA_ARTWORK);
                 mEventHandler.sendMessage(
-                        mEventHandler.obtainMessage(MSG_REQUEST_PLAYBACK_STATE));
+                        mEventHandler.obtainMessage(MSG_REQUEST_PLAYBACK_STATE, null));
                 mEventHandler.sendMessage(
-                        mEventHandler.obtainMessage(MSG_REQUEST_TRANSPORTCONTROL));
-                mEventHandler.sendMessage(mEventHandler.obtainMessage(MSG_REQUEST_METADATA));
-                mEventHandler.sendMessage(mEventHandler.obtainMessage(MSG_REQUEST_ARTWORK));
+                        mEventHandler.obtainMessage(MSG_REQUEST_TRANSPORTCONTROL, null));
+                mEventHandler.sendMessage(mEventHandler.obtainMessage(MSG_REQUEST_METADATA_ARTWORK,
+                        0, 0, null));
+            }
+        }
+
+        public void informationRequestForDisplay(IRemoteControlDisplay rcd, int w, int h) {
+            // only post messages, we can't block here
+            if (mEventHandler != null) {
+                mEventHandler.sendMessage(
+                        mEventHandler.obtainMessage(MSG_REQUEST_TRANSPORTCONTROL, rcd));
+                mEventHandler.sendMessage(
+                        mEventHandler.obtainMessage(MSG_REQUEST_PLAYBACK_STATE, rcd));
+                if ((w > 0) && (h > 0)) {
+                    mEventHandler.sendMessage(
+                            mEventHandler.obtainMessage(MSG_REQUEST_METADATA_ARTWORK, w, h, rcd));
+                } else {
+                    mEventHandler.sendMessage(
+                            mEventHandler.obtainMessage(MSG_REQUEST_METADATA, rcd));
+                }
             }
         }
 
@@ -1207,6 +1226,7 @@
     private final static int MSG_POSITION_DRIFT_CHECK = 11;
     private final static int MSG_DISPLAY_WANTS_POS_SYNC = 12;
     private final static int MSG_UPDATE_METADATA = 13;
+    private final static int MSG_REQUEST_METADATA_ARTWORK = 14;
 
     private class EventHandler extends Handler {
         public EventHandler(RemoteControlClient rcc, Looper looper) {
@@ -1218,22 +1238,29 @@
             switch(msg.what) {
                 case MSG_REQUEST_PLAYBACK_STATE:
                     synchronized (mCacheLock) {
-                        sendPlaybackState_syncCacheLock();
+                        sendPlaybackState_syncCacheLock((IRemoteControlDisplay)msg.obj);
                     }
                     break;
                 case MSG_REQUEST_METADATA:
                     synchronized (mCacheLock) {
-                        sendMetadata_syncCacheLock();
+                        sendMetadata_syncCacheLock((IRemoteControlDisplay)msg.obj);
                     }
                     break;
                 case MSG_REQUEST_TRANSPORTCONTROL:
                     synchronized (mCacheLock) {
-                        sendTransportControlInfo_syncCacheLock();
+                        sendTransportControlInfo_syncCacheLock((IRemoteControlDisplay)msg.obj);
                     }
                     break;
                 case MSG_REQUEST_ARTWORK:
                     synchronized (mCacheLock) {
-                        sendArtwork_syncCacheLock();
+                        sendArtwork_syncCacheLock((IRemoteControlDisplay)msg.obj,
+                                msg.arg1, msg.arg2);
+                    }
+                    break;
+                case MSG_REQUEST_METADATA_ARTWORK:
+                    synchronized (mCacheLock) {
+                        sendMetadataWithArtwork_syncCacheLock((IRemoteControlDisplay)msg.obj,
+                                msg.arg1, msg.arg2);
                     }
                     break;
                 case MSG_NEW_INTERNAL_CLIENT_GEN:
@@ -1272,8 +1299,19 @@
     //===========================================================
     // Communication with the IRemoteControlDisplay (the displays known to the system)
 
-    private void sendPlaybackState_syncCacheLock() {
+    private void sendPlaybackState_syncCacheLock(IRemoteControlDisplay target) {
         if (mCurrentClientGenId == mInternalClientGenId) {
+            if (target != null) {
+                try {
+                    target.setPlaybackState(mInternalClientGenId,
+                            mPlaybackState, mPlaybackStateChangeTimeMs, mPlaybackPositionMs,
+                            mPlaybackSpeed);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in setPlaybackState() for dead display " + target, e);
+                }
+                return;
+            }
+            // target == null implies all displays must be updated
             final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext()) {
                 final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next();
@@ -1289,8 +1327,17 @@
         }
     }
 
-    private void sendMetadata_syncCacheLock() {
+    private void sendMetadata_syncCacheLock(IRemoteControlDisplay target) {
         if (mCurrentClientGenId == mInternalClientGenId) {
+            if (target != null) {
+                try {
+                    target.setMetadata(mInternalClientGenId, mMetadata);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in setMetadata() for dead display " + target, e);
+                }
+                return;
+            }
+            // target == null implies all displays must be updated
             final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext()) {
                 final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next();
@@ -1304,8 +1351,19 @@
         }
     }
 
-    private void sendTransportControlInfo_syncCacheLock() {
+    private void sendTransportControlInfo_syncCacheLock(IRemoteControlDisplay target) {
         if (mCurrentClientGenId == mInternalClientGenId) {
+            if (target != null) {
+                try {
+                    target.setTransportControlInfo(mInternalClientGenId,
+                            mTransportControlFlags, mPlaybackPositionCapabilities);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in setTransportControlFlags() for dead display " + target,
+                            e);
+                }
+                return;
+            }
+            // target == null implies all displays must be updated
             final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext()) {
                 final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next();
@@ -1321,9 +1379,15 @@
         }
     }
 
-    private void sendArtwork_syncCacheLock() {
+    private void sendArtwork_syncCacheLock(IRemoteControlDisplay target, int w, int h) {
         // FIXME modify to cache all requested sizes?
         if (mCurrentClientGenId == mInternalClientGenId) {
+            if (target != null) {
+                final DisplayInfoForClient di = new DisplayInfoForClient(target, w, h);
+                sendArtworkToDisplay(di);
+                return;
+            }
+            // target == null implies all displays must be updated
             final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext()) {
                 if (!sendArtworkToDisplay((DisplayInfoForClient) displayIterator.next())) {
@@ -1353,9 +1417,23 @@
         return true;
     }
 
-    private void sendMetadataWithArtwork_syncCacheLock() {
+    private void sendMetadataWithArtwork_syncCacheLock(IRemoteControlDisplay target, int w, int h) {
         // FIXME modify to cache all requested sizes?
         if (mCurrentClientGenId == mInternalClientGenId) {
+            if (target != null) {
+                try {
+                    if ((w > 0) && (h > 0)) {
+                        Bitmap artwork = scaleBitmapIfTooBig(mOriginalArtwork, w, h);
+                        target.setAllMetadata(mInternalClientGenId, mMetadata, artwork);
+                    } else {
+                        target.setMetadata(mInternalClientGenId, mMetadata);
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in set(All)Metadata() for dead display " + target, e);
+                }
+                return;
+            }
+            // target == null implies all displays must be updated
             final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext()) {
                 final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next();
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 10e1c70..96f6a92 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -74,6 +74,8 @@
     private OnClientUpdateListener mOnClientUpdateListener;
     private PlaybackInfo mLastPlaybackInfo;
     private int mLastTransportControlFlags = TRANSPORT_UNKNOWN;
+    private int mArtworkWidth = -1;
+    private int mArtworkHeight = -1;
 
     /**
      * Class constructor.
@@ -290,7 +292,6 @@
 
     /**
      * @hide
-     * must be called on a registered RemoteController
      * @param wantBitmap
      * @param width
      * @param height
@@ -298,22 +299,26 @@
      */
     public int setArtworkConfiguration(boolean wantBitmap, int width, int height) {
         synchronized (mInfoLock) {
-            if (!mIsRegistered) {
-                Log.e(TAG, "Cannot specify bitmap configuration on unregistered RemoteController");
-                return ERROR;
-            }
-        }
-        if (wantBitmap) {
-            if ((width > 0) && (height > 0)) {
-                if (width > MAX_BITMAP_DIMENSION) { width = MAX_BITMAP_DIMENSION; }
-                if (height > MAX_BITMAP_DIMENSION) { height = MAX_BITMAP_DIMENSION; }
-                mAudioManager.remoteControlDisplayUsesBitmapSize(mRcd, width, height);
+            if (wantBitmap) {
+                if ((width > 0) && (height > 0)) {
+                    if (width > MAX_BITMAP_DIMENSION) { width = MAX_BITMAP_DIMENSION; }
+                    if (height > MAX_BITMAP_DIMENSION) { height = MAX_BITMAP_DIMENSION; }
+                    mArtworkWidth = width;
+                    mArtworkHeight = height;
+                } else {
+                    Log.e(TAG, "Invalid dimensions");
+                    return ERROR_BAD_VALUE;
+                }
             } else {
-                Log.e(TAG, "Invalid dimensions");
-                return ERROR_BAD_VALUE;
+                mArtworkWidth = -1;
+                mArtworkHeight = -1;
             }
-        } else {
-            mAudioManager.remoteControlDisplayUsesBitmapSize(mRcd, -1, -1);
+            if (mIsRegistered) {
+                mAudioManager.remoteControlDisplayUsesBitmapSize(mRcd,
+                        mArtworkWidth, mArtworkHeight);
+            } // else new values have been stored, and will be read by AudioManager with
+              //    RemoteController.getArtworkSize() when AudioManager.registerRemoteController()
+              //    is called.
         }
         return SUCCESS;
     }
@@ -321,7 +326,6 @@
     /**
      * Set the maximum artwork image dimensions to be received in the metadata.
      * No bitmaps will be received unless this has been specified.
-     * This method can only be called on a registered RemoteController.
      * @param width the maximum width in pixels
      * @param height  the maximum height in pixels
      * @return {@link #SUCCESS}, {@link #ERROR} or {@link #ERROR_BAD_VALUE}
@@ -332,7 +336,6 @@
 
     /**
      * Prevents this RemoteController from receiving artwork images.
-     * This method can only be called on a registered RemoteController.
      * @return {@link #SUCCESS}, {@link #ERROR}
      */
     public int clearArtworkConfiguration() {
@@ -767,4 +770,17 @@
     protected RcDisplay getRcDisplay() {
         return mRcd;
     }
+
+    /**
+     * @hide
+     * Used by AudioManager to read the current artwork dimension
+     * @return array containing width (index 0) and height (index 1) of currently set artwork size
+     */
+    protected int[] getArtworkSize() {
+        synchronized (mInfoLock) {
+            int[] size = { mArtworkWidth, mArtworkHeight };
+            return size;
+        }
+    }
+
 }
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
index 16a3f3f..a31f708 100644
--- a/packages/Keyguard/res/values/styles.xml
+++ b/packages/Keyguard/res/values/styles.xml
@@ -22,15 +22,16 @@
     <style name="Widget.Button.NumPadKey"
             parent="@android:style/Widget.Button">
         <item name="android:singleLine">true</item>
-        <item name="android:padding">6dip</item>
         <item name="android:gravity">left|center_vertical</item>
         <item name="android:background">?android:attr/selectableItemBackground</item>
         <item name="android:textSize">34dp</item>
         <item name="android:fontFamily">sans-serif</item>
         <item name="android:textStyle">normal</item>
         <item name="android:textColor">#ffffff</item>
-        <item name="android:paddingBottom">10dp</item>
+        <item name="android:paddingTop">6dp</item>
+        <item name="android:paddingBottom">8dp</item>
         <item name="android:paddingLeft">20dp</item>
+        <item name="android:paddingRight">6dp</item>
     </style>
     <style name="TextAppearance.NumPadKey"
             parent="@android:style/TextAppearance">
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index f4c16c6..4da6171 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -428,10 +428,11 @@
     }
 
     private boolean widgetsDisabled() {
+        boolean disabledByLowRamDevice = ActivityManager.isLowRamDeviceStatic();
         boolean disabledByDpm =
                 (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
         boolean disabledByUser = !mLockPatternUtils.getWidgetsEnabled();
-        return disabledByDpm || disabledByUser;
+        return disabledByLowRamDevice || disabledByDpm || disabledByUser;
     }
 
     private boolean cameraDisabledByDpm() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
index c0586d5..ab8a759 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
@@ -254,7 +254,7 @@
      */
     public void enableHardwareLayersForContent() {
         View widget = getContent();
-        if (widget != null) {
+        if (widget != null && widget.isHardwareAccelerated()) {
             widget.setLayerType(LAYER_TYPE_HARDWARE, null);
         }
     }
@@ -271,14 +271,6 @@
         }
     }
 
-    public void enableHardwareLayers() {
-        setLayerType(LAYER_TYPE_HARDWARE, null);
-    }
-
-    public void disableHardwareLayers() {
-        setLayerType(LAYER_TYPE_NONE, null);
-    }
-
     public View getContent() {
         return getChildAt(0);
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
index 2e47768..9718c9b 100644
--- a/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
+++ b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
@@ -395,7 +395,7 @@
         cancelTransitionsInProgress();
 
         mChallengeInteractiveInternal = false;
-        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+        enableHardwareLayerForChallengeView();
         final int sy = mChallengeView.getBottom();
         final int dy = y - sy;
         if (dy == 0) {
@@ -580,7 +580,7 @@
                         mGestureStartY = y;
                         mGestureStartChallengeBottom = getChallengeBottom();
                         mDragging = true;
-                        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+                        enableHardwareLayerForChallengeView();
                     } else if (mChallengeShowing && isInChallengeView(x, y)) {
                         mBlockDrag = true;
                     }
@@ -657,7 +657,7 @@
                             mActivePointerId = ev.getPointerId(i);
                             mGestureStartChallengeBottom = getChallengeBottom();
                             mDragging = true;
-                            mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+                            enableHardwareLayerForChallengeView();
                             break;
                         }
                     }
@@ -1065,7 +1065,7 @@
 
     private void onFadeStart(boolean show) {
         mChallengeInteractiveInternal = false;
-        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+        enableHardwareLayerForChallengeView();
 
         if (show) {
             moveChallengeTo(getMinChallengeBottom());
@@ -1074,6 +1074,12 @@
         setScrollState(SCROLL_STATE_FADING);
     }
 
+    private void enableHardwareLayerForChallengeView() {
+        if (mChallengeView.isHardwareAccelerated()) {
+            mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+        }
+    }
+
     private void onFadeEnd(boolean show) {
         mChallengeInteractiveInternal = true;
         setChallengeShowing(show);
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
index 2145b76..3a3dfd5 100644
--- a/services/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -47,6 +47,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.RegisteredServicesCache;
 import android.content.pm.RegisteredServicesCacheListener;
+import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
@@ -580,15 +581,18 @@
         try {
             new Session(fromAccounts, null, account.type, false,
                     false /* stripAuthTokenFromResult */) {
+                @Override
                 protected String toDebugString(long now) {
                     return super.toDebugString(now) + ", getAccountCredentialsForClone"
                             + ", " + account.type;
                 }
 
+                @Override
                 public void run() throws RemoteException {
                     mAuthenticator.getAccountCredentialsForCloning(this, account);
                 }
 
+                @Override
                 public void onResult(Bundle result) {
                     if (result != null) {
                         if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) {
@@ -613,11 +617,13 @@
         try {
             new Session(targetUser, null, account.type, false,
                     false /* stripAuthTokenFromResult */) {
+                @Override
                 protected String toDebugString(long now) {
                     return super.toDebugString(now) + ", getAccountCredentialsForClone"
                             + ", " + account.type;
                 }
 
+                @Override
                 public void run() throws RemoteException {
                     // Confirm that the owner's account still exists before this step.
                     UserAccounts owner = getUserAccounts(UserHandle.USER_OWNER);
@@ -632,6 +638,7 @@
                     }
                 }
 
+                @Override
                 public void onResult(Bundle result) {
                     if (result != null) {
                         if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) {
@@ -646,6 +653,7 @@
                     }
                 }
 
+                @Override
                 public void onError(int errorCode, String errorMessage) {
                     super.onError(errorCode,  errorMessage);
                     // TODO: Show error notification to user
@@ -774,6 +782,7 @@
             mAccount = account;
         }
 
+        @Override
         public void run() throws RemoteException {
             try {
                 mAuthenticator.hasFeatures(this, mAccount, mFeatures);
@@ -782,6 +791,7 @@
             }
         }
 
+        @Override
         public void onResult(Bundle result) {
             IAccountManagerResponse response = getResponseAndClose();
             if (response != null) {
@@ -807,6 +817,7 @@
             }
         }
 
+        @Override
         protected String toDebugString(long now) {
             return super.toDebugString(now) + ", hasFeatures"
                     + ", " + mAccount
@@ -863,15 +874,18 @@
             mAccount = account;
         }
 
+        @Override
         protected String toDebugString(long now) {
             return super.toDebugString(now) + ", removeAccount"
                     + ", account " + mAccount;
         }
 
+        @Override
         public void run() throws RemoteException {
             mAuthenticator.getAccountRemovalAllowed(this, mAccount);
         }
 
+        @Override
         public void onResult(Bundle result) {
             if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT)
                     && !result.containsKey(AccountManager.KEY_INTENT)) {
@@ -1212,16 +1226,19 @@
         try {
             new Session(accounts, response, accountType, false,
                     false /* stripAuthTokenFromResult */) {
+                @Override
                 protected String toDebugString(long now) {
                     return super.toDebugString(now) + ", getAuthTokenLabel"
                             + ", " + accountType
                             + ", authTokenType " + authTokenType;
                 }
 
+                @Override
                 public void run() throws RemoteException {
                     mAuthenticator.getAuthTokenLabel(this, authTokenType);
                 }
 
+                @Override
                 public void onResult(Bundle result) {
                     if (result != null) {
                         String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
@@ -1299,6 +1316,7 @@
 
             new Session(accounts, response, account.type, expectActivityLaunch,
                     false /* stripAuthTokenFromResult */) {
+                @Override
                 protected String toDebugString(long now) {
                     if (loginOptions != null) loginOptions.keySet();
                     return super.toDebugString(now) + ", getAuthToken"
@@ -1308,6 +1326,7 @@
                             + ", notifyOnAuthFailure " + notifyOnAuthFailure;
                 }
 
+                @Override
                 public void run() throws RemoteException {
                     // If the caller doesn't have permission then create and return the
                     // "grant permission" intent instead of the "getAuthToken" intent.
@@ -1318,6 +1337,7 @@
                     }
                 }
 
+                @Override
                 public void onResult(Bundle result) {
                     if (result != null) {
                         if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) {
@@ -1482,11 +1502,13 @@
         try {
             new Session(accounts, response, accountType, expectActivityLaunch,
                     true /* stripAuthTokenFromResult */) {
+                @Override
                 public void run() throws RemoteException {
                     mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures,
                             options);
                 }
 
+                @Override
                 protected String toDebugString(long now) {
                     return super.toDebugString(now) + ", addAccount"
                             + ", accountType " + accountType
@@ -1530,9 +1552,11 @@
         try {
             new Session(accounts, response, account.type, expectActivityLaunch,
                     true /* stripAuthTokenFromResult */) {
+                @Override
                 public void run() throws RemoteException {
                     mAuthenticator.confirmCredentials(this, account, options);
                 }
+                @Override
                 protected String toDebugString(long now) {
                     return super.toDebugString(now) + ", confirmCredentials"
                             + ", " + account;
@@ -1563,9 +1587,11 @@
         try {
             new Session(accounts, response, account.type, expectActivityLaunch,
                     true /* stripAuthTokenFromResult */) {
+                @Override
                 public void run() throws RemoteException {
                     mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
                 }
+                @Override
                 protected String toDebugString(long now) {
                     if (loginOptions != null) loginOptions.keySet();
                     return super.toDebugString(now) + ", updateCredentials"
@@ -1596,9 +1622,11 @@
         try {
             new Session(accounts, response, accountType, expectActivityLaunch,
                     true /* stripAuthTokenFromResult */) {
+                @Override
                 public void run() throws RemoteException {
                     mAuthenticator.editProperties(this, mAccountType);
                 }
+                @Override
                 protected String toDebugString(long now) {
                     return super.toDebugString(now) + ", editProperties"
                             + ", accountType " + accountType;
@@ -1624,6 +1652,7 @@
             mFeatures = features;
         }
 
+        @Override
         public void run() throws RemoteException {
             synchronized (mAccounts.cacheLock) {
                 mAccountsOfType = getAccountsFromCacheLocked(mAccounts, mAccountType, mCallingUid,
@@ -1661,6 +1690,7 @@
             }
         }
 
+        @Override
         public void onResult(Bundle result) {
             mNumResults++;
             if (result == null) {
@@ -1699,6 +1729,7 @@
         }
 
 
+        @Override
         protected String toDebugString(long now) {
             return super.toDebugString(now) + ", getAccountsByTypeAndFeatures"
                     + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null);
@@ -2111,9 +2142,31 @@
             }
         }
 
+        @Override
         public void onResult(Bundle result) {
             mNumResults++;
-            if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) {
+            Intent intent = null;
+            if (result != null
+                    && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
+                /*
+                 * The Authenticator API allows third party authenticators to
+                 * supply arbitrary intents to other apps that they can run,
+                 * this can be very bad when those apps are in the system like
+                 * the System Settings.
+                 */
+                PackageManager pm = mContext.getPackageManager();
+                ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
+                int targetUid = resolveInfo.activityInfo.applicationInfo.uid;
+                int authenticatorUid = Binder.getCallingUid();
+                if (PackageManager.SIGNATURE_MATCH !=
+                        pm.checkSignatures(authenticatorUid, targetUid)) {
+                    throw new SecurityException(
+                            "Activity to be started with KEY_INTENT must " +
+                            "share Authenticator's signatures");
+                }
+            }
+            if (result != null
+                    && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) {
                 String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
                 String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
                 if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
@@ -2223,6 +2276,7 @@
             super(looper);
         }
 
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MESSAGE_TIMED_OUT:
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a7fc995..4d66946 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1083,10 +1083,24 @@
                         // At this point, nothing else needs to be shown
                         if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
                         behindFullscreen = true;
-                    } else if (task.mActivities.indexOf(r) == 0 && task.mOnTopOfHome) {
-                        if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
-                        showHomeBehindStack = true;
-                        behindFullscreen = true;
+                    } else if (task.mOnTopOfHome) {
+                        // Work our way down from r to bottom of task and see if there are any
+                        // visible activities below r.
+                        int rIndex = task.mActivities.indexOf(r);
+                        for ( --rIndex; rIndex >= 0; --rIndex) {
+                            final ActivityRecord blocker = task.mActivities.get(rIndex);
+                            if (!blocker.finishing && blocker.visible) {
+                                if (DEBUG_VISBILITY) Slog.v(TAG, "Home visibility for " +
+                                        r + " blocked by " + blocker);
+                                break;
+                            }
+                        }
+                        if (rIndex < 0) {
+                            // Got to task bottom without finding a visible activity, show home.
+                            if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
+                            showHomeBehindStack = true;
+                            behindFullscreen = true;
+                        }
                     }
                 } else {
                     if (DEBUG_VISBILITY) Slog.v(
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index 635ba5c..2ae7bc7 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -1785,16 +1785,20 @@
         public final SyncTimeTracker mSyncTimeTracker = new SyncTimeTracker();
         private final HashMap<Pair<Account, String>, PowerManager.WakeLock> mWakeLocks =
                 Maps.newHashMap();
-
-        private volatile CountDownLatch mReadyToRunLatch = new CountDownLatch(1);
+        private List<Message> mBootQueue = new ArrayList<Message>();
 
         public void onBootCompleted() {
-            mBootCompleted = true;
-
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "Boot completed, clearing boot queue.");
+            }
             doDatabaseCleanup();
-
-            if (mReadyToRunLatch != null) {
-                mReadyToRunLatch.countDown();
+            synchronized(this) {
+                // Dispatch any stashed messages.
+                for (Message message : mBootQueue) {
+                    sendMessage(message);
+                }
+                mBootQueue = null;
+                mBootCompleted = true;
             }
         }
 
@@ -1811,20 +1815,24 @@
             return wakeLock;
         }
 
-        private void waitUntilReadyToRun() {
-            CountDownLatch latch = mReadyToRunLatch;
-            if (latch != null) {
-                while (true) {
-                    try {
-                        latch.await();
-                        mReadyToRunLatch = null;
-                        return;
-                    } catch (InterruptedException e) {
-                        Thread.currentThread().interrupt();
-                    }
+        /**
+         * Stash any messages that come to the handler before boot is complete.
+         * {@link #onBootCompleted()} will disable this and dispatch all the messages collected.
+         * @param msg Message to dispatch at a later point.
+         * @return true if a message was enqueued, false otherwise. This is to avoid losing the
+         * message if we manage to acquire the lock but by the time we do boot has completed.
+         */
+        private boolean tryEnqueueMessageUntilReadyToRun(Message msg) {
+            synchronized (this) {
+                if (!mBootCompleted) {
+                    // Need to copy the message bc looper will recycle it.
+                    mBootQueue.add(Message.obtain(msg));
+                    return true;
                 }
+                return false;
             }
         }
+
         /**
          * Used to keep track of whether a sync notification is active and who it is for.
          */
@@ -1854,13 +1862,15 @@
 
         @Override
         public void handleMessage(Message msg) {
+            if (tryEnqueueMessageUntilReadyToRun(msg)) {
+                return;
+            }
+
             long earliestFuturePollTime = Long.MAX_VALUE;
             long nextPendingSyncTime = Long.MAX_VALUE;
-
             // Setting the value here instead of a method because we want the dumpsys logs
             // to have the most recent value used.
             try {
-                waitUntilReadyToRun();
                 mDataConnectionIsConnected = readDataConnectionState();
                 mSyncManagerWakeLock.acquire();
                 // Always do this first so that we be sure that any periodic syncs that
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 76bd636..798bc2e 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1456,9 +1456,6 @@
     public void setCountryCode(String countryCode, boolean persist) {
         if (persist) {
             mPersistedCountryCode = countryCode;
-            Settings.Global.putString(mContext.getContentResolver(),
-                    Settings.Global.WIFI_COUNTRY_CODE,
-                    countryCode);
         }
         sendMessage(CMD_SET_COUNTRY_CODE, countryCode);
         mWifiP2pChannel.sendMessage(WifiP2pService.SET_COUNTRY_CODE, countryCode);
@@ -1691,8 +1688,8 @@
      * Set the country code from the system setting value, if any.
      */
     private void setCountryCode() {
-        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.WIFI_COUNTRY_CODE);
+        String countryCode = mContext.getResources().getString(
+                                    R.string.config_wifi_default_country_code);
         if (countryCode != null && !countryCode.isEmpty()) {
             setCountryCode(countryCode, false);
         } else {
@@ -2417,13 +2414,6 @@
                 case CMD_BOOT_COMPLETED:
                     String countryCode = mPersistedCountryCode;
                     if (TextUtils.isEmpty(countryCode) == false) {
-                        Settings.Global.putString(mContext.getContentResolver(),
-                                Settings.Global.WIFI_COUNTRY_CODE,
-                                countryCode);
-                        // it may be that the state transition that should send this info
-                        // to the driver happened between mPersistedCountryCode getting set
-                        // and now, so simply persisting it here would mean we have sent
-                        // nothing to the driver.  Send the cmd so it might be set now.
                         sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE, countryCode);
                     }
                     break;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 625ffb8..50e8e3d 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -2545,12 +2545,6 @@
         mServiceTransactionId = 0;
         mServiceDiscReqId = null;
 
-        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.WIFI_COUNTRY_CODE);
-        if (countryCode != null && !countryCode.isEmpty()) {
-            mP2pStateMachine.sendMessage(SET_COUNTRY_CODE, countryCode);
-        }
-
         updatePersistentNetworks(RELOAD);
     }