Merge "Refactor Settings theme colors." into nyc-mr1-dev
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index 44cf585..cdee328 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -51,10 +51,11 @@
         android:title="@string/bt_hci_snoop_log"
         android:summary="@string/bt_hci_snoop_log_summary"/>
 
-    <SwitchPreference
+    <com.android.settingslib.RestrictedSwitchPreference
         android:key="oem_unlock_enable"
         android:title="@string/oem_unlock_enable"
-        android:summary="@string/oem_unlock_enable_summary"/>
+        android:summary="@string/oem_unlock_enable_summary"
+        settings:useAdditionalSummary="true"/>
 
     <PreferenceScreen
         android:key="running_apps"
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index e28a586..6a0abe3 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -239,7 +239,7 @@
     private SwitchPreference mBugreportInPower;
     private RestrictedSwitchPreference mKeepScreenOn;
     private SwitchPreference mBtHciSnoopLog;
-    private SwitchPreference mEnableOemUnlock;
+    private RestrictedSwitchPreference mEnableOemUnlock;
     private SwitchPreference mDebugViewAttributes;
     private SwitchPreference mForceAllowOnExternal;
 
@@ -372,7 +372,7 @@
         mBugreportInPower = findAndInitSwitchPref(BUGREPORT_IN_POWER_KEY);
         mKeepScreenOn = (RestrictedSwitchPreference) findAndInitSwitchPref(KEEP_SCREEN_ON);
         mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG);
-        mEnableOemUnlock = findAndInitSwitchPref(ENABLE_OEM_UNLOCK);
+        mEnableOemUnlock = (RestrictedSwitchPreference) findAndInitSwitchPref(ENABLE_OEM_UNLOCK);
         if (!showEnableOemUnlockPreference()) {
             removePreference(mEnableOemUnlock);
             mEnableOemUnlock = null;
@@ -1021,7 +1021,21 @@
 
     private void updateOemUnlockOptions() {
         if (mEnableOemUnlock != null) {
+            // Showing mEnableOemUnlock preference as device has persistent data block.
+            mEnableOemUnlock.setDisabledByAdmin(null);
             mEnableOemUnlock.setEnabled(enableOemUnlockPreference());
+            if (mEnableOemUnlock.isEnabled()) {
+                // mEnableOemUnlock is enabled as device's flash lock is unlocked.
+                if (RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
+                        UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) {
+                    // Set mEnableOemUnlock to disabled as restriction is set, but not by admin.
+                    mEnableOemUnlock.setEnabled(false);
+                } else {
+                    // Check restriction, disable mEnableOemUnlock and apply policy transparency.
+                    mEnableOemUnlock
+                            .checkRestrictionAndSetDisabled(UserManager.DISALLOW_FACTORY_RESET);
+                }
+            }
         }
     }
 
diff --git a/src/com/android/settings/TrustedCredentialsDialogBuilder.java b/src/com/android/settings/TrustedCredentialsDialogBuilder.java
index 2508d8c..da557fe 100644
--- a/src/com/android/settings/TrustedCredentialsDialogBuilder.java
+++ b/src/com/android/settings/TrustedCredentialsDialogBuilder.java
@@ -38,12 +38,14 @@
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.IntConsumer;
 
 class TrustedCredentialsDialogBuilder extends AlertDialog.Builder {
     public interface DelegateInterface {
         List<X509Certificate> getX509CertsFromCertHolder(CertHolder certHolder);
         void removeOrInstallCert(CertHolder certHolder);
-        boolean startConfirmCredentialIfNotConfirmed(int userId);
+        boolean startConfirmCredentialIfNotConfirmed(int userId,
+                IntConsumer onCredentialConfirmedListener);
     }
 
     private final DialogEventHandler mDialogEventHandler;
@@ -145,7 +147,8 @@
 
         private void onClickTrust() {
             CertHolder certHolder = getCurrentCertInfo();
-            if (!mDelegate.startConfirmCredentialIfNotConfirmed(certHolder.getUserId())) {
+            if (!mDelegate.startConfirmCredentialIfNotConfirmed(certHolder.getUserId(),
+                    this::onCredentialConfirmed)) {
                 mDpm.approveCaCert(certHolder.getAlias(), certHolder.getUserId(), true);
                 nextOrDismiss();
             }
@@ -168,6 +171,14 @@
                     .show();
         }
 
+        private void onCredentialConfirmed(int userId) {
+            if (mDialog.isShowing() && mNeedsApproval && getCurrentCertInfo() != null
+                    && getCurrentCertInfo().getUserId() == userId) {
+                // Treat it as user just clicks "trust" for this cert
+                onClickTrust();
+            }
+        }
+
         private CertHolder getCurrentCertInfo() {
             return mCurrentCertIndex < mCertHolders.length ? mCertHolders[mCurrentCertIndex] : null;
         }
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index 4100e75..92b7f6b 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -68,6 +68,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.function.IntConsumer;
 
 public class TrustedCredentialsSettings extends OptionsMenuFragment
         implements TrustedCredentialsDialogBuilder.DelegateInterface {
@@ -159,6 +160,7 @@
     private AliasOperation mAliasOperation;
     private ArraySet<Integer> mConfirmedCredentialUsers;
     private int mConfirmingCredentialUser;
+    private IntConsumer mConfirmingCredentialListener;
     private Set<AdapterData.AliasLoader> mAliasLoaders = new ArraySet<AdapterData.AliasLoader>(2);
     private final SparseArray<KeyChainConnection>
             mKeyChainConnectionByProfileId = new SparseArray<KeyChainConnection>();
@@ -199,6 +201,8 @@
             }
         }
 
+        mConfirmingCredentialListener = null;
+
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
@@ -246,10 +250,18 @@
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == REQUEST_CONFIRM_CREDENTIALS) {
-            if (resultCode == Activity.RESULT_OK) {
-                mConfirmedCredentialUsers.add(mConfirmingCredentialUser);
-            }
+            int userId = mConfirmingCredentialUser;
+            IntConsumer listener = mConfirmingCredentialListener;
+            // reset them before calling the listener because the listener may call back to start
+            // activity again. (though it should never happen.)
             mConfirmingCredentialUser = UserHandle.USER_NULL;
+            mConfirmingCredentialListener = null;
+            if (resultCode == Activity.RESULT_OK) {
+                mConfirmedCredentialUsers.add(userId);
+                if (listener != null) {
+                    listener.accept(userId);
+                }
+            }
         }
     }
 
@@ -942,12 +954,18 @@
     }
 
     @Override
-    public boolean startConfirmCredentialIfNotConfirmed(int userId) {
+    public boolean startConfirmCredentialIfNotConfirmed(int userId,
+            IntConsumer onCredentialConfirmedListener) {
         if (mConfirmedCredentialUsers.contains(userId)) {
             // Credential has been confirmed. Don't start activity.
             return false;
         }
-        return startConfirmCredential(userId);
+
+        boolean result = startConfirmCredential(userId);
+        if (result) {
+            mConfirmingCredentialListener = onCredentialConfirmedListener;
+        }
+        return result;
     }
 
     private class AliasOperation extends AsyncTask<Void, Void, Boolean> {
diff --git a/src/com/android/settings/deletionhelper/AppDeletionPreference.java b/src/com/android/settings/deletionhelper/AppDeletionPreference.java
index cb025ab..97420c2 100644
--- a/src/com/android/settings/deletionhelper/AppDeletionPreference.java
+++ b/src/com/android/settings/deletionhelper/AppDeletionPreference.java
@@ -22,6 +22,7 @@
 import android.view.View;
 import android.widget.Switch;
 import android.widget.TextView;
+import com.android.settings.deletionhelper.AppStateUsageStatsBridge.UsageStatsState;
 import com.android.settings.R;
 
 import com.android.settingslib.applications.ApplicationsState;
@@ -72,18 +73,18 @@
             return;
         }
 
-        long daysSinceLastUse = (long) mEntry.extraInfo;
+        UsageStatsState extraData = (UsageStatsState) mEntry.extraInfo;
         String fileSize = Formatter.formatFileSize(mContext, mEntry.size);
-        if (daysSinceLastUse == AppStateUsageStatsBridge.NEVER_USED) {
+        if (extraData.daysSinceLastUse == AppStateUsageStatsBridge.NEVER_USED) {
             summary.setText(mContext.getString(R.string.deletion_helper_app_summary_never_used,
                     fileSize));
-        } else if (daysSinceLastUse == AppStateUsageStatsBridge.UNKNOWN_LAST_USE) {
+        } else if (extraData.daysSinceLastUse == AppStateUsageStatsBridge.UNKNOWN_LAST_USE) {
             summary.setText(mContext.getString(R.string.deletion_helper_app_summary_unknown_used,
                     fileSize));
         } else {
             summary.setText(mContext.getString(R.string.deletion_helper_app_summary,
                     fileSize,
-                    daysSinceLastUse));
+                    extraData.daysSinceLastUse));
         }
     }
 
diff --git a/src/com/android/settings/deletionhelper/AppStateUsageStatsBridge.java b/src/com/android/settings/deletionhelper/AppStateUsageStatsBridge.java
index 7bbe8bf..36c4196 100644
--- a/src/com/android/settings/deletionhelper/AppStateUsageStatsBridge.java
+++ b/src/com/android/settings/deletionhelper/AppStateUsageStatsBridge.java
@@ -137,7 +137,10 @@
         }
     };
 
-    private class UsageStatsState {
+    /**
+     * UsageStatsState contains the days since the last use and first install of a given app.
+     */
+    public static class UsageStatsState {
         public long daysSinceLastUse;
         public long daysSinceFirstInstall;