summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java2
-rw-r--r--core/java/android/provider/Settings.java32
-rw-r--r--core/res/res/drawable-hdpi/stat_sys_certificate_info.pngbin0 -> 1416 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_certificate_info.pngbin0 -> 930 bytes
-rw-r--r--core/res/res/drawable-xhdpi/stat_sys_certificate_info.pngbin0 -> 1946 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/stat_sys_certificate_info.pngbin0 -> 4141 bytes
-rw-r--r--core/res/res/values/strings.xml12
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--packages/SystemUI/res/values/strings.xml13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java43
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java81
11 files changed, 132 insertions, 55 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e0b1c00..ab82531 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1372,7 +1372,7 @@ public class DevicePolicyManager {
*
* @hide
*/
- public boolean hasAnyCaCertsInstalled() {
+ public static boolean hasAnyCaCertsInstalled() {
TrustedCertificateStore certStore = new TrustedCertificateStore();
Set<String> aliases = certStore.userAliases();
return aliases != null && !aliases.isEmpty();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index af905b4..c1c826c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -160,6 +160,38 @@ public final class Settings {
"android.settings.SECURITY_SETTINGS";
/**
+ * Activity Action: Show trusted credentials settings, opening to the user tab,
+ * to allow management of installed credentials.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_TRUSTED_CREDENTIALS_USER =
+ "com.android.settings.TRUSTED_CREDENTIALS_USER";
+
+ /**
+ * Activity Action: Show dialog explaining that an installed CA cert may enable
+ * monitoring of encrypted network traffic.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MONITORING_CERT_INFO =
+ "com.android.settings.MONITORING_CERT_INFO";
+
+ /**
* Activity Action: Show settings to allow configuration of privacy options.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/res/res/drawable-hdpi/stat_sys_certificate_info.png b/core/res/res/drawable-hdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..3be426c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_certificate_info.png b/core/res/res/drawable-mdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..e15cf38
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_certificate_info.png b/core/res/res/drawable-xhdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..3c93ea0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png b/core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..d96ef64
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 35d0fbd..a03378e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -273,6 +273,18 @@
<!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
<string name="low_memory" product="default">Phone storage is full. Delete some files to free space.</string>
+ <!-- SSL CA cert notification --> <skip />
+ <!-- Shows up when there is a user SSL CA Cert installed on the
+ device. Indicates to the user that SSL traffic can be intercepted. [CHAR LIMIT=NONE] -->
+ <string name="ssl_ca_cert_warning">Network may be monitored</string>
+ <!-- Content text for a notification. The Title of the notification is "ssl_ca_cert_warning",
+ i.e. "Network may be monitored". This says that an unknown party is doing the monitoring.
+ [CHAR LIMIT=100]-->
+ <string name="ssl_ca_cert_noti_by_unknown">By an unknown third party</string>
+ <!-- Content text for a notification. The Title of the notification is "ssl_ca_cert_warning",
+ i.e. "Network may be monitored". This indicates who is doing the monitoring.
+ [CHAR LIMIT=100]-->
+ <string name="ssl_ca_cert_noti_managed">By <xliff:g id="managing_domain">%s</xliff:g></string>
<!-- Display name for any time a piece of data refers to the owner of the phone. For example, this could be used in place of the phone's phone number. -->
<string name="me">Me</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 44891a8..4148f20 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -886,6 +886,9 @@
<java-symbol type="string" name="write_fail_reason_cannot_write" />
<java-symbol type="string" name="transient_navigation_confirmation" />
<java-symbol type="string" name="transient_navigation_confirmation_long" />
+ <java-symbol type="string" name="ssl_ca_cert_noti_by_unknown" />
+ <java-symbol type="string" name="ssl_ca_cert_noti_managed" />
+ <java-symbol type="string" name="ssl_ca_cert_warning" />
<java-symbol type="plurals" name="abbrev_in_num_days" />
<java-symbol type="plurals" name="abbrev_in_num_hours" />
@@ -1008,6 +1011,7 @@
<java-symbol type="drawable" name="stat_notify_rssi_in_range" />
<java-symbol type="drawable" name="stat_sys_gps_on" />
<java-symbol type="drawable" name="stat_sys_tether_wifi" />
+ <java-symbol type="drawable" name="stat_sys_certificate_info" />
<java-symbol type="drawable" name="status_bar_background" />
<java-symbol type="drawable" name="sym_keyboard_shift" />
<java-symbol type="drawable" name="sym_keyboard_shift_locked" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3ffa6f4..bbfe383 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -500,16 +500,5 @@
<!-- Shows up when there is a user SSL CA Cert installed on the
device. Indicates to the user that SSL traffic can be intercepted. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_warning">Network may be monitored</string>
- <!-- Button to close the SSL CA cert warning dialog box. [CHAR LIMIT=NONE] -->
- <string name="done_button">Done</string>
- <!-- Title of Dialog warning users of SSL monitoring. [CHAR LIMIT=NONE] -->
- <string name="ssl_ca_cert_dialog_title">Network Monitoring</string>
- <!-- Text of message to show to users whose administrator has installed a SSL CA Cert.
- [CHAR LIMIT=NONE] -->
- <string name="ssl_ca_cert_info_message">This device is managed by: <xliff:g id="managing_domain">%s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity, including emails, apps, and secure websites.\n\nFor more information,contact your administrator.</string>
- <!-- Text of warning to show to users that have a SSL CA Cert installed. [CHAR LIMIT=NONE] -->
- <string name="ssl_ca_cert_warning_message">A third party is capable of monitoring your network\nactivity, including emails, apps, and secure websites.\n\nA trusted credential installed on your device is making this possible.</string>
- <!-- Label on button that will take the user to the Trusted Credentials settings page.
- [CHAR LIMIT=NONE]-->
- <string name="ssl_ca_cert_settings_button">Check trusted credentials</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 68ee2b5..ceed30e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -194,7 +194,7 @@ class QuickSettings {
mQueryCertTask = new AsyncTask<Void, Void, Pair<Boolean, Boolean>>() {
@Override
protected Pair<Boolean, Boolean> doInBackground(Void... params) {
- boolean hasCert = mDevicePolicyManager.hasAnyCaCertsInstalled();
+ boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
return Pair.create(hasCert, isManaged);
@@ -764,7 +764,7 @@ class QuickSettings {
@Override
public void onClick(View v) {
collapsePanels();
- showSslCaCertWarningDialog();
+ startSettingsActivity(Settings.ACTION_MONITORING_CERT_INFO);
}
});
@@ -832,45 +832,6 @@ class QuickSettings {
dialog.show();
}
- private void showSslCaCertWarningDialog() {
- final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
- builder.setTitle(R.string.ssl_ca_cert_dialog_title);
- builder.setCancelable(true);
- final boolean hasDeviceOwner = mDevicePolicyManager.getDeviceOwner() != null;
- int buttonLabel;
- if (hasDeviceOwner) {
- // Institutional case. Show informational message.
- String message = mContext.getResources().getString(R.string.ssl_ca_cert_info_message,
- mDevicePolicyManager.getDeviceOwnerName());
- builder.setMessage(message);
- buttonLabel = R.string.done_button;
- } else {
- // Consumer case. Show scary warning.
- builder.setMessage(R.string.ssl_ca_cert_warning_message);
- buttonLabel = R.string.ssl_ca_cert_settings_button;
- }
-
- builder.setPositiveButton(buttonLabel, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // do something.
- if (hasDeviceOwner) {
- // Close
- } else {
- startSettingsActivity("com.android.settings.TRUSTED_CREDENTIALS_USER");
- }
- }
- });
-
- final Dialog dialog = builder.create();
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- try {
- WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
- } catch (RemoteException e) {
- }
- dialog.show();
- }
-
private void updateWifiDisplayStatus() {
mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus();
applyWifiDisplayStatus();
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 7e83396..2bca759 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -18,6 +18,7 @@ package com.android.server;
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
+import com.android.internal.R;
import com.android.internal.os.storage.ExternalStorageFormatter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -33,6 +34,9 @@ import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.AppGlobals;
+import android.app.INotificationManager;
+import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DeviceAdminReceiver;
@@ -51,6 +55,7 @@ import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
@@ -123,6 +128,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION
= "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
+ private static final int MONITORING_CERT_NOTIFICATION_ID = R.string.ssl_ca_cert_warning;
+
private static final boolean DBG = false;
final Context mContext;
@@ -130,6 +137,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
IPowerManager mIPowerManager;
IWindowManager mIWindowManager;
+ NotificationManager mNotificationManager;
private DeviceOwner mDeviceOwner;
@@ -177,7 +185,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
handlePasswordExpirationNotification(getUserData(userHandle));
}
});
- } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ }
+ if (Intent.ACTION_BOOT_COMPLETED.equals(action)
+ || KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
+ manageMonitoringCertificateNotification(intent);
+ }
+ if (Intent.ACTION_USER_REMOVED.equals(action)) {
removeUserData(userHandle);
} else if (Intent.ACTION_USER_STARTED.equals(action)
|| Intent.ACTION_PACKAGE_CHANGED.equals(action)
@@ -526,6 +539,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
filter.addAction(Intent.ACTION_USER_REMOVED);
filter.addAction(Intent.ACTION_USER_STARTED);
+ filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
@@ -635,6 +649,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return mIWindowManager;
}
+ private NotificationManager getNotificationManager() {
+ if (mNotificationManager == null) {
+ mNotificationManager =
+ (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ }
+ return mNotificationManager;
+ }
+
ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who);
if (admin != null
@@ -1053,6 +1075,63 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ private void manageMonitoringCertificateNotification(Intent intent) {
+ final NotificationManager notificationManager = getNotificationManager();
+
+ final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
+ if (! hasCert) {
+ if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ for (UserInfo user : um.getUsers()) {
+ notificationManager.cancelAsUser(
+ null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
+ }
+ }
+ 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;
+ }
+
+ 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)
+ .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)) {
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ for (UserInfo user : um.getUsers()) {
+ notificationManager.notifyAsUser(
+ null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
+ }
+ } else {
+ notificationManager.notifyAsUser(
+ null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
+ }
+ }
+
/**
* @param adminReceiver The admin to add
* @param refreshing true = update an active admin, no error