Merge "Import translations. DO NOT MERGE" into lmp-dev
diff --git a/res/layout/bluetooth_pin_confirm.xml b/res/layout/bluetooth_pin_confirm.xml
index 241bedc..08f5d9f 100644
--- a/res/layout/bluetooth_pin_confirm.xml
+++ b/res/layout/bluetooth_pin_confirm.xml
@@ -24,6 +24,7 @@
 
     <LinearLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
+        android:paddingStart="16dip"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:orientation="vertical">
diff --git a/res/layout/bluetooth_pin_entry.xml b/res/layout/bluetooth_pin_entry.xml
index 7161342..6f50cd4 100644
--- a/res/layout/bluetooth_pin_entry.xml
+++ b/res/layout/bluetooth_pin_entry.xml
@@ -84,7 +84,8 @@
             android:layout_marginStart="@dimen/bluetooth_dialog_padding"
             android:layout_marginEnd="@dimen/bluetooth_dialog_padding"
             android:gravity="center_vertical"
-            android:textAppearance="?android:attr/textAppearanceMedium" />
+            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+            android:textColor="@*android:color/secondary_text_material_light"/>
 
         <TextView
             android:id="@+id/phonebook_sharing_message"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index c7c0020..0a09a9c 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -894,6 +894,13 @@
         <item>16M</item>
     </string-array>
 
+    <!-- Titles for logd limit size lowram selection preference. [CHAR LIMIT=14] -->
+    <string-array name="select_logd_size_lowram_titles">
+        <item>64K</item>
+        <item>256K</item>
+        <item>1M</item>
+    </string-array>
+
     <!-- Values for logd limit size selection preference. -->
     <string-array name="select_logd_size_values" translatable="false" >
         <item>65536</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index df9afb4..e7a124e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -269,7 +269,7 @@
     <!-- Bluetooth Settings. text displayed when user has restriction DISALLOW_CONFIG_BLUETOOTH [CHAR LIMIT=NONE]-->
     <string name="bluetooth_empty_list_user_restricted">You don\'t have permission to change Bluetooth settings.</string>
 
-    <!-- Bluetooth Visibility message.  This message informs the user that their device is now visible to other bluetooth devices.  [CHAR LIMIT=50] -->
+    <!-- Bluetooth Visibility message.  This message informs the user that their device is now visible to other bluetooth devices.  [CHAR LIMIT=NONE] -->
     <string name="bluetooth_is_visible_message"><xliff:g id="device_name">%1$s</xliff:g> is visible to nearby devices while Bluetooth Settings is open.</string>
     <!-- Bluetooth Visibility discoonect question.  Asks the user if they wish to disconnect a paired bluetooth device.  [CHAR LIMIT=50] -->
     <string name="bluetooth_is_disconnect_question">Disconnect <xliff:g id="device_name">%1$s</xliff:g>?</string>
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 90f9f54..013fd3a 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -752,8 +752,9 @@
         mHandler.removeMessages(MESSAGE_NOTIFY);
         mHandler.sendEmptyMessageDelayed(MESSAGE_NOTIFY, 120 * 1000);
 
-        // Dismiss keyguard while this screen is showing.
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+        // Dismiss secure & non-secure keyguards while this screen is showing.
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
     }
 
     /**
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index d801ae0..8bc4b64 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -1107,9 +1107,13 @@
             }
             String[] values = getResources().getStringArray(R.array.select_logd_size_values);
             String[] titles = getResources().getStringArray(R.array.select_logd_size_titles);
+            if (SystemProperties.get("ro.config.low_ram").equals("true")) {
+                mLogdSize.setEntries(R.array.select_logd_size_lowram_titles);
+                titles = getResources().getStringArray(R.array.select_logd_size_lowram_titles);
+            }
             String[] summaries = getResources().getStringArray(R.array.select_logd_size_summaries);
             int index = 1; // punt to second entry if not found
-            for (int i = 0; i < values.length; i++) {
+            for (int i = 0; i < titles.length; i++) {
                 if (currentValue.equals(values[i])
                         || currentValue.equals(titles[i])) {
                     index = i;
@@ -1123,6 +1127,10 @@
     }
 
     private void writeLogdSizeOption(Object newValue) {
+        String currentValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
+        if (currentValue != null) {
+            DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = currentValue;
+        }
         final String size = (newValue != null) ?
                 newValue.toString() : DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES;
         SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, size);
diff --git a/src/com/android/settings/HomeSettings.java b/src/com/android/settings/HomeSettings.java
index 2ac93c6..cd60091 100644
--- a/src/com/android/settings/HomeSettings.java
+++ b/src/com/android/settings/HomeSettings.java
@@ -250,8 +250,7 @@
     }
 
     private boolean versionNumberAtLeastL(int versionNumber) {
-        // TODO: remove "|| true" once the build code for L is fixed.
-        return versionNumber >= Build.VERSION_CODES.L || true;
+        return versionNumber >= Build.VERSION_CODES.L;
     }
 
     @Override
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index c566f6c..ffb55d6 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -858,6 +858,33 @@
     }
 
     /**
+     * Start a new fragment in a new activity containing a preference panel for a given user. If the
+     * preferences are being displayed in multi-pane mode, the given fragment class will be
+     * instantiated and placed in the appropriate pane. If running in single-pane mode, a new
+     * activity will be launched in which to show the fragment.
+     *
+     * @param fragmentClass Full name of the class implementing the fragment.
+     * @param args Any desired arguments to supply to the fragment.
+     * @param titleRes Optional resource identifier of the title of this fragment.
+     * @param titleText Optional text of the title of this fragment.
+     * @param userHandle The user for which the panel has to be started.
+     */
+    public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes,
+            CharSequence titleText, UserHandle userHandle) {
+        String title = null;
+        if (titleRes < 0) {
+            if (titleText != null) {
+                title = titleText.toString();
+            } else {
+                // There not much we can do in that case
+                title = "";
+            }
+        }
+        Utils.startWithFragmentAsUser(this, fragmentClass, args,
+                titleRes, title, mIsShortcut, userHandle);
+    }
+
+    /**
      * Called by a preference panel fragment to finish itself.
      *
      * @param caller The fragment that is asking to be finished.
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 60bf226..de9fac7 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -609,6 +609,13 @@
         }
     }
 
+    public static void startWithFragmentAsUser(Context context, String fragmentName, Bundle args,
+            int titleResId, CharSequence title, boolean isShortcut, UserHandle userHandle) {
+        Intent intent = onBuildStartFragmentIntent(context, fragmentName, args, titleResId,
+                title, isShortcut);
+        context.startActivityAsUser(intent, userHandle);
+    }
+
     /**
      * Build an Intent to launch a new activity showing the selected fragment.
      * The implementation constructs an Intent that re-launches the current activity with the
diff --git a/src/com/android/settings/bluetooth/BluetoothEventManager.java b/src/com/android/settings/bluetooth/BluetoothEventManager.java
index 0eead85..bf7606e 100755
--- a/src/com/android/settings/bluetooth/BluetoothEventManager.java
+++ b/src/com/android/settings/bluetooth/BluetoothEventManager.java
@@ -206,7 +206,7 @@
             }
             cachedDevice.setRssi(rssi);
             cachedDevice.setBtClass(btClass);
-            cachedDevice.setName(name);
+            cachedDevice.setNewName(name);
             cachedDevice.setVisible(true);
         }
     }
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
index 6d0e690..fd8489b 100755
--- a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
@@ -235,6 +235,7 @@
         switch (mType) {
             case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
             case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
+                messagePairing.setVisibility(View.VISIBLE);
             case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
                 messageCaption = getString(R.string.bluetooth_enter_pin_msg);
                 pairingContent = mPairingKey;
@@ -242,6 +243,7 @@
 
             case BluetoothDevice.PAIRING_VARIANT_CONSENT:
             case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
+                messagePairing.setVisibility(View.VISIBLE);
                 messageCaption = getString(R.string.bluetooth_enter_pin_msg);
                 break;
 
@@ -259,7 +261,6 @@
             pairingViewCaption.setVisibility(View.VISIBLE);
             pairingViewContent.setVisibility(View.VISIBLE);
             pairingViewContent.setText(pairingContent);
-            messagePairing.setVisibility(View.VISIBLE);
         }
 
         return view;
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index 6d2222e..bcb803b 100755
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -381,15 +381,26 @@
         return mName;
     }
 
+    /**
+     * Populate name from BluetoothDevice.ACTION_FOUND intent
+     */
+    void setNewName(String name) {
+        if (mName == null) {
+            mName = name;
+            if (mName == null || TextUtils.isEmpty(mName)) {
+                mName = mDevice.getAddress();
+            }
+            dispatchAttributesChanged();
+        }
+    }
+
+    /**
+     * user changes the device name
+     */
     void setName(String name) {
         if (!mName.equals(name)) {
-            if (TextUtils.isEmpty(name)) {
-                // TODO: use friendly name for unknown device (bug 1181856)
-                mName = mDevice.getAddress();
-            } else {
-                mName = name;
-                mDevice.setAlias(name);
-            }
+            mName = name;
+            mDevice.setAlias(name);
             dispatchAttributesChanged();
         }
     }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index b745c9d..36a2444 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -104,6 +104,7 @@
         args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, entry.sipper.drainType);
         args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton);
 
+        int userId = UserHandle.myUserId();
         int[] types;
         double[] values;
         switch (entry.sipper.drainType) {
@@ -155,6 +156,7 @@
                     printWriter.flush();
                     args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS,
                             result.toString());
+                    userId = UserHandle.getUserId(uid.getUid());
                 }
             }
             break;
@@ -256,8 +258,9 @@
         }
         args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types);
         args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values);
-        caller.startPreferencePanel(PowerUsageDetail.class.getName(), args,
-                R.string.details_title, null, null, 0);
+
+        caller.startPreferencePanelAsUser(PowerUsageDetail.class.getName(), args,
+                R.string.details_title, null, new UserHandle(userId));
     }
 
     public static final int ACTION_DISPLAY_SETTINGS = 1;
diff --git a/src/com/android/settings/print/PrintJobSettingsFragment.java b/src/com/android/settings/print/PrintJobSettingsFragment.java
index a72fa7d..34db97b 100644
--- a/src/com/android/settings/print/PrintJobSettingsFragment.java
+++ b/src/com/android/settings/print/PrintJobSettingsFragment.java
@@ -112,13 +112,18 @@
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
 
-        if (!getPrintJob().getInfo().isCancelling()) {
+        PrintJob printJob = getPrintJob();
+        if (printJob == null) {
+            return;
+        }
+
+        if (!printJob.getInfo().isCancelling()) {
             MenuItem cancel = menu.add(0, MENU_ITEM_ID_CANCEL, Menu.NONE,
                     getString(R.string.print_cancel));
             cancel.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
         }
 
-        if (getPrintJob().isFailed()) {
+        if (printJob.isFailed()) {
             MenuItem restart = menu.add(0, MENU_ITEM_ID_RESTART, Menu.NONE,
                     getString(R.string.print_restart));
             restart.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 0d7b279..872f71f 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -920,8 +920,11 @@
                 return;
             }
         }
-        // No guest user. Create one.
-        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
+        // No guest user. Create one, if there's no restriction.
+        // If it is not the primary user, then adding users from lockscreen must be enabled
+        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)
+                || (!mIsOwner && Settings.Global.getInt(getContentResolver(),
+                        Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 1)) {
             Log.i(TAG, "Blocking guest creation because it is restricted");
             return;
         }
diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java
index ffc10a0..8426439 100644
--- a/src/com/android/settings/wifi/WifiEnabler.java
+++ b/src/com/android/settings/wifi/WifiEnabler.java
@@ -40,6 +40,7 @@
 public class WifiEnabler implements SwitchBar.OnSwitchChangeListener  {
     private Context mContext;
     private SwitchBar mSwitchBar;
+    private boolean mListeningToOnSwitchChange = false;
     private AtomicBoolean mConnected = new AtomicBoolean(false);
 
     private final WifiManager mWifiManager;
@@ -99,23 +100,41 @@
     public void setupSwitchBar() {
         final int state = mWifiManager.getWifiState();
         handleWifiStateChanged(state);
-        mSwitchBar.addOnSwitchChangeListener(this);
+        if (!mListeningToOnSwitchChange) {
+            mSwitchBar.addOnSwitchChangeListener(this);
+            mListeningToOnSwitchChange = true;
+        }
         mSwitchBar.show();
+
+        mContext.registerReceiver(mReceiver, mIntentFilter);
     }
 
     public void teardownSwitchBar() {
-        mSwitchBar.removeOnSwitchChangeListener(this);
+        if (mListeningToOnSwitchChange) {
+            mSwitchBar.removeOnSwitchChangeListener(this);
+            mListeningToOnSwitchChange = false;
+        }
         mSwitchBar.hide();
+
+        mContext.unregisterReceiver(mReceiver);
     }
 
     public void resume(Context context) {
         mContext = context;
         // Wi-Fi state is sticky, so just let the receiver update UI
         mContext.registerReceiver(mReceiver, mIntentFilter);
+        if (!mListeningToOnSwitchChange) {
+            mSwitchBar.addOnSwitchChangeListener(this);
+            mListeningToOnSwitchChange = true;
+        }
     }
 
     public void pause() {
         mContext.unregisterReceiver(mReceiver);
+        if (mListeningToOnSwitchChange) {
+            mSwitchBar.removeOnSwitchChangeListener(this);
+            mListeningToOnSwitchChange = false;
+        }
     }
 
     private void handleWifiStateChanged(int state) {
diff --git a/src/com/android/settings/wifi/WifiSetupActivity.java b/src/com/android/settings/wifi/WifiSetupActivity.java
index 5452a03..a87c733 100644
--- a/src/com/android/settings/wifi/WifiSetupActivity.java
+++ b/src/com/android/settings/wifi/WifiSetupActivity.java
@@ -87,9 +87,10 @@
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
-                    WifiManager.EXTRA_NETWORK_INFO);
-            refreshConnectionState(info.isConnected());
+            // Refresh the connection state with the latest connection info. Use the connection info
+            // from ConnectivityManager instead of the one attached in the intent to make sure
+            // we have the most up-to-date connection state. b/17511772
+            refreshConnectionState();
         }
     };