Merge "Notify people of empty proxies too." into ics-factoryrom
diff --git a/api/14.txt b/api/14.txt
index 45bb882..9f2a6df 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -759,6 +759,7 @@
     field public static final int prompt = 16843131; // 0x101017b
     field public static final int propertyName = 16843489; // 0x10102e1
     field public static final int protectionLevel = 16842761; // 0x1010009
+    field public static final int publicKey = 16843686; // 0x10103a6
     field public static final int queryActionMsg = 16843227; // 0x10101db
     field public static final int queryAfterZeroResults = 16843394; // 0x1010282
     field public static final int queryHint = 16843608; // 0x1010358
@@ -4566,6 +4567,7 @@
     field public static final java.lang.String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE";
     field public static final java.lang.String EXTRA_STATE = "android.bluetooth.profile.extra.STATE";
     field public static final int HEADSET = 1; // 0x1
+    field public static final int HEALTH = 3; // 0x3
     field public static final int STATE_CONNECTED = 2; // 0x2
     field public static final int STATE_CONNECTING = 1; // 0x1
     field public static final int STATE_DISCONNECTED = 0; // 0x0
@@ -5454,6 +5456,7 @@
     field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
     field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED";
     field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
+    field public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION";
     field public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
     field public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
     field public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
@@ -6207,11 +6210,13 @@
     method public abstract void setApplicationEnabledSetting(java.lang.String, int, int);
     method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
+    method public abstract void verifyPendingInstall(int, int);
     field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
     field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2
     field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3
     field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1
     field public static final int DONT_KILL_APP = 1; // 0x1
+    field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
     field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
     field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera";
@@ -6273,6 +6278,8 @@
     field public static final int SIGNATURE_NO_MATCH = -3; // 0xfffffffd
     field public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; // 0xfffffffe
     field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc
+    field public static final int VERIFICATION_ALLOW = 1; // 0x1
+    field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
   }
 
   public static class PackageManager.NameNotFoundException extends android.util.AndroidException {
@@ -19834,6 +19841,7 @@
     method public void setApplicationEnabledSetting(java.lang.String, int, int);
     method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public void setInstallerPackageName(java.lang.String, java.lang.String);
+    method public void verifyPendingInstall(int, int);
   }
 
   public class MockResources extends android.content.res.Resources {
diff --git a/api/current.txt b/api/current.txt
index 45bb882..9f2a6df 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -759,6 +759,7 @@
     field public static final int prompt = 16843131; // 0x101017b
     field public static final int propertyName = 16843489; // 0x10102e1
     field public static final int protectionLevel = 16842761; // 0x1010009
+    field public static final int publicKey = 16843686; // 0x10103a6
     field public static final int queryActionMsg = 16843227; // 0x10101db
     field public static final int queryAfterZeroResults = 16843394; // 0x1010282
     field public static final int queryHint = 16843608; // 0x1010358
@@ -4566,6 +4567,7 @@
     field public static final java.lang.String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE";
     field public static final java.lang.String EXTRA_STATE = "android.bluetooth.profile.extra.STATE";
     field public static final int HEADSET = 1; // 0x1
+    field public static final int HEALTH = 3; // 0x3
     field public static final int STATE_CONNECTED = 2; // 0x2
     field public static final int STATE_CONNECTING = 1; // 0x1
     field public static final int STATE_DISCONNECTED = 0; // 0x0
@@ -5454,6 +5456,7 @@
     field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
     field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED";
     field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
+    field public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION";
     field public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
     field public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
     field public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
@@ -6207,11 +6210,13 @@
     method public abstract void setApplicationEnabledSetting(java.lang.String, int, int);
     method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
+    method public abstract void verifyPendingInstall(int, int);
     field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
     field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2
     field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3
     field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1
     field public static final int DONT_KILL_APP = 1; // 0x1
+    field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
     field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
     field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera";
@@ -6273,6 +6278,8 @@
     field public static final int SIGNATURE_NO_MATCH = -3; // 0xfffffffd
     field public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; // 0xfffffffe
     field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc
+    field public static final int VERIFICATION_ALLOW = 1; // 0x1
+    field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
   }
 
   public static class PackageManager.NameNotFoundException extends android.util.AndroidException {
@@ -19834,6 +19841,7 @@
     method public void setApplicationEnabledSetting(java.lang.String, int, int);
     method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public void setInstallerPackageName(java.lang.String, java.lang.String);
+    method public void verifyPendingInstall(int, int);
   }
 
   public class MockResources extends android.content.res.Resources {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index bd42e34..8ed7481 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -954,9 +954,9 @@
     }
 
     @Override
-    public void verifyPendingInstall(int id, boolean verified, String failureMessage) {
+    public void verifyPendingInstall(int id, int response) {
         try {
-            mPM.verifyPendingInstall(id, verified, failureMessage);
+            mPM.verifyPendingInstall(id, response);
         } catch (RemoteException e) {
             // Should never happen!
         }
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 58b3868..f7ccfbd 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -66,7 +66,6 @@
 
     /**
      * Health Profile
-     * @hide
      */
     public static final int HEALTH = 3;
 
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c7698bf..72cf26a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1535,8 +1535,6 @@
      * <p class="note">
      * This is a protected intent that can only be sent by the system.
      * </p>
-     *
-     * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION";
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 5e6e768..a3bcc28 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -359,7 +359,7 @@
             int flags, in String installerPackageName, in Uri verificationURI,
             in ManifestDigest manifestDigest);
 
-    void verifyPendingInstall(int id, boolean verified, in String message);
+    void verifyPendingInstall(int id, int verificationCode);
 
     VerifierDeviceIdentity getVerifierDeviceIdentity();
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index dcb6776..ef7e233 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -725,7 +725,22 @@
     public static final int MOVE_EXTERNAL_MEDIA = 0x00000002;
 
     /**
+     * Used as the {@code verificationCode} argument for
+     * {@link PackageManager#verifyPendingInstall} to indicate that the calling
+     * package verifier allows the installation to proceed.
+     */
+    public static final int VERIFICATION_ALLOW = 1;
+
+    /**
+     * Used as the {@code verificationCode} argument for
+     * {@link PackageManager#verifyPendingInstall} to indicate the calling
+     * package verifier does not vote to allow the installation to proceed.
+     */
+    public static final int VERIFICATION_REJECT = -1;
+
+    /**
      * Range of IDs allocated for a user.
+     *
      * @hide
      */
     public static final int PER_USER_RANGE = 100000;
@@ -1045,9 +1060,7 @@
     /**
      * Extra field name for the ID of a package pending verification. Passed to
      * a package verifier and is used to call back to
-     * {@link PackageManager#verifyPendingInstall(int, boolean)}
-     *
-     * @hide
+     * {@link PackageManager#verifyPendingInstall(int, int)}
      */
     public static final String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
 
@@ -2156,16 +2169,17 @@
     /**
      * Allows a package listening to the
      * {@link Intent#ACTION_PACKAGE_NEEDS_VERIFICATION package verification
-     * broadcast} to respond to the package manager.
+     * broadcast} to respond to the package manager. The response must include
+     * the {@code verificationCode} which is one of
+     * {@link PackageManager#VERIFICATION_ALLOW} or
+     * {@link PackageManager#VERIFICATION_REJECT}.
      *
      * @param id pending package identifier as passed via the
      *            {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra
-     * @param verified whether the package was verified as valid
-     * @param failureMessage if verification was false, this is the error
-     *            message that may be shown to the user
-     * @hide
+     * @param verificationCode either {@link PackageManager#VERIFICATION_ALLOW}
+     *            or {@link PackageManager#VERIFICATION_REJECT}.
      */
-    public abstract void verifyPendingInstall(int id, boolean verified, String failureMessage);
+    public abstract void verifyPendingInstall(int id, int verificationCode);
 
     /**
      * Change the installer associated with a given package.  There are limitations
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bc5994e..bc05078 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1882,6 +1882,11 @@
         /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
+         *
+         * NOTE: Settings are backed up and restored in the order they appear
+         *       in this array. If you have one setting depending on another,
+         *       make sure that they are ordered appropriately.
+         *
          * @hide
          */
         public static final String[] SETTINGS_TO_BACKUP = {
@@ -4048,6 +4053,12 @@
         public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
 
         /**
+         * This are the settings to be backed up.
+         *
+         * NOTE: Settings are backed up and restored in the order they appear
+         *       in this array. If you have one setting depending on another,
+         *       make sure that they are ordered appropriately.
+         *
          * @hide
          */
         public static final String[] SETTINGS_TO_BACKUP = {
@@ -4056,11 +4067,11 @@
             PARENTAL_CONTROL_ENABLED,
             PARENTAL_CONTROL_REDIRECT_URL,
             USB_MASS_STORAGE_ENABLED,
-            ACCESSIBILITY_ENABLED,
             ACCESSIBILITY_SCRIPT_INJECTION,
             BACKUP_AUTO_RESTORE,
             ENABLED_ACCESSIBILITY_SERVICES,
             TOUCH_EXPLORATION_ENABLED,
+            ACCESSIBILITY_ENABLED,
             TTS_USE_DEFAULTS,
             TTS_DEFAULT_RATE,
             TTS_DEFAULT_PITCH,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ca06b9c..f993160 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12969,15 +12969,13 @@
      * Request that the visibility of the status bar be changed.
      * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
-     *
-     * This value will be re-applied immediately, even if the flags have not changed, so a view may
-     * easily reassert a particular SystemUiVisibility condition even if the system UI itself has
-     * since countermanded the original request.
      */
     public void setSystemUiVisibility(int visibility) {
-        mSystemUiVisibility = visibility;
-        if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
-            mParent.recomputeViewAttributes(this);
+        if (visibility != mSystemUiVisibility) {
+            mSystemUiVisibility = visibility;
+            if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
+                mParent.recomputeViewAttributes(this);
+            }
         }
     }
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 847afa0..11531fc 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1561,8 +1561,21 @@
             <enum name="xhdpi" value="320" />
         </attr>
     </declare-styleable>
-    
-    
+
+    <!-- The attribute that holds a Base64-encoded public key. -->
+    <attr name="publicKey" format="string" />
+
+    <!-- Attributes relating to a package verifier -->
+    <declare-styleable name="AndroidManifestPackageVerifier" parent="AndroidManifest">
+        <!-- Specifies the Java-style package name that defines this
+             package verifier. -->
+        <attr name="name" />
+
+        <!-- The Base64 encoded public key of the package verifier's
+             signature. -->
+        <attr name="publicKey" />
+    </declare-styleable>
+
     <!-- Declaration of an {@link android.content.Intent} object in XML.  May
          also include zero or more {@link #IntentCategory <category> and
          {@link #Extra <extra>} tags. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 848fb8b..97d5afe 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1768,6 +1768,7 @@
   <public type="attr" name="listPreferredItemPaddingLeft" id="0x010103a3" />
   <public type="attr" name="listPreferredItemPaddingRight" id="0x010103a4" />
   <public type="attr" name="requiresFadingEdge" id="0x010103a5" />
+  <public type="attr" name="publicKey" id="0x010103a6" />
 
   <public type="style" name="TextAppearance.SuggestionHighlight" id="0x01030118" />
   <public type="style" name="Theme.Holo.Light.DarkActionBar" id="0x01030119" />
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 4f39e69..b851ab7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,6 +16,21 @@
 
 package com.android.providers.settings;
 
+import android.app.backup.BackupAgentHelper;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.FullBackupDataOutput;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.net.wifi.WifiManager;
+import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.provider.Settings;
+import android.util.Log;
+
 import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
@@ -27,28 +42,13 @@
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
-import java.io.InputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.zip.CRC32;
 
-import android.app.backup.BackupDataInput;
-import android.app.backup.BackupDataOutput;
-import android.app.backup.BackupAgentHelper;
-import android.app.backup.FullBackupDataOutput;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.FileUtils;
-import android.os.ParcelFileDescriptor;
-import android.os.Process;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-
 /**
  * Performs backup and restore of the System and Secure settings.
  * List of settings that are backed up are stored in the Settings.java file
@@ -79,8 +79,7 @@
     // Versioning of the 'full backup' format
     private static final int FULL_BACKUP_VERSION = 1;
 
-    private static String[] sortedSystemKeys = null;
-    private static String[] sortedSecureKeys = null;
+    private static final int INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE;
 
     private static final byte[] EMPTY_DATA = new byte[0];
 
@@ -112,6 +111,7 @@
     private WifiManager mWfm;
     private static String mWifiConfigFile;
 
+    @Override
     public void onCreate() {
         if (DEBUG_BACKUP) Log.d(TAG, "onCreate() invoked");
 
@@ -348,26 +348,17 @@
     }
 
     private byte[] getSystemSettings() {
-        Cursor sortedCursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION,
-                null, null, Settings.NameValueTable.NAME);
-        // Copy and sort the array
-        if (sortedSystemKeys == null) {
-            sortedSystemKeys = copyAndSort(Settings.System.SETTINGS_TO_BACKUP);
-        }
-        byte[] result = extractRelevantValues(sortedCursor, sortedSystemKeys);
-        sortedCursor.close();
+        Cursor cursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION, null,
+                null, null);
+        byte[] result = extractRelevantValues(cursor, Settings.System.SETTINGS_TO_BACKUP);
+        cursor.close();
         return result;
     }
 
     private byte[] getSecureSettings() {
-        Cursor sortedCursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION,
-                null, null, Settings.NameValueTable.NAME);
-        // Copy and sort the array
-        if (sortedSecureKeys == null) {
-            sortedSecureKeys = copyAndSort(Settings.Secure.SETTINGS_TO_BACKUP);
-        }
-        byte[] result = extractRelevantValues(sortedCursor, sortedSecureKeys);
-        sortedCursor.close();
+        Cursor cursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION, null,
+                null, null);
+        byte[] result = extractRelevantValues(cursor, Settings.Secure.SETTINGS_TO_BACKUP);
         return result;
     }
 
@@ -383,119 +374,132 @@
     }
 
     private void restoreSettings(byte[] settings, int bytes, Uri contentUri) {
-        if (DEBUG) Log.i(TAG, "restoreSettings: " + contentUri);
+        if (DEBUG) {
+            Log.i(TAG, "restoreSettings: " + contentUri);
+        }
+
+        // Figure out the white list.
         String[] whitelist = null;
         if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
             whitelist = Settings.Secure.SETTINGS_TO_BACKUP;
         } else if (contentUri.equals(Settings.System.CONTENT_URI)) {
             whitelist = Settings.System.SETTINGS_TO_BACKUP;
+        } else {
+            throw new IllegalArgumentException("Unknown URI: " + contentUri);
         }
 
-        ContentValues cv = new ContentValues(2);
+        // Restore only the white list data.
         int pos = 0;
-        while (pos < bytes) {
-            int length = readInt(settings, pos);
-            pos += 4;
-            String settingName = length > 0? new String(settings, pos, length) : null;
-            pos += length;
-            length = readInt(settings, pos);
-            pos += 4;
-            String settingValue = length > 0? new String(settings, pos, length) : null;
-            pos += length;
-            if (!TextUtils.isEmpty(settingName) && !TextUtils.isEmpty(settingValue)) {
-                //Log.i(TAG, "Restore " + settingName + " = " + settingValue);
+        Map<String, String> cachedEntries = new HashMap<String, String>();
+        ContentValues contentValues = new ContentValues(2);
+        SettingsHelper settingsHelper = mSettingsHelper;
 
-                // Only restore settings in our list of known-acceptable data
-                if (invalidSavedSetting(whitelist, settingName)) {
-                    continue;
-                }
+        final int whiteListSize = whitelist.length;
+        for (int i = 0; i < whiteListSize; i++) {
+            String key = whitelist[i];
+            String value = cachedEntries.remove(key);
 
-                if (mSettingsHelper.restoreValue(settingName, settingValue)) {
-                    cv.clear();
-                    cv.put(Settings.NameValueTable.NAME, settingName);
-                    cv.put(Settings.NameValueTable.VALUE, settingValue);
-                    getContentResolver().insert(contentUri, cv);
+            // If the value not cached, let us look it up.
+            if (value == null) {
+                while (pos < bytes) {
+                    int length = readInt(settings, pos);
+                    pos += INTEGER_BYTE_COUNT;
+                    String dataKey = length > 0 ? new String(settings, pos, length) : null;
+                    pos += length;
+                    length = readInt(settings, pos);
+                    pos += INTEGER_BYTE_COUNT;
+                    String dataValue = length > 0 ? new String(settings, pos, length) : null;
+                    pos += length;
+                    if (key.equals(dataKey)) {
+                        value = dataValue;
+                        break;
+                    }
+                    cachedEntries.put(dataKey, dataValue);
                 }
             }
-        }
-    }
 
-    // Returns 'true' if the given setting is one that we refuse to restore
-    private boolean invalidSavedSetting(String[] knownNames, String candidate) {
-        // no filter? allow everything
-        if (knownNames == null) {
-            return false;
-        }
+            if (value == null) {
+                continue;
+            }
 
-        // whitelisted setting?  allow it
-        for (String name : knownNames) {
-            if (name.equals(candidate)) {
-                return false;
+            if (settingsHelper.restoreValue(key, value)) {
+                contentValues.clear();
+                contentValues.put(Settings.NameValueTable.NAME, key);
+                contentValues.put(Settings.NameValueTable.VALUE, value);
+                getContentResolver().insert(contentUri, contentValues);
+            }
+
+            if (DEBUG) {
+                Log.d(TAG, "Restored setting: " + key + "=" + value);
             }
         }
-
-        // refuse everything else
-        if (DEBUG) Log.v(TAG, "Ignoring restore datum: " + candidate);
-        return true;
-    }
-
-    private String[] copyAndSort(String[] keys) {
-        String[] sortedKeys = new String[keys.length];
-        System.arraycopy(keys, 0, sortedKeys, 0, keys.length);
-        Arrays.sort(sortedKeys);
-        return sortedKeys;
     }
 
     /**
-     * Given a cursor sorted by key name and a set of keys sorted by name,
-     * extract the required keys and values and write them to a byte array.
-     * @param sortedCursor
-     * @param sortedKeys
-     * @return
+     * Given a cursor and a set of keys, extract the required keys and
+     * values and write them to a byte array.
+     *
+     * @param cursor A cursor with settings data.
+     * @param settings The settings to extract.
+     * @return The byte array of extracted values.
      */
-    byte[] extractRelevantValues(Cursor sortedCursor, String[] sortedKeys) {
-        byte[][] values = new byte[sortedKeys.length * 2][]; // keys and values
-        if (!sortedCursor.moveToFirst()) {
+    private byte[] extractRelevantValues(Cursor cursor, String[] settings) {
+        final int settingsCount = settings.length;
+        byte[][] values = new byte[settingsCount * 2][]; // keys and values
+        if (!cursor.moveToFirst()) {
             Log.e(TAG, "Couldn't read from the cursor");
             return new byte[0];
         }
-        int keyIndex = 0;
+
+        // Obtain the relevant data in a temporary array.
         int totalSize = 0;
-        while (!sortedCursor.isAfterLast()) {
-            String name = sortedCursor.getString(COLUMN_NAME);
-            while (sortedKeys[keyIndex].compareTo(name.toString()) < 0) {
-                keyIndex++;
-                if (keyIndex == sortedKeys.length) break;
-            }
-            if (keyIndex < sortedKeys.length && name.equals(sortedKeys[keyIndex])) {
-                String value = sortedCursor.getString(COLUMN_VALUE);
-                byte[] nameBytes = name.toString().getBytes();
-                totalSize += 4 + nameBytes.length;
-                values[keyIndex * 2] = nameBytes;
-                byte[] valueBytes;
-                if (TextUtils.isEmpty(value)) {
-                    valueBytes = null;
-                    totalSize += 4;
-                } else {
-                    valueBytes = value.toString().getBytes();
-                    totalSize += 4 + valueBytes.length;
-                    //Log.i(TAG, "Backing up " + name + " = " + value);
+        int backedUpSettingIndex = 0;
+        Map<String, String> cachedEntries = new HashMap<String, String>();
+        for (int i = 0; i < settingsCount; i++) {
+            String key = settings[i];
+            String value = cachedEntries.remove(key);
+
+            // If the value not cached, let us look it up.
+            if (value == null) {
+                while (!cursor.isAfterLast()) {
+                    String cursorKey = cursor.getString(COLUMN_NAME);
+                    String cursorValue = cursor.getString(COLUMN_VALUE);
+                    cursor.moveToNext();
+                    if (key.equals(cursorKey)) {
+                        value = cursorValue;
+                        break;
+                    }
+                    cachedEntries.put(cursorKey, cursorValue);
                 }
-                values[keyIndex * 2 + 1] = valueBytes;
-                keyIndex++;
             }
-            if (keyIndex == sortedKeys.length || !sortedCursor.moveToNext()) {
-                break;
+
+            if (value == null) {
+                continue;
+            }
+
+            // Write the key and value in the intermediary array.
+            byte[] keyBytes = key.getBytes();
+            totalSize += INTEGER_BYTE_COUNT + keyBytes.length;
+            values[backedUpSettingIndex * 2] = keyBytes;
+
+            byte[] valueBytes = value.getBytes();
+            totalSize += INTEGER_BYTE_COUNT + valueBytes.length;
+            values[backedUpSettingIndex * 2 + 1] = valueBytes;
+
+            backedUpSettingIndex++;
+
+            if (DEBUG) {
+                Log.d(TAG, "Backed up setting: " + key + "=" + value);
             }
         }
 
+        // Aggregate the result.
         byte[] result = new byte[totalSize];
         int pos = 0;
-        for (int i = 0; i < sortedKeys.length * 2; i++) {
-            if (values[i] != null) {
-                pos = writeInt(result, pos, values[i].length);
-                pos = writeBytes(result, pos, values[i]);
-            }
+        final int keyValuePairCount = backedUpSettingIndex * 2;
+        for (int i = 0; i < keyValuePairCount; i++) {
+            pos = writeInt(result, pos, values[i].length);
+            pos = writeBytes(result, pos, values[i]);
         }
         return result;
     }
@@ -647,14 +651,14 @@
      * @param out byte array
      * @param pos current pos in array
      * @param value integer to write
-     * @return the index after adding the size of an int (4)
+     * @return the index after adding the size of an int (4) in bytes.
      */
     private int writeInt(byte[] out, int pos, int value) {
         out[pos + 0] = (byte) ((value >> 24) & 0xFF);
         out[pos + 1] = (byte) ((value >> 16) & 0xFF);
         out[pos + 2] = (byte) ((value >>  8) & 0xFF);
         out[pos + 3] = (byte) ((value >>  0) & 0xFF);
-        return pos + 4;
+        return pos + INTEGER_BYTE_COUNT;
     }
 
     private int writeBytes(byte[] out, int pos, byte[] value) {
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 8fc8448..da6bcd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2031,8 +2031,13 @@
     // The user is not allowed to get stuck without navigation UI. Upon the slightest user
     // interaction we bring the navigation back.
     public void userActivity() {
-        if (mNavigationBarView != null) {
-            mNavigationBarView.setHidden(false);
+        if (0 != (mSystemUiVisibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) {
+            try {
+                mBarService.setSystemUiVisibility(
+                    mSystemUiVisibility & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+            } catch (RemoteException ex) {
+                // weep softly
+            }
         }
     }
 
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 9ebdd52..105e603 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -4849,15 +4849,14 @@
     }
 
     @Override
-    public void verifyPendingInstall(int id, boolean verified, String message)
+    public void verifyPendingInstall(int id, int verificationCode)
             throws RemoteException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, null);
 
         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
         msg.arg1 = id;
-        msg.arg2 = verified ? 1 : 0;
-        msg.obj = message;
+        msg.arg2 = verificationCode;
         mHandler.sendMessage(msg);
     }
 
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index f2fb36f..3525abe 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -546,11 +546,8 @@
         throw new UnsupportedOperationException();
     }
 
-    /**
-     * @hide
-     */
     @Override
-    public void verifyPendingInstall(int id, boolean verified, String failureMessage) {
+    public void verifyPendingInstall(int id, int verificationCode) {
         throw new UnsupportedOperationException();
     }