Restriction pin changes.

Fixed bug in WirelessSettings where it was asking users for a PIN when
they weren't restricted.  Did this by refactoring the preference level
pin checking into the superclass, where it checks for the restricted mode first.
Also pin protected changes to certificates for restricted users.

Change-Id: I8310fd39f0862159668318fc1360ec6859cc00d5
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index dd04cd9..c727bcc 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -54,7 +54,6 @@
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.PreferenceFragment;
 import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
@@ -210,7 +209,6 @@
             = new ArrayList<CheckBoxPreference>();
 
     private final HashSet<Preference> mDisabledPrefs = new HashSet<Preference>();
-    private final HashSet<Preference> mProtectedByRestrictionsPrefs = new HashSet<Preference>();
 
     // To track whether a confirmation dialog was clicked.
     private boolean mDialogClicked;
@@ -362,12 +360,6 @@
         }
     }
 
-    private void protectByRestrictions(Preference pref) {
-        if (pref != null) {
-            mProtectedByRestrictionsPrefs.add(pref);
-        }
-    }
-
     private CheckBoxPreference findAndInitCheckboxPref(String key) {
         CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
         if (pref == null) {
@@ -1178,11 +1170,9 @@
 
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (mProtectedByRestrictionsPrefs.contains(preference)
-                && !restrictionsPinCheck(RESTRICTIONS_PIN_SET)) {
-            return false;
+        if (super.onPreferenceTreeClick(preferenceScreen, preference)) {
+            return true;
         }
-
         if (Utils.isMonkeyRunning()) {
             return false;
         }
diff --git a/src/com/android/settings/RestrictedSettingsFragment.java b/src/com/android/settings/RestrictedSettingsFragment.java
index ebf2bcf..e25570e 100644
--- a/src/com/android/settings/RestrictedSettingsFragment.java
+++ b/src/com/android/settings/RestrictedSettingsFragment.java
@@ -16,11 +16,15 @@
 
 package com.android.settings;
 
+import java.util.HashSet;
+
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.UserManager;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
 
 /**
  * Base class for settings activities that should be pin protected when in restricted mode.
@@ -50,6 +54,8 @@
 
     private final String mRestrictionKey;
 
+    private final HashSet<Preference> mProtectedByRestictionsPrefs = new HashSet<Preference>();
+
     /**
      * @param restrictionKey The restriction key to check before pin protecting
      *            this settings page. Pass in {@link RESTRICTIONS_PIN_SET} if it should
@@ -162,4 +168,30 @@
                || mUserManager.hasUserRestriction(restrictionKey);
        return restricted && mUserManager.hasRestrictionsPin();
    }
+
+   /**
+    * If the preference is one that was added by protectByRestrictions(), then it will
+    * prompt the user for the restrictions pin if they haven't entered it already.
+    * Intended to be called at the top of onPreferenceTreeClick.  If this function returns
+    * true, then onPreferenceTreeClick should return true.
+    */
+   boolean ensurePinRestrictedPreference(Preference preference) {
+       return mProtectedByRestictionsPrefs.contains(preference)
+               && !restrictionsPinCheck(RESTRICTIONS_PIN_SET);
+   }
+
+    /**
+     * Call this with any preferences that should require the PIN to be entered
+     * before they are accessible.
+     */
+   protected void protectByRestrictions(Preference pref) {
+       if (pref != null) {
+           mProtectedByRestictionsPrefs.add(pref);
+       }
+   }
+
+   protected void protectByRestrictions(String key) {
+       Preference pref = findPreference(key);
+       protectByRestrictions(pref);
+   }
 }
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 7a442a9..f893c36 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -45,7 +45,6 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -75,6 +74,7 @@
     private static final String KEY_SHOW_PASSWORD = "show_password";
     private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type";
     private static final String KEY_RESET_CREDENTIALS = "reset_credentials";
+    private static final String KEY_CREDENTIALS_INSTALL = "credentials_install";
     private static final String KEY_TOGGLE_INSTALL_APPLICATIONS = "toggle_install_applications";
     private static final String KEY_TOGGLE_VERIFY_APPLICATIONS = "toggle_verify_applications";
     private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks";
@@ -82,8 +82,6 @@
     private static final String KEY_NOTIFICATION_ACCESS = "manage_notification_access";
     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
 
-    private final HashSet<Preference> mProtectedByRestictionsPrefs = new HashSet<Preference>();
-
     private PackageManager mPM;
     DevicePolicyManager mDPM;
 
@@ -245,6 +243,7 @@
 
         // Show password
         mShowPassword = (CheckBoxPreference) root.findPreference(KEY_SHOW_PASSWORD);
+        mResetCredentials = root.findPreference(KEY_RESET_CREDENTIALS);
 
         // Credential storage
         final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
@@ -257,7 +256,6 @@
                         : R.string.credential_storage_type_software;
             credentialStorageType.setSummary(storageSummaryRes);
 
-            mResetCredentials = root.findPreference(KEY_RESET_CREDENTIALS);
         } else {
             removePreference(KEY_CREDENTIALS_MANAGER);
         }
@@ -312,16 +310,12 @@
         if (shouldBePinProtected(RESTRICTIONS_PIN_SET)) {
             protectByRestrictions(mToggleAppInstallation);
             protectByRestrictions(mToggleVerifyApps);
+            protectByRestrictions(mResetCredentials);
+            protectByRestrictions(root.findPreference(KEY_CREDENTIALS_INSTALL));
         }
         return root;
     }
 
-    private void protectByRestrictions(Preference pref) {
-        if (pref != null) {
-            mProtectedByRestictionsPrefs.add(pref);
-        }
-    }
-
     private int getNumEnabledNotificationListeners() {
         final String flat = Settings.Secure.getString(getContentResolver(),
                 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
@@ -487,11 +481,9 @@
 
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (mProtectedByRestictionsPrefs.contains(preference)
-                && !restrictionsPinCheck(RESTRICTIONS_PIN_SET)) {
-            return false;
+        if (ensurePinRestrictedPreference(preference)) {
+            return true;
         }
-
         final String key = preference.getKey();
 
         final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 60765a9..0a382b5 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -241,7 +241,7 @@
                     mParentFragment = getFragmentManager().findFragmentById(mParentFragmentId);
                     if (!(mParentFragment instanceof DialogCreatable)) {
                         throw new IllegalArgumentException(
-                                (mParentFragment != null 
+                                (mParentFragment != null
                                         ? mParentFragment.getClass().getName()
                                         : mParentFragmentId)
                                 + " must implement "
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index cdfe7cd..b3716e3 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -16,14 +16,18 @@
 
 package com.android.settings;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.Fragment;
+import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.net.http.SslCertificate;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.os.UserManager;
 import android.security.IKeyChainService;
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
@@ -52,6 +56,14 @@
 
     private static final String TAG = "TrustedCredentialsSettings";
 
+    private UserManager mUserManager;
+
+    private static final int REQUEST_PIN_CHALLENGE = 12309;
+    // If the restriction PIN is entered correctly.
+    private boolean mChallengeSucceeded;
+    private boolean mChallengeRequested;
+
+
     private enum Tab {
         SYSTEM("system",
                R.string.trusted_credentials_system_tab,
@@ -142,6 +154,13 @@
 
     private TabHost mTabHost;
 
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mUserManager = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
+    }
+
+
     @Override public View onCreateView(
             LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
         mTabHost = (TabHost) inflater.inflate(R.layout.trusted_credentials, parent, false);
@@ -355,6 +374,11 @@
         removeButton.setText(certHolder.mTab.getButtonLabel(certHolder));
         removeButton.setOnClickListener(new View.OnClickListener() {
             @Override public void onClick(View v) {
+                if (mUserManager.hasRestrictionsPin() && !mChallengeSucceeded) {
+                    ensurePin();
+                    return;
+                }
+
                 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                 builder.setMessage(certHolder.mTab.getButtonConfirmation(certHolder));
                 builder.setPositiveButton(
@@ -379,6 +403,35 @@
         certDialog.show();
     }
 
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_PIN_CHALLENGE) {
+            mChallengeRequested = false;
+            if (resultCode == Activity.RESULT_OK) {
+                mChallengeSucceeded = true;
+            }
+            return;
+        }
+
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
+    private void ensurePin() {
+        if (!mChallengeSucceeded) {
+            final UserManager um = UserManager.get(getActivity());
+            if (!mChallengeRequested) {
+                if (um.hasRestrictionsPin()) {
+                    Intent requestPin =
+                            new Intent(Intent.ACTION_RESTRICTIONS_PIN_CHALLENGE);
+                    startActivityForResult(requestPin, REQUEST_PIN_CHALLENGE);
+                    mChallengeRequested = true;
+                }
+            }
+        }
+        mChallengeSucceeded = false;
+    }
+
+
     private class AliasOperation extends AsyncTask<Void, Void, Boolean> {
         private final CertHolder mCertHolder;
         private AliasOperation(CertHolder certHolder) {
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index ecb984d..81c1794 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -16,7 +16,6 @@
 
 package com.android.settings;
 
-import java.util.HashSet;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -75,7 +74,6 @@
 
     private static final int MANAGE_MOBILE_PLAN_DIALOG_ID = 1;
     private static final String SAVED_MANAGE_MOBILE_PLAN_MSG = "mManageMobilePlanMessage";
-    private final HashSet<Preference> mProtectedByRestictionsPrefs = new HashSet<Preference>();
 
     public WirelessSettings() {
         super(null);
@@ -87,9 +85,8 @@
      */
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (mProtectedByRestictionsPrefs.contains(preference) && !hasChallengeSucceeded()) {
-            restrictionsPinCheck(RESTRICTIONS_PIN_SET);
-            return false;
+        if (ensurePinRestrictedPreference(preference)) {
+            return true;
         }
         log("onPreferenceTreeClick: preference=" + preference);
         if (preference == mAirplaneModePreference && Boolean.parseBoolean(
@@ -155,13 +152,6 @@
         }
     }
 
-    private void protectByRestrictions(String key) {
-        Preference pref = findPreference(key);
-        if (pref != null) {
-            mProtectedByRestictionsPrefs.add(pref);
-        }
-    }
-
     @Override
     public Dialog onCreateDialog(int dialogId) {
         log("onCreateDialog: dialogId=" + dialogId);