From c94b63730584dd4dd2e1c19266d6bbe1bbf56174 Mon Sep 17 00:00:00 2001 From: phweiss Date: Thu, 24 Nov 2016 16:20:57 +0100 Subject: DO NOT MERGE Add network logging icon to Quicksettings when enabled Add the network logging icon in Quick Settings' footer if network logging is enabled, possible next to the VPN icon. Quicksettings has to be able to tell that network logging is enabled, so this CL changes DPM.isNetworkLoggingEnabled() to be callable from the device owner or from any app with the MANAGE_USERS permission. The icon is only a placeholder until the official icon is finished. CTS Verifier tests will be added when all Network logging UX changes are done. Cherry-picked from master, and then modified to work in N: I had to remove the QSFooterTest change because the testing infrastructure is not there in N. Also, I had to add DPMS.enforceDeviceOwnerOrManageUsers() to which did not exist in N before. BUG: 33126618 BUG: 29748723 Test: Manual, CTS-Verifier tests will be added in a follow-up (cherry picked from commit a4e169ed68ee57aa249e5e79fcd6bff5df46199e) Change-Id: Ib35d323605ab11f883a4b6199d1db79b9e53c49b --- .../android/app/admin/DevicePolicyManager.java | 8 +++--- .../res/drawable/ic_qs_network_logging.xml | 29 ++++++++++++++++++++++ .../SystemUI/res/layout/quick_settings_footer.xml | 14 ++++++++++- .../src/com/android/systemui/qs/QSFooter.java | 23 +++++++++++++++-- .../statusbar/policy/SecurityController.java | 1 + .../statusbar/policy/SecurityControllerImpl.java | 5 ++++ .../devicepolicy/DevicePolicyManagerService.java | 13 ++++++++-- 7 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 packages/SystemUI/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 c2197b55ef97..2bcf9f22611d 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -6637,13 +6637,15 @@ public class DevicePolicyManager { /** * Return whether network logging is enabled by a device owner. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Can only + * be {@code null} if the caller has MANAGE_USERS permission. * @return {@code true} if network logging is enabled by device owner, {@code false} otherwise. - * @throws {@link SecurityException} if {@code admin} is not a device owner. + * @throws {@link SecurityException} if {@code admin} is not a device owner and caller has + * no MANAGE_USERS permission * * @hide */ - public boolean isNetworkLoggingEnabled(@NonNull ComponentName admin) { + public boolean isNetworkLoggingEnabled(@Nullable ComponentName admin) { throwIfParentInstance("isNetworkLoggingEnabled"); try { return mService.isNetworkLoggingEnabled(admin); diff --git a/packages/SystemUI/res/drawable/ic_qs_network_logging.xml b/packages/SystemUI/res/drawable/ic_qs_network_logging.xml new file mode 100644 index 000000000000..8200fcb2ca10 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_network_logging.xml @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/packages/SystemUI/res/layout/quick_settings_footer.xml b/packages/SystemUI/res/layout/quick_settings_footer.xml index 53baf74ffee9..8667a5a8f5cd 100644 --- a/packages/SystemUI/res/layout/quick_settings_footer.xml +++ b/packages/SystemUI/res/layout/quick_settings_footer.xml @@ -39,4 +39,16 @@ android:src="@drawable/ic_qs_vpn" android:visibility="invisible" /> - \ No newline at end of file + + + + diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java index ccb28e95802e..756513b61c45 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java @@ -46,6 +46,7 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene private final View mRootView; private final TextView mFooterText; private final ImageView mFooterIcon; + private final ImageView mFooterIcon2; private final Context mContext; private final Callback mCallback = new Callback(); @@ -57,8 +58,10 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene private boolean mIsVisible; private boolean mIsIconVisible; + private boolean mIsIcon2Visible; private int mFooterTextId; private int mFooterIconId; + private int mFooterIcon2Id; public QSFooter(QSPanel qsPanel, Context context) { mRootView = LayoutInflater.from(context) @@ -66,7 +69,9 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene mRootView.setOnClickListener(this); mFooterText = (TextView) mRootView.findViewById(R.id.footer_text); mFooterIcon = (ImageView) mRootView.findViewById(R.id.footer_icon); + mFooterIcon2 = (ImageView) mRootView.findViewById(R.id.footer_icon2); mFooterIconId = R.drawable.ic_qs_vpn; + mFooterIcon2Id = R.drawable.ic_qs_network_logging; mContext = context; mMainHandler = new Handler(); } @@ -113,17 +118,29 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene } private void handleRefreshState() { - mIsIconVisible = mSecurityController.isVpnEnabled(); // If the device has device owner, show "Device may be monitored", but -- // TODO See b/25779452 -- device owner doesn't actually have monitoring power. + boolean isVpnEnabled = mSecurityController.isVpnEnabled(); + boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled(); + mIsIconVisible = isVpnEnabled || isNetworkLoggingEnabled; + mIsIcon2Visible = isVpnEnabled && isNetworkLoggingEnabled; if (mSecurityController.isDeviceManaged()) { mFooterTextId = R.string.device_owned_footer; mIsVisible = true; + int footerIconId = isVpnEnabled + ? R.drawable.ic_qs_vpn + : R.drawable.ic_qs_network_logging; + if (mFooterIconId != footerIconId) { + mFooterIconId = footerIconId; + mMainHandler.post(mUpdateIcon); + } } else { boolean isBranded = mSecurityController.isVpnBranded(); mFooterTextId = isBranded ? R.string.branded_vpn_footer : R.string.vpn_footer; // Update the VPN footer icon, if needed. - int footerIconId = isBranded ? R.drawable.ic_qs_branded_vpn : R.drawable.ic_qs_vpn; + int footerIconId = isVpnEnabled + ? (isBranded ? R.drawable.ic_qs_branded_vpn : R.drawable.ic_qs_vpn) + : R.drawable.ic_qs_network_logging; if (mFooterIconId != footerIconId) { mFooterIconId = footerIconId; mMainHandler.post(mUpdateIcon); @@ -219,6 +236,7 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene @Override public void run() { mFooterIcon.setImageResource(mFooterIconId); + mFooterIcon2.setImageResource(mFooterIcon2Id); } }; @@ -230,6 +248,7 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene } mRootView.setVisibility(mIsVisible ? View.VISIBLE : View.GONE); mFooterIcon.setVisibility(mIsIconVisible ? View.VISIBLE : View.INVISIBLE); + mFooterIcon2.setVisibility(mIsIcon2Visible ? View.VISIBLE : View.INVISIBLE); } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java index 014afae7bf5a..63d4381e4aaa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java @@ -21,6 +21,7 @@ public interface SecurityController { boolean hasProfileOwner(); String getDeviceOwnerName(); String getProfileOwnerName(); + boolean isNetworkLoggingEnabled(); boolean isVpnEnabled(); boolean isVpnRestricted(); /** Whether the VPN app should use branded VPN iconography. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index 07d3b596bc05..65a119ac0f1c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -153,6 +153,11 @@ public class SecurityControllerImpl implements SecurityController { return null; } + @Override + public boolean isNetworkLoggingEnabled() { + return mDevicePolicyManager.isNetworkLoggingEnabled(null); + } + @Override public boolean isVpnEnabled() { for (int profileId : mUserManager.getProfileIdsWithDisabled(mVpnUserId)) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 232300a2e70c..8189a7ec3b08 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -6531,6 +6531,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private void enforceDeviceOwnerOrManageUsers() { + synchronized (this) { + if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, + mInjector.binderGetCallingUid()) != null) { + return; + } + } + enforceManageUsers(); + } + private void ensureCallerPackage(@Nullable String packageName) { if (packageName == null) { Preconditions.checkState(isCallerWithSystemUid(), @@ -9488,9 +9498,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } - Preconditions.checkNotNull(admin); synchronized (this) { - getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + enforceDeviceOwnerOrManageUsers(); return isNetworkLoggingEnabledInternalLocked(); } } -- cgit v1.2.3-59-g8ed1b