Merge "Move DropDownPreference to supportlib"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 212aeae..8c9af29 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1468,6 +1468,17 @@
             </intent-filter>
         </activity>
 
+        <!-- Note this must not be exported since it authenticates the given user -->
+        <activity android:name="ConfirmDeviceCredentialActivity$InternalActivity"
+            android:exported="false"
+            android:permission="android.permission.MANAGE_USERS"
+            android:theme="@android:style/Theme.NoDisplay">
+            <intent-filter android:priority="1">
+                <action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".SetupRedactionInterstitial"
             android:taskAffinity="com.android.wizard"
             android:theme="@style/SetupWizardDisableAppStartingTheme"/>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cd152b6..26961c8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5512,46 +5512,44 @@
     <string name="search_results_label">Results</string>
 
     <!--Search Keywords [CHAR LIMIT=NONE]-->
-    <string name="keywords_wifi">wifi wi-fi network connection</string>
-    <string name="keywords_more_default_sms_app">text message texting messages messaging</string>
-    <string name="keywords_more_mobile_networks">cellular cell carrier wireless data 4g 3g 2g lte</string>
-    <string name="keywords_wifi_calling">wifi wi-fi call calling</string>
+    <string name="keywords_wifi">wifi, wi-fi, network connection</string>
+    <string name="keywords_more_default_sms_app">text message, texting, messages, messaging</string>
+    <string name="keywords_more_mobile_networks">cellular, cell carrier, wireless, data, 4g, 3g, 2g, lte</string>
+    <string name="keywords_wifi_calling">wifi, wi-fi, call, calling</string>
     <string name="keywords_home">launcher</string>
-    <string name="keywords_display">screen touchscreen</string>
-    <string name="keywords_display_brightness_level">dim screen touchscreen battery</string>
-    <string name="keywords_display_auto_brightness">dim screen touchscreen battery</string>
-    <!-- Search keywords for display light/dark theme: dark theme, night mode, dim screen, invert brightness [CHAR LIMIT=NONE] -->
-    <string name="keywords_display_night_mode">dark theme night mode dim screen invert brightness</string>
-    <string name="keywords_display_wallpaper">background personalize customize display</string>
+    <string name="keywords_display">screen, touchscreen</string>
+    <string name="keywords_display_brightness_level">dim screen, touchscreen, battery</string>
+    <string name="keywords_display_auto_brightness">dim screen, touchscreen, battery</string>
+    <string name="keywords_display_night_mode">dark theme, night mode, dim screen, invert brightness</string>
+    <string name="keywords_display_wallpaper">background, personalize, customize display</string>
     <string name="keywords_display_font_size">text size</string>
-    <string name="keywords_display_cast_screen">project cast</string>
-    <string name="keywords_storage">space disk hard drive device usage</string>
-    <string name="keywords_battery">power usage charge</string>
-    <string name="keywords_spell_checker">spelling dictionary spellcheck auto-correct</string>
-    <string name="keywords_voice_input">recognizer input speech speak language hands-free hand free recognition offensive word audio history bluetooth headset</string>
-    <string name="keywords_text_to_speech_output">rate language default speak speaking tts accessibility reader blind</string>
-    <string name="keywords_date_and_time">clock military</string>
-    <string name="keywords_network_reset">reset restore factory</string>
-    <string name="keywords_factory_data_reset">wipe delete restore clear remove</string>
+    <string name="keywords_display_cast_screen">project, cast</string>
+    <string name="keywords_storage">space, disk, hard drive, device usage</string>
+    <string name="keywords_battery">power usage, charge</string>
+    <string name="keywords_spell_checker">spelling, dictionary, spellcheck, auto-correct</string>
+    <string name="keywords_voice_input">recognizer, input, speech, speak, language, hands-free, hand free recognition offensive word audio history bluetooth headset</string>
+    <string name="keywords_text_to_speech_output">rate, language, default, speak, speaking, tts, accessibility, screen reader, blind</string>
+    <string name="keywords_date_and_time">clock, military</string>
+    <string name="keywords_network_reset">reset, restore, factory</string>
+    <string name="keywords_factory_data_reset">wipe, delete, restore, clear, remove</string>
     <string name="keywords_printing">printer</string>
     <string name="keywords_sounds">speaker beep</string>
-    <string name="keywords_sounds_and_notifications_interruptions">dont don\u2019t disturb interrupt interruption break</string>
+    <string name="keywords_sounds_and_notifications_interruptions">dont don\u2019t disturb, interrupt, interruption, break</string>
     <string name="keywords_app">RAM</string>
-    <string name="keywords_location">nearby location history reporting</string>
+    <string name="keywords_location">nearby, location, history, reporting</string>
     <string name="keywords_location_mode">accuracy</string>
     <string name="keywords_accounts">account</string>
-    <string name="keywords_users">restriction restrict restricted</string>
-    <string name="keywords_keyboard_and_ime">text correction correct sound vibrate auto language gesture suggest suggestion theme offensive word type emoji international</string>
-    <string name="keywords_reset_apps">reset preferences default</string>
-    <string name="keywords_emergency_app">emergency ice app default</string>
-    <string name="keywords_default_phone_app">phone dialer default</string>
-    <string name="keywords_all_apps">apps download applications system</string>
-    <string name="keywords_app_permissions">apps permissions security</string>
-    <string name="keywords_default_apps">apps default</string>
-    <string name="keywords_ignore_optimizations">ignore optimizations doze app standby</string>
-    <string name="keywords_color_mode">vibrant rgb srgb color natural standard</string>
-    <!-- Search keywords for different screen unlock modes : slide to unlock, password, pattern and PIN [CHAR LIMIT=none] -->
-    <string name="keywords_lockscreen">slide password pattern pin</string>
+    <string name="keywords_users">restriction, restrict, restricted</string>
+    <string name="keywords_keyboard_and_ime">text correction, correct, sound, vibrate, auto, language, gesture, suggest, suggestion, theme, offensive, word, type, emoji, international</string>
+    <string name="keywords_reset_apps">reset, preferences, default</string>
+    <string name="keywords_emergency_app">emergency, ice, app, default</string>
+    <string name="keywords_default_phone_app">phone, dialer, default</string>
+    <string name="keywords_all_apps">apps, download, applications, system</string>
+    <string name="keywords_app_permissions">apps, permissions, security</string>
+    <string name="keywords_default_apps">apps, default</string>
+    <string name="keywords_ignore_optimizations">ignore optimizations, doze, app standby</string>
+    <string name="keywords_color_mode">vibrant, rgb, srgb, color, natural, standard</string>
+    <string name="keywords_lockscreen">slide to unlock, password, pattern, pin</string>
 
     <!-- NFC Wi-Fi pairing/setup strings-->
 
@@ -6616,7 +6614,7 @@
     <!-- Title of setting that controls screen zoom (e.g. how large interface elements appear). [CHAR LIMIT=40] -->
     <string name="screen_zoom_title">Screen zoom</string>
     <!-- Keywords for setting that controls screen zoom (e.g. how large interface elements appear). [CHAR LIMIT=NONE] -->
-    <string name="screen_zoom_keywords">display density screen zoom scale scaling</string>
+    <string name="screen_zoom_keywords">display density, screen zoom, scale, scaling</string>
 
     <string name="screen_zoom_summary">Choose how zoomed you want the screen using the slider below the preview image.</string>
 
diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java
index 4c3fb7b..ab81455 100644
--- a/src/com/android/settings/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/ChooseLockSettingsHelper.java
@@ -21,6 +21,7 @@
 import android.app.Fragment;
 import android.app.admin.DevicePolicyManager;
 import android.content.Intent;
+import android.content.IntentSender;
 
 import com.android.internal.widget.LockPatternUtils;
 
@@ -114,6 +115,27 @@
 
     /**
      * If a pattern, password or PIN exists, prompt the user before allowing them to change it.
+     *
+     * @param title title of the confirmation screen; shown in the action bar
+     * @param header header of the confirmation screen; shown as large text
+     * @param description description of the confirmation screen
+     * @param returnCredentials if true, put credentials into intent. Note that if this is true,
+     *                          this can only be called internally.
+     * @param external specifies whether this activity is launched externally, meaning that it will
+     *                 get a dark theme and allow fingerprint authentication
+     * @param userId The userId for whom the lock should be confirmed.
+     * @return true if one exists and we launched an activity to confirm it
+     * @see Activity#onActivityResult(int, int, android.content.Intent)
+     */
+    boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
+            @Nullable CharSequence header, @Nullable CharSequence description,
+            boolean returnCredentials, boolean external, int userId) {
+        return launchConfirmationActivity(request, title, header, description,
+                returnCredentials, external, false, 0, Utils.getSameOwnerUserId(mActivity, userId));
+    }
+
+    /**
+     * If a pattern, password or PIN exists, prompt the user before allowing them to change it.
      * @param message optional message to display about the action about to be done
      * @param details optional detail message to display
      * @param challenge a challenge to be verified against the device credential.
@@ -175,8 +197,18 @@
         if (external) {
             intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
             if (mFragment != null) {
+                IntentSender intentSender = mFragment.getActivity().getIntent()
+                        .getParcelableExtra(Intent.EXTRA_INTENT);
+                if (intentSender != null) {
+                    intent.putExtra(Intent.EXTRA_INTENT, intentSender);
+                }
                 mFragment.startActivity(intent);
             } else {
+                IntentSender intentSender = mActivity.getIntent()
+                        .getParcelableExtra(Intent.EXTRA_INTENT);
+                if (intentSender != null) {
+                    intent.putExtra(Intent.EXTRA_INTENT, intentSender);
+                }
                 mActivity.startActivity(intent);
             }
         } else {
diff --git a/src/com/android/settings/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/ConfirmDeviceCredentialActivity.java
index 86935c3..c4587eb 100644
--- a/src/com/android/settings/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/ConfirmDeviceCredentialActivity.java
@@ -20,7 +20,11 @@
 import android.app.Activity;
 import android.app.KeyguardManager;
 import android.content.Intent;
+import android.os.Binder;
 import android.os.Bundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Log;
 
 /**
@@ -30,6 +34,9 @@
 public class ConfirmDeviceCredentialActivity extends Activity {
     public static final String TAG = ConfirmDeviceCredentialActivity.class.getSimpleName();
 
+    public static class InternalActivity extends ConfirmDeviceCredentialActivity {
+    }
+
     public static Intent createIntent(CharSequence title, CharSequence details) {
         Intent intent = new Intent();
         intent.setClassName("com.android.settings",
@@ -57,13 +64,24 @@
         Intent intent = getIntent();
         String title = intent.getStringExtra(KeyguardManager.EXTRA_TITLE);
         String details = intent.getStringExtra(KeyguardManager.EXTRA_DESCRIPTION);
-
+        int userId = Utils.getEffectiveUserId(this);
+        if (isInternalActivity()) {
+            int givenUserId = intent.getIntExtra(Intent.EXTRA_USER_ID, userId);
+            UserManager userManager = UserManager.get(this);
+            if (userManager.isSameProfileGroup(givenUserId, userId)) {
+                userId = givenUserId;
+            }
+        }
         ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this);
         if (!helper.launchConfirmationActivity(0 /* request code */, null /* title */, title,
-                details, false /* returnCredentials */, true /* isExternal */)) {
+                details, false /* returnCredentials */, true /* isExternal */, userId)) {
             Log.d(TAG, "No pattern, password or PIN set.");
             setResult(Activity.RESULT_OK);
         }
         finish();
     }
+
+    private boolean isInternalActivity() {
+        return this instanceof ConfirmDeviceCredentialActivity.InternalActivity;
+    }
 }
diff --git a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
index 32ad317..e04f86f 100644
--- a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.Button;
@@ -124,4 +125,16 @@
 
     public void startEnterAnimation() {
     }
+
+    protected void checkForPendingIntent() {
+        IntentSender intentSender = getActivity().getIntent()
+                .getParcelableExtra(Intent.EXTRA_INTENT);
+        if (intentSender != null) {
+            try {
+                getActivity().startIntentSenderForResult(intentSender, -1, null, 0, 0, 0);
+            } catch (IntentSender.SendIntentException e) {
+                /* ignore */
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index 7ef6a57..53555e0 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -20,6 +20,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.CountDownTimer;
@@ -405,6 +406,7 @@
             mPasswordEntryInputDisabler.setInputEnabled(true);
             if (matched) {
                 startDisappearAnimation(intent);
+                checkForPendingIntent();
             } else {
                 if (timeoutMs > 0) {
                     long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
index 44e74c9..6331290 100644
--- a/src/com/android/settings/ConfirmLockPattern.java
+++ b/src/com/android/settings/ConfirmLockPattern.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.CountDownTimer;
@@ -473,6 +474,7 @@
             mLockPatternView.setEnabled(true);
             if (matched) {
                 startDisappearAnimation(intent);
+                checkForPendingIntent();
             } else {
                 if (timeoutMs > 0) {
                     long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
diff --git a/src/com/android/settings/search/Index.java b/src/com/android/settings/search/Index.java
index 73386fb..3fd06a2 100644
--- a/src/com/android/settings/search/Index.java
+++ b/src/com/android/settings/search/Index.java
@@ -150,7 +150,9 @@
 
     private static final String EMPTY = "";
     private static final String NON_BREAKING_HYPHEN = "\u2011";
+    private static final String LIST_DELIMITERS = "[,]\\s*";
     private static final String HYPHEN = "-";
+    private static final String SPACE = " ";
 
     private static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER =
             "SEARCH_INDEX_DATA_PROVIDER";
@@ -1002,12 +1004,13 @@
         final String normalizedSummaryOn = normalizeString(updatedSummaryOn);
         final String normalizedSummaryOff = normalizeString(updatedSummaryOff);
 
+        final String spaceDelimitedKeywords = normalizeKeywords(keywords);
+
         updateOneRow(database, locale,
                 updatedTitle, normalizedTitle, updatedSummaryOn, normalizedSummaryOn,
-                updatedSummaryOff, normalizedSummaryOff, entries,
-                className, screenTitle, iconResId,
-                rank, keywords, intentAction, intentTargetPackage, intentTargetClass, enabled,
-                key, userId);
+                updatedSummaryOff, normalizedSummaryOff, entries, className, screenTitle, iconResId,
+                rank, spaceDelimitedKeywords, intentAction, intentTargetPackage, intentTargetClass,
+                enabled, key, userId);
     }
 
     private static String normalizeHyphen(String input) {
@@ -1021,11 +1024,14 @@
         return REMOVE_DIACRITICALS_PATTERN.matcher(normalized).replaceAll("").toLowerCase();
     }
 
-    private void updateOneRow(SQLiteDatabase database, String locale,
-            String updatedTitle, String normalizedTitle,
-            String updatedSummaryOn, String normalizedSummaryOn,
-            String updatedSummaryOff, String normalizedSummaryOff, String entries,
-            String className, String screenTitle, int iconResId, int rank, String keywords,
+    private static String normalizeKeywords(String input) {
+        return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY;
+    }
+
+    private void updateOneRow(SQLiteDatabase database, String locale, String updatedTitle,
+            String normalizedTitle, String updatedSummaryOn, String normalizedSummaryOn,
+            String updatedSummaryOff, String normalizedSummaryOff, String entries, String className,
+            String screenTitle, int iconResId, int rank, String spaceDelimitedKeywords,
             String intentAction, String intentTargetPackage, String intentTargetClass,
             boolean enabled, String key, int userId) {
 
@@ -1050,7 +1056,7 @@
         values.put(IndexColumns.DATA_SUMMARY_OFF, updatedSummaryOff);
         values.put(IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, normalizedSummaryOff);
         values.put(IndexColumns.DATA_ENTRIES, entries);
-        values.put(IndexColumns.DATA_KEYWORDS, keywords);
+        values.put(IndexColumns.DATA_KEYWORDS, spaceDelimitedKeywords);
         values.put(IndexColumns.CLASS_NAME, className);
         values.put(IndexColumns.SCREEN_TITLE, screenTitle);
         values.put(IndexColumns.INTENT_ACTION, intentAction);