Merge "Revert "Publish DevicePolicyManager CA certificate APIs""
diff --git a/api/current.txt b/api/current.txt
index cf19d54..af989e8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5243,10 +5243,7 @@
     method public int getPasswordQuality(android.content.ComponentName);
     method public boolean getStorageEncryption(android.content.ComponentName);
     method public int getStorageEncryptionStatus();
-    method public boolean hasAnyCaCertsInstalled();
-    method public boolean hasCaCertInstalled(byte[]);
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
-    method public boolean installCaCert(android.content.ComponentName, byte[]);
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
     method public boolean isApplicationBlocked(android.content.ComponentName, java.lang.String);
@@ -5284,7 +5281,6 @@
     method public void setRestrictionsProvider(android.content.ComponentName, android.content.ComponentName);
     method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public int setStorageEncryption(android.content.ComponentName, boolean);
-    method public void uninstallCaCert(android.content.ComponentName, byte[]);
     method public void wipeData(int);
     field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.ACTION_PROVISION_MANAGED_PROFILE";
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 99f68d0..e80c761 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1506,11 +1506,12 @@
      *
      * @return false if the certBuffer cannot be parsed or installation is
      *         interrupted, otherwise true
+     * @hide
      */
-    public boolean installCaCert(ComponentName who, byte[] certBuffer) {
+    public boolean installCaCert(byte[] certBuffer) {
         if (mService != null) {
             try {
-                return mService.installCaCert(who, certBuffer);
+                return mService.installCaCert(certBuffer);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1520,14 +1521,13 @@
 
     /**
      * Uninstalls the given certificate from the list of User CAs, if present.
+     *
+     * @hide
      */
-    public void uninstallCaCert(ComponentName who, byte[] certBuffer) {
+    public void uninstallCaCert(byte[] certBuffer) {
         if (mService != null) {
             try {
-                final String alias = getCaCertAlias(certBuffer);
-                mService.uninstallCaCert(who, alias);
-            } catch (CertificateException e) {
-                Log.w(TAG, "Unable to parse certificate", e);
+                mService.uninstallCaCert(certBuffer);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1536,8 +1536,10 @@
 
     /**
      * Returns whether there are any user-installed CA certificates.
+     *
+     * @hide
      */
-    public boolean hasAnyCaCertsInstalled() {
+    public static boolean hasAnyCaCertsInstalled() {
         TrustedCertificateStore certStore = new TrustedCertificateStore();
         Set<String> aliases = certStore.userAliases();
         return aliases != null && !aliases.isEmpty();
@@ -1545,10 +1547,18 @@
 
     /**
      * Returns whether this certificate has been installed as a User CA.
+     *
+     * @hide
      */
     public boolean hasCaCertInstalled(byte[] certBuffer) {
+        TrustedCertificateStore certStore = new TrustedCertificateStore();
+        String alias;
+        byte[] pemCert;
         try {
-            return getCaCertAlias(certBuffer) != null;
+            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(
+                            new ByteArrayInputStream(certBuffer));
+            return certStore.getCertificateAlias(cert) != null;
         } catch (CertificateException ce) {
             Log.w(TAG, "Could not parse certificate", ce);
         }
@@ -1556,17 +1566,6 @@
     }
 
     /**
-     * Returns the alias of a given CA certificate in the certificate store, or null if it
-     * doesn't exist.
-     */
-    private static String getCaCertAlias(byte[] certBuffer) throws CertificateException {
-        final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-        final X509Certificate cert = (X509Certificate) certFactory.generateCertificate(
-                              new ByteArrayInputStream(certBuffer));
-        return new TrustedCertificateStore().getCertificateAlias(cert);
-    }
-
-    /**
      * Called by an application that is administering the device to disable all cameras
      * on the device.  After setting this, no applications will be able to access any cameras
      * on the device.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index e935da7..a1caa21 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -115,8 +115,8 @@
     String getProfileOwnerName(int userHandle);
     void setProfileEnabled(in ComponentName who);
 
-    boolean installCaCert(in ComponentName admin, in byte[] certBuffer);
-    void uninstallCaCert(in ComponentName admin, in String alias);
+    boolean installCaCert(in byte[] certBuffer);
+    void uninstallCaCert(in byte[] certBuffer);
 
     void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
     void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 0da2b99..9d6d76e 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -23,9 +23,7 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Process;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.security.InvalidKeyException;
@@ -439,14 +437,6 @@
      * Caller should call unbindService on the result when finished.
      */
     public static KeyChainConnection bind(Context context) throws InterruptedException {
-        return bindAsUser(context, Process.myUserHandle());
-    }
-
-    /**
-     * @hide
-     */
-    public static KeyChainConnection bindAsUser(Context context, UserHandle user)
-            throws InterruptedException {
         if (context == null) {
             throw new NullPointerException("context == null");
         }
@@ -469,10 +459,9 @@
         Intent intent = new Intent(IKeyChainService.class.getName());
         ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
         intent.setComponent(comp);
-        boolean isBound = context.bindServiceAsUser(intent,
-                                                    keyChainServiceConnection,
-                                                    Context.BIND_AUTO_CREATE,
-                                                    user);
+        boolean isBound = context.bindService(intent,
+                                              keyChainServiceConnection,
+                                              Context.BIND_AUTO_CREATE);
         if (!isBound) {
             throw new AssertionError("could not bind to KeyChainService");
         }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 24a998d..4574caf 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1324,7 +1324,7 @@
     private void manageMonitoringCertificateNotification(Intent intent) {
         final NotificationManager notificationManager = getNotificationManager();
 
-        final boolean hasCert = !(new TrustedCertificateStore().userAliases().isEmpty());
+        final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
         if (! hasCert) {
             if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
                 for (UserInfo user : mUserManager.getUsers()) {
@@ -2384,19 +2384,13 @@
         return !"".equals(state);
     }
 
-    public boolean installCaCert(ComponentName who, byte[] certBuffer) throws RemoteException {
-        if (who == null) {
-            mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
-        } else {
-            synchronized (this) {
-                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            }
-        }
-
+    public boolean installCaCert(byte[] certBuffer) throws RemoteException {
+        mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
+        KeyChainConnection keyChainConnection = null;
         byte[] pemCert;
         try {
             X509Certificate cert = parseCert(certBuffer);
-            pemCert = Credentials.convertToPem(cert);
+            pemCert =  Credentials.convertToPem(cert);
         } catch (CertificateException ce) {
             Log.e(LOG_TAG, "Problem converting cert", ce);
             return false;
@@ -2404,24 +2398,20 @@
             Log.e(LOG_TAG, "Problem reading cert", ioe);
             return false;
         }
-
-        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
-        final long id = Binder.clearCallingIdentity();
         try {
-            final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
+            keyChainConnection = KeyChain.bind(mContext);
             try {
                 keyChainConnection.getService().installCaCertificate(pemCert);
                 return true;
-            } catch (RemoteException e) {
-                Log.e(LOG_TAG, "installCaCertsToKeyChain(): ", e);
             } finally {
-                keyChainConnection.close();
+                if (keyChainConnection != null) {
+                    keyChainConnection.close();
+                    keyChainConnection = null;
+                }
             }
         } catch (InterruptedException e1) {
             Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1);
             Thread.currentThread().interrupt();
-        } finally {
-            Binder.restoreCallingIdentity(id);
         }
         return false;
     }
@@ -2433,31 +2423,34 @@
                 certBuffer));
     }
 
-    public void uninstallCaCert(ComponentName who, String alias) {
-        if (who == null) {
-            mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
-        } else {
-            synchronized (this) {
-                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            }
-        }
-
-        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
-        final long id = Binder.clearCallingIdentity();
+    public void uninstallCaCert(final byte[] certBuffer) {
+        mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
+        TrustedCertificateStore certStore = new TrustedCertificateStore();
+        String alias = null;
         try {
-            final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
+            X509Certificate cert = parseCert(certBuffer);
+            alias = certStore.getCertificateAlias(cert);
+        } catch (CertificateException ce) {
+            Log.e(LOG_TAG, "Problem creating X509Certificate", ce);
+            return;
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "Problem reading certificate", ioe);
+            return;
+        }
+        try {
+            KeyChainConnection keyChainConnection = KeyChain.bind(mContext);
+            IKeyChainService service = keyChainConnection.getService();
             try {
-                keyChainConnection.getService().deleteCaCertificate(alias);
+                service.deleteCaCertificate(alias);
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, "from CaCertUninstaller: ", e);
             } finally {
                 keyChainConnection.close();
+                keyChainConnection = null;
             }
         } catch (InterruptedException ie) {
             Log.w(LOG_TAG, "CaCertUninstaller: ", ie);
             Thread.currentThread().interrupt();
-        } finally {
-            Binder.restoreCallingIdentity(id);
         }
     }