Merge "Handle the case when KeyChain binding fails"
This commit is contained in:
@@ -763,28 +763,33 @@ public final class KeyChain {
|
||||
* @see KeyChain#bind
|
||||
*/
|
||||
public static class KeyChainConnection implements Closeable {
|
||||
private final Context context;
|
||||
private final ServiceConnection serviceConnection;
|
||||
private final IKeyChainService service;
|
||||
private final Context mContext;
|
||||
private final ServiceConnection mServiceConnection;
|
||||
private final IKeyChainService mService;
|
||||
protected KeyChainConnection(Context context,
|
||||
ServiceConnection serviceConnection,
|
||||
IKeyChainService service) {
|
||||
this.context = context;
|
||||
this.serviceConnection = serviceConnection;
|
||||
this.service = service;
|
||||
this.mContext = context;
|
||||
this.mServiceConnection = serviceConnection;
|
||||
this.mService = service;
|
||||
}
|
||||
@Override public void close() {
|
||||
context.unbindService(serviceConnection);
|
||||
mContext.unbindService(mServiceConnection);
|
||||
}
|
||||
|
||||
/** returns the service binder. */
|
||||
public IKeyChainService getService() {
|
||||
return service;
|
||||
return mService;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide for reuse by CertInstaller and Settings.
|
||||
*
|
||||
* Bind to KeyChainService in the current user.
|
||||
* Caller should call unbindService on the result when finished.
|
||||
*
|
||||
*@throws InterruptedException if interrupted during binding.
|
||||
*@throws AssertionError if unable to bind to KeyChainService.
|
||||
* @hide for reuse by CertInstaller and Settings.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static KeyChainConnection bind(@NonNull Context context) throws InterruptedException {
|
||||
@@ -792,6 +797,11 @@ public final class KeyChain {
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind to KeyChainService in the target user.
|
||||
* Caller should call unbindService on the result when finished.
|
||||
*
|
||||
* @throws InterruptedException if interrupted during binding.
|
||||
* @throws AssertionError if unable to bind to KeyChainService.
|
||||
* @hide
|
||||
*/
|
||||
@WorkerThread
|
||||
@@ -814,6 +824,16 @@ public final class KeyChain {
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override public void onBindingDied(ComponentName name) {
|
||||
if (!mConnectedAtLeastOnce) {
|
||||
mConnectedAtLeastOnce = true;
|
||||
try {
|
||||
q.put(null);
|
||||
} catch (InterruptedException e) {
|
||||
// will never happen, since the queue starts with one available slot
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override public void onServiceDisconnected(ComponentName name) {}
|
||||
};
|
||||
Intent intent = new Intent(IKeyChainService.class.getName());
|
||||
@@ -823,7 +843,13 @@ public final class KeyChain {
|
||||
intent, keyChainServiceConnection, Context.BIND_AUTO_CREATE, user)) {
|
||||
throw new AssertionError("could not bind to KeyChainService");
|
||||
}
|
||||
return new KeyChainConnection(context, keyChainServiceConnection, q.take());
|
||||
IKeyChainService service = q.take();
|
||||
if (service != null) {
|
||||
return new KeyChainConnection(context, keyChainServiceConnection, service);
|
||||
} else {
|
||||
context.unbindService(keyChainServiceConnection);
|
||||
throw new AssertionError("KeyChainService died while binding");
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureNotOnMainThread(@NonNull Context context) {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.server.devicepolicy;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -26,12 +25,9 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.provider.Settings;
|
||||
import android.security.Credentials;
|
||||
@@ -39,9 +35,9 @@ import android.security.KeyChain;
|
||||
import android.security.KeyChain.KeyChainConnection;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||
import com.android.internal.notification.SystemNotificationChannels;
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -49,7 +45,6 @@ import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class CertificateMonitor {
|
||||
protected static final String LOG_TAG = DevicePolicyManagerService.LOG_TAG;
|
||||
@@ -111,13 +106,13 @@ public class CertificateMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getInstalledCaCertificates(UserHandle userHandle)
|
||||
private List<String> getInstalledCaCertificates(UserHandle userHandle)
|
||||
throws RemoteException, RuntimeException {
|
||||
try (KeyChainConnection conn = mInjector.keyChainBindAsUser(userHandle)) {
|
||||
return conn.getService().getUserCaAliases().getList();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return null;
|
||||
throw new RuntimeException(e);
|
||||
} catch (AssertionError e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user