From 923d2cc9d9915b18a8d29e9087add48dbe820eeb Mon Sep 17 00:00:00 2001 From: phweiss Date: Wed, 14 Dec 2016 21:37:48 +0100 Subject: DO NOT MERGE Show notification when network logging is enabled A notification is shown after network logging is enabled and after the next three reboots that are at least one day apart. Clicking it sends an intent to quick settings to shown its device monitoring dialog. Cherry-picked from master. Bug: 29748723 Bug: 33126577 (cherry-picked from commit a0cb251ca6a8ea8df17ff8089573bc50f2f1849f) Test: Manual, CTS-Verifier tests will be added later Change-Id: I2bf517bd27ab23ad3f66270602dbf062efab8cbb --- .../android/app/admin/DevicePolicyManager.java | 9 ++++ core/res/AndroidManifest.xml | 1 + core/res/res/drawable/ic_qs_network_logging.xml | 29 +++++++++++ core/res/res/values/strings.xml | 7 +++ core/res/res/values/symbols.xml | 3 ++ .../src/com/android/systemui/qs/QSFooter.java | 4 ++ .../src/com/android/systemui/qs/QSPanel.java | 4 ++ .../systemui/statusbar/phone/PhoneStatusBar.java | 5 ++ .../devicepolicy/DevicePolicyManagerService.java | 60 +++++++++++++++++++++- 9 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 core/res/res/drawable/ic_qs_network_logging.xml diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 2bcf9f22611d..1912437e40e0 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -949,6 +949,15 @@ public class DevicePolicyManager { public static final String ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = "android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD"; + /** + * Broadcast action: Tell the status bar to open the device monitoring dialog, e.g. when + * Network logging was enabled and the user tapped the notification. + *

This is a protected intent that can only be sent by the system.

+ * @hide + */ + public static final String ACTION_SHOW_DEVICE_MONITORING_DIALOG + = "android.app.action.SHOW_DEVICE_MONITORING_DIALOG"; + /** * Flag used by {@link #addCrossProfileIntentFilter} to allow activities in * the parent profile to access intents sent from the managed profile. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 36311dcf243f..632bcfe1f9fe 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -101,6 +101,7 @@ + diff --git a/core/res/res/drawable/ic_qs_network_logging.xml b/core/res/res/drawable/ic_qs_network_logging.xml new file mode 100644 index 000000000000..9e08264156e6 --- /dev/null +++ b/core/res/res/drawable/ic_qs_network_logging.xml @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 5e24442835a8..382f9023a703 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -390,6 +390,13 @@ This indicates that a work profile has been deleted. [CHAR LIMIT=NONE]--> Your work profile is no longer available on this device. + + Network traffic is being monitored + + Tap for more details + Your device will be erased diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index d4ba583932c6..d95f6e9e1a68 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1109,6 +1109,8 @@ + + @@ -1221,6 +1223,7 @@ + diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java index 756513b61c45..cdd936225e82 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java @@ -108,6 +108,10 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene } private void handleClick() { + showDeviceMonitoringDialog(); + } + + public void showDeviceMonitoringDialog() { mHost.collapsePanels(); // TODO: Delay dialog creation until after panels are collapsed. createDialog(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index fef89305e553..bdb488feffa5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -511,6 +511,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { return mFooter; } + public void showDeviceMonitoringDialog() { + mFooter.showDeviceMonitoringDialog(); + } + private class H extends Handler { private static final int SHOW_DETAIL = 1; private static final int SET_TILE_VISIBILITY = 2; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 556aac1603f8..4f5048fc3da1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -36,6 +36,7 @@ import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.ActivityOptions; +import android.app.admin.DevicePolicyManager; import android.app.IActivityManager; import android.app.Notification; import android.app.PendingIntent; @@ -994,6 +995,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); IntentFilter demoFilter = new IntentFilter(); @@ -3572,6 +3574,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, else if (Intent.ACTION_SCREEN_ON.equals(action)) { notifyNavigationBarScreenOn(true); } + else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) { + mQSPanel.showDeviceMonitoringDialog(); + } } }; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 8189a7ec3b08..46cc3a900129 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -17,6 +17,7 @@ package com.android.server.devicepolicy; import static android.Manifest.permission.MANAGE_CA_CERTIFICATES; +import static android.app.admin.DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; @@ -218,6 +219,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final int MONITORING_CERT_NOTIFICATION_ID = R.plurals.ssl_ca_cert_warning; private static final int PROFILE_WIPED_NOTIFICATION_ID = 1001; + private static final int NETWORK_LOGGING_NOTIFICATION_ID = 1002; private static final String ATTR_PERMISSION_PROVIDER = "permission-provider"; private static final String ATTR_SETUP_COMPLETE = "setup-complete"; @@ -605,6 +607,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_PARENT_ADMIN = "parent-admin"; private static final String TAG_ORGANIZATION_COLOR = "organization-color"; private static final String TAG_ORGANIZATION_NAME = "organization-name"; + private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification"; + private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications"; final DeviceAdminInfo info; @@ -663,6 +667,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean forceEphemeralUsers = false; // Can only be set by a device owner. boolean isNetworkLoggingEnabled = false; // Can only be set by a device owner. + // one notification after enabling + 3 more after reboots + static final int DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN = 4; + int numNetworkLoggingNotifications = 0; + long lastNetworkLoggingNotificationTimeMs = 0; // Time in milliseconds since epoch + ActiveAdmin parentAdmin; final boolean isParent; @@ -873,6 +882,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (isNetworkLoggingEnabled) { out.startTag(null, TAG_IS_NETWORK_LOGGING_ENABLED); out.attribute(null, ATTR_VALUE, Boolean.toString(isNetworkLoggingEnabled)); + out.attribute(null, ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS, + Integer.toString(numNetworkLoggingNotifications)); + out.attribute(null, ATTR_LAST_NETWORK_LOGGING_NOTIFICATION, + Long.toString(lastNetworkLoggingNotificationTimeMs)); out.endTag(null, TAG_IS_NETWORK_LOGGING_ENABLED); } if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) { @@ -1064,6 +1077,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (TAG_IS_NETWORK_LOGGING_ENABLED.equals(tag)) { isNetworkLoggingEnabled = Boolean.parseBoolean( parser.getAttributeValue(null, ATTR_VALUE)); + lastNetworkLoggingNotificationTimeMs = Long.parseLong( + parser.getAttributeValue(null, ATTR_LAST_NETWORK_LOGGING_NOTIFICATION)); + numNetworkLoggingNotifications = Integer.parseInt( + parser.getAttributeValue(null, ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS)); } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) { disabledKeyguardFeatures = Integer.parseInt( parser.getAttributeValue(null, ATTR_VALUE)); @@ -9464,7 +9481,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // already in the requested state return; } - getDeviceOwnerAdminLocked().isNetworkLoggingEnabled = enabled; + ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); + deviceOwner.isNetworkLoggingEnabled = enabled; + if (!enabled) { + deviceOwner.numNetworkLoggingNotifications = 0; + deviceOwner.lastNetworkLoggingNotificationTimeMs = 0; + } saveSettingsLocked(mInjector.userHandleGetCallingUserId()); setNetworkLoggingActiveInternal(enabled); @@ -9480,6 +9502,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Slog.wtf(LOG_TAG, "Network logging could not be started due to the logging" + " service not being available yet."); } + sendNetworkLoggingNotificationLocked(); } else { if (mNetworkLogger != null && !mNetworkLogger.stopNetworkLogging()) { mNetworkLogger = null; @@ -9532,4 +9555,39 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ? mNetworkLogger.retrieveLogs(batchToken) : null; } + + private void sendNetworkLoggingNotificationLocked() { + final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); + if (deviceOwner == null || !deviceOwner.isNetworkLoggingEnabled) { + return; + } + if (deviceOwner.numNetworkLoggingNotifications >= + ActiveAdmin.DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN) { + return; + } + final long now = System.currentTimeMillis(); + if (now - deviceOwner.lastNetworkLoggingNotificationTimeMs < MS_PER_DAY) { + return; + } + deviceOwner.numNetworkLoggingNotifications++; + if (deviceOwner.numNetworkLoggingNotifications + >= ActiveAdmin.DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN) { + deviceOwner.lastNetworkLoggingNotificationTimeMs = 0; + } else { + deviceOwner.lastNetworkLoggingNotificationTimeMs = now; + } + final Intent intent = new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG); + intent.setPackage("com.android.systemui"); + final PendingIntent pendingIntent = PendingIntent.getBroadcastAsUser(mContext, 0, intent, 0, + UserHandle.CURRENT); + Notification notification = new Notification.Builder(mContext) + .setSmallIcon(R.drawable.ic_qs_network_logging) + .setContentTitle(mContext.getString(R.string.network_logging_notification_title)) + .setContentText(mContext.getString(R.string.network_logging_notification_text)) + .setShowWhen(true) + .setContentIntent(pendingIntent) + .build(); + mInjector.getNotificationManager().notify(NETWORK_LOGGING_NOTIFICATION_ID, notification); + saveSettingsLocked(mOwners.getDeviceOwnerUserId()); + } } -- cgit v1.2.3-59-g8ed1b