Merge "Fix ConfirmCredential is not presented before trusting cert installed by PO/DO" into nyc-dev
diff --git a/src/com/android/settings/MonitoringCertInfoActivity.java b/src/com/android/settings/MonitoringCertInfoActivity.java
index 9df3413..8ad9d83 100644
--- a/src/com/android/settings/MonitoringCertInfoActivity.java
+++ b/src/com/android/settings/MonitoringCertInfoActivity.java
@@ -29,15 +29,20 @@
 
 /**
  * Activity that shows a dialog explaining that a CA cert is allowing someone to monitor network
- * traffic. This activity should be launched for the user into which the CA cert is installed.
+ * traffic. This activity should be launched for the user into which the CA cert is installed
+ * unless Intent.EXTRA_USER_ID is provided.
  */
 public class MonitoringCertInfoActivity extends Activity implements OnClickListener,
         OnDismissListener {
 
+    private int mUserId;
+
     @Override
     protected void onCreate(Bundle savedStates) {
         super.onCreate(savedStates);
 
+        mUserId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId());
+
         DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class);
         final int numberOfCertificates = getIntent().getIntExtra(
                 Settings.EXTRA_NUMBER_OF_CERTIFICATES, 1);
@@ -53,7 +58,7 @@
         builder.setNeutralButton(R.string.cancel, null);
         builder.setOnDismissListener(this);
 
-        if (dpm.getProfileOwner() != null) {
+        if (dpm.getProfileOwnerAsUser(mUserId) != null) {
             builder.setMessage(getResources().getQuantityString(R.plurals.ssl_ca_cert_info_message,
                     numberOfCertificates, dpm.getProfileOwnerName()));
         } else if (dpm.getDeviceOwnerComponentOnCallingUser() != null) {
@@ -73,7 +78,7 @@
     public void onClick(DialogInterface dialog, int which) {
         Intent intent = new Intent(android.provider.Settings.ACTION_TRUSTED_CREDENTIALS_USER);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        intent.putExtra(TrustedCredentialsSettings.ARG_SHOW_NEW_FOR_USER, UserHandle.myUserId());
+        intent.putExtra(TrustedCredentialsSettings.ARG_SHOW_NEW_FOR_USER, mUserId);
         startActivity(intent);
         finish();
     }
diff --git a/src/com/android/settings/TrustedCredentialsDialogBuilder.java b/src/com/android/settings/TrustedCredentialsDialogBuilder.java
index ed2ab09..2508d8c 100644
--- a/src/com/android/settings/TrustedCredentialsDialogBuilder.java
+++ b/src/com/android/settings/TrustedCredentialsDialogBuilder.java
@@ -43,6 +43,7 @@
     public interface DelegateInterface {
         List<X509Certificate> getX509CertsFromCertHolder(CertHolder certHolder);
         void removeOrInstallCert(CertHolder certHolder);
+        boolean startConfirmCredentialIfNotConfirmed(int userId);
     }
 
     private final DialogEventHandler mDialogEventHandler;
@@ -144,8 +145,10 @@
 
         private void onClickTrust() {
             CertHolder certHolder = getCurrentCertInfo();
-            mDpm.approveCaCert(certHolder.getAlias(), certHolder.getUserId(), true);
-            nextOrDismiss();
+            if (!mDelegate.startConfirmCredentialIfNotConfirmed(certHolder.getUserId())) {
+                mDpm.approveCaCert(certHolder.getAlias(), certHolder.getUserId(), true);
+                nextOrDismiss();
+            }
         }
 
         private void onClickRemove() {
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index e7ab406..c630ed6 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -17,6 +17,7 @@
 package com.android.settings;
 
 import android.annotation.UiThread;
+import android.app.Activity;
 import android.app.KeyguardManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
@@ -79,8 +80,10 @@
     private KeyguardManager mKeyguardManager;
     private int mTrustAllCaUserId;
 
-
+    private static final String SAVED_CONFIRMED_CREDENTIAL_USERS = "ConfirmedCredentialUsers";
+    private static final String SAVED_CONFIRMING_CREDENTIAL_USER = "ConfirmingCredentialUser";
     private static final String USER_ACTION = "com.android.settings.TRUSTED_CREDENTIALS_USER";
+    private static final int REQUEST_CONFIRM_CREDENTIALS = 1;
 
     @Override
     protected int getMetricsCategory() {
@@ -154,6 +157,8 @@
     private TabHost mTabHost;
     private ArrayList<GroupAdapter> mGroupAdapters = new ArrayList<>(2);
     private AliasOperation mAliasOperation;
+    private ArraySet<Integer> mConfirmedCredentialUsers;
+    private int mConfirmingCredentialUser;
     private Set<AdapterData.AliasLoader> mAliasLoaders = new ArraySet<AdapterData.AliasLoader>(2);
     private final SparseArray<KeyChainConnection>
             mKeyChainConnectionByProfileId = new SparseArray<KeyChainConnection>();
@@ -182,6 +187,17 @@
                 .getSystemService(Context.KEYGUARD_SERVICE);
         mTrustAllCaUserId = getActivity().getIntent().getIntExtra(ARG_SHOW_NEW_FOR_USER,
                 UserHandle.USER_NULL);
+        mConfirmedCredentialUsers = new ArraySet<>(2);
+        mConfirmingCredentialUser = UserHandle.USER_NULL;
+        if (savedInstanceState != null) {
+            mConfirmingCredentialUser = savedInstanceState.getInt(SAVED_CONFIRMING_CREDENTIAL_USER,
+                    UserHandle.USER_NULL);
+            ArrayList<Integer> users = savedInstanceState.getIntegerArrayList(
+                    SAVED_CONFIRMED_CREDENTIAL_USERS);
+            if (users != null) {
+                mConfirmedCredentialUsers.addAll(users);
+            }
+        }
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
@@ -190,6 +206,14 @@
         getActivity().registerReceiver(mWorkProfileChangedReceiver, filter);
     }
 
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putIntegerArrayList(SAVED_CONFIRMED_CREDENTIAL_USERS, new ArrayList<>(
+                mConfirmedCredentialUsers));
+        outState.putInt(SAVED_CONFIRMING_CREDENTIAL_USER, mConfirmingCredentialUser);
+    }
+
     @Override public View onCreateView(
             LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
         mTabHost = (TabHost) inflater.inflate(R.layout.trusted_credentials, parent, false);
@@ -219,6 +243,16 @@
         super.onDestroy();
     }
 
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CONFIRM_CREDENTIALS) {
+            if (resultCode == Activity.RESULT_OK) {
+                mConfirmedCredentialUsers.add(mConfirmingCredentialUser);
+            }
+            mConfirmingCredentialUser = UserHandle.USER_NULL;
+        }
+    }
+
     private void closeKeyChainConnections() {
         final int n = mKeyChainConnectionByProfileId.size();
         for (int i = 0; i < n; ++i) {
@@ -262,14 +296,18 @@
     }
 
     /**
-     * Start work challenge activity. TODO: Move and refactor this method as a util function.
+     * Start work challenge activity.
+     * @return true if screenlock exists
      */
-    private void startWorkChallenge(int userId) {
+    private boolean startConfirmCredential(int userId) {
         final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null,
                 userId);
-        newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        getActivity().startActivity(newIntent);
+        if (newIntent == null) {
+            return false;
+        }
+        mConfirmingCredentialUser = userId;
+        startActivityForResult(newIntent, REQUEST_CONFIRM_CREDENTIALS);
+        return true;
     }
 
     /**
@@ -303,7 +341,8 @@
         }
         @Override
         public CertHolder getChild(int groupPosition, int childPosition) {
-            return mData.mCertHoldersByUserId.get(getUserIdByGroup(groupPosition)).get(childPosition);
+            return mData.mCertHoldersByUserId.get(getUserIdByGroup(groupPosition)).get(
+                    childPosition);
         }
         @Override
         public long getGroupId(int groupPosition) {
@@ -386,18 +425,27 @@
         }
 
         public boolean checkGroupExpandableAndStartWarningActivity(int groupPosition) {
+            return checkGroupExpandableAndStartWarningActivity(groupPosition, true);
+        }
+
+        public boolean checkGroupExpandableAndStartWarningActivity(int groupPosition,
+                boolean startActivity) {
             final UserHandle groupUser = getGroup(groupPosition);
             final int groupUserId = groupUser.getIdentifier();
             if (mUserManager.isQuietModeEnabled(groupUser)) {
                 final Intent intent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
                         groupUserId);
-                getActivity().startActivity(intent);
+                if (startActivity) {
+                    getActivity().startActivity(intent);
+                }
                 return false;
             } else if (!mUserManager.isUserUnlocked(groupUser)) {
                 final LockPatternUtils lockPatternUtils = new LockPatternUtils(
                         getActivity());
                 if (lockPatternUtils.isSeparateProfileChallengeEnabled(groupUserId)) {
-                    startWorkChallenge(groupUserId);
+                    if (startActivity) {
+                        startConfirmCredential(groupUserId);
+                    }
                     return false;
                 }
             }
@@ -548,7 +596,8 @@
         }
 
         public void prepare() {
-            mIsListExpanded = checkGroupExpandableAndStartWarningActivity();
+            mIsListExpanded = mParent.checkGroupExpandableAndStartWarningActivity(mGroupPosition,
+                    false /* startActivity */);
             refreshViews();
         }
 
@@ -890,6 +939,15 @@
         new AliasOperation(certHolder).execute();
     }
 
+    @Override
+    public boolean startConfirmCredentialIfNotConfirmed(int userId) {
+        if (mConfirmedCredentialUsers.contains(userId)) {
+            // Credential has been confirmed. Don't start activity.
+            return false;
+        }
+        return startConfirmCredential(userId);
+    }
+
     private class AliasOperation extends AsyncTask<Void, Void, Boolean> {
         private final CertHolder mCertHolder;