Merge "DevicePolicy: One cert tracker warning per profile" into lmp-dev
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d1aba3c..f8f20dc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -53,6 +53,7 @@
import android.net.ConnectivityManager;
import android.net.ProxyInfo;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -288,7 +289,7 @@
}
if (Intent.ACTION_BOOT_COMPLETED.equals(action)
|| KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
- manageMonitoringCertificateNotification(intent);
+ new MonitoringCertNotificationTask().execute(intent);
}
if (Intent.ACTION_USER_REMOVED.equals(action)) {
removeUserData(userHandle);
@@ -1610,60 +1611,91 @@
}
}
- private void manageMonitoringCertificateNotification(Intent intent) {
- final NotificationManager notificationManager = getNotificationManager();
+ private class MonitoringCertNotificationTask extends AsyncTask<Intent, Void, Void> {
+ @Override
+ protected Void doInBackground(Intent... params) {
+ int userHandle = params[0].getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_ALL);
- final boolean hasCert = !(new TrustedCertificateStore().userAliases().isEmpty());
- if (! hasCert) {
- if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
- for (UserInfo user : mUserManager.getUsers()) {
- notificationManager.cancelAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
+ if (userHandle == UserHandle.USER_ALL) {
+ for (UserInfo userInfo : mUserManager.getUsers()) {
+ manageNotification(userInfo.getUserHandle());
}
+ } else {
+ manageNotification(new UserHandle(userHandle));
}
- return;
- }
- final boolean isManaged = getDeviceOwner() != null;
- int smallIconId;
- String contentText;
- if (isManaged) {
- contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed,
- getDeviceOwnerName());
- smallIconId = R.drawable.stat_sys_certificate_info;
- } else {
- contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
- smallIconId = android.R.drawable.stat_sys_warning;
+ return null;
}
- Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
- dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- dialogIntent.setPackage("com.android.settings");
- // Notification will be sent individually to all users. The activity should start as
- // whichever user is current when it starts.
- PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent,
- PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
-
- Notification noti = new Notification.Builder(mContext)
- .setSmallIcon(smallIconId)
- .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
- .setContentText(contentText)
- .setContentIntent(notifyIntent)
- .setPriority(Notification.PRIORITY_HIGH)
- .setShowWhen(false)
- .setColor(mContext.getResources().getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .build();
-
- // If this is a boot intent, this will fire for each user. But if this is a storage changed
- // intent, it will fire once, so we need to notify all users.
- if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
- for (UserInfo user : mUserManager.getUsers()) {
- notificationManager.notifyAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
+ private void manageNotification(UserHandle userHandle) {
+ if (!mUserManager.isUserRunning(userHandle)) {
+ return;
}
- } else {
- notificationManager.notifyAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
+
+ boolean hasCert = false;
+ final long id = Binder.clearCallingIdentity();
+ try {
+ KeyChainConnection kcs = KeyChain.bindAsUser(mContext, userHandle);
+ try {
+ if (!kcs.getService().getUserCaAliases().getList().isEmpty()) {
+ hasCert = true;
+ }
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Could not connect to KeyChain service", e);
+ } finally {
+ kcs.close();
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ } catch (RuntimeException e) {
+ Log.e(LOG_TAG, "Could not connect to KeyChain service", e);
+ } finally {
+ Binder.restoreCallingIdentity(id);
+ }
+ if (!hasCert) {
+ getNotificationManager().cancelAsUser(
+ null, MONITORING_CERT_NOTIFICATION_ID, userHandle);
+ return;
+ }
+
+ int smallIconId;
+ String contentText;
+ final String ownerName = getDeviceOwnerName();
+ if (ownerName != null) {
+ contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed, ownerName);
+ smallIconId = R.drawable.stat_sys_certificate_info;
+ } else {
+ contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
+ smallIconId = android.R.drawable.stat_sys_warning;
+ }
+
+ Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
+ dialogIntent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ dialogIntent.setPackage("com.android.settings");
+ PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0,
+ dialogIntent, PendingIntent.FLAG_UPDATE_CURRENT, null, userHandle);
+
+ final Context userContext;
+ try {
+ userContext = mContext.createPackageContextAsUser("android", 0, userHandle);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG, "Create context as " + userHandle + " failed", e);
+ return;
+ }
+ final Notification noti = new Notification.Builder(userContext)
+ .setSmallIcon(smallIconId)
+ .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
+ .setContentText(contentText)
+ .setContentIntent(notifyIntent)
+ .setOngoing(true)
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setShowWhen(false)
+ .setColor(mContext.getResources().getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .build();
+
+ getNotificationManager().notifyAsUser(
+ null, MONITORING_CERT_NOTIFICATION_ID, noti, userHandle);
}
}