Link from Quick Settings to Enterprise Privacy page
This CL updates the information shown in Quick Settings when a device
is managed by a Device Owner and adds a "learn more" link that takes
the user to the Enterprise Privacy page in Settings.
Bug: 32692748
Bug: 25779452
Test: runtest --path frameworks/base/packages/SystemUI/tests &
runtest --path frameworks/base/core/tests/coretests
Change-Id: I8cbb6f2bb5c6da29ae581b6dcf7a01b1a4f2af2b
This commit is contained in:
@@ -35532,6 +35532,7 @@ package android.provider {
|
||||
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
|
||||
field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS";
|
||||
field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
|
||||
field public static final java.lang.String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
|
||||
field public static final java.lang.String ACTION_HARD_KEYBOARD_SETTINGS = "android.settings.HARD_KEYBOARD_SETTINGS";
|
||||
field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS";
|
||||
field public static final java.lang.String ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS = "android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS";
|
||||
|
||||
@@ -32831,6 +32831,7 @@ package android.provider {
|
||||
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
|
||||
field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS";
|
||||
field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
|
||||
field public static final java.lang.String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
|
||||
field public static final java.lang.String ACTION_HARD_KEYBOARD_SETTINGS = "android.settings.HARD_KEYBOARD_SETTINGS";
|
||||
field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS";
|
||||
field public static final java.lang.String ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS = "android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS";
|
||||
|
||||
@@ -1321,6 +1321,20 @@ public final class Settings {
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_WEBVIEW_SETTINGS = "android.settings.WEBVIEW_SETTINGS";
|
||||
|
||||
/**
|
||||
* Activity Action: Show enterprise privacy section.
|
||||
* <p>
|
||||
* Input: Nothing.
|
||||
* <p>
|
||||
* Output: Nothing.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS
|
||||
= "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
|
||||
|
||||
// End of Intent actions for Settings
|
||||
|
||||
/**
|
||||
|
||||
@@ -351,6 +351,10 @@ public class SettingsProviderTest extends AndroidTestCase {
|
||||
assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SETTINGS));
|
||||
assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SAVED_NETWORK_SETTINGS));
|
||||
assertCanBeHandled(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
|
||||
|
||||
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
|
||||
assertCanBeHandled(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertCanBeHandled(final Intent intent) {
|
||||
|
||||
@@ -840,10 +840,10 @@
|
||||
<!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] -->
|
||||
<string name="keyguard_unlock">Swipe up to unlock</string>
|
||||
|
||||
<!-- Text on keyguard screen indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
|
||||
<!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
|
||||
<string name="do_disclosure_generic">This device is managed</string>
|
||||
|
||||
<!-- Text on keyguard screen indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=40] -->
|
||||
<!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=40] -->
|
||||
<string name="do_disclosure_with_name">This device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g></string>
|
||||
|
||||
<!-- Shows when people have clicked on the phone icon [CHAR LIMIT=60] -->
|
||||
@@ -992,9 +992,6 @@
|
||||
<!-- Text which is shown in the notification shade when there are no notifications. [CHAR LIMIT=30] -->
|
||||
<string name="empty_shade_text">No notifications</string>
|
||||
|
||||
<!-- Footer device owned text [CHAR LIMIT=50] -->
|
||||
<string name="device_owned_footer">Device may be monitored</string>
|
||||
|
||||
<!-- Footer profile owned text [CHAR LIMIT=50] -->
|
||||
<string name="profile_owned_footer">Profile may be monitored</string>
|
||||
|
||||
@@ -1019,15 +1016,27 @@
|
||||
<!-- Monitoring dialog disconnect vpn button [CHAR LIMIT=30] -->
|
||||
<string name="disconnect_vpn">Disconnect VPN</string>
|
||||
|
||||
<!-- Monitoring dialog device owner body text [CHAR LIMIT=400] -->
|
||||
<string name="monitoring_description_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information. For more information, contact your administrator.</string>
|
||||
<!-- Monitoring dialog: Header indicating that the device is managed by a Device Owner app [CHAR LIMIT=80] -->
|
||||
<string name="monitoring_description_do_header_generic">Your device is managed by <xliff:g id="device_owner_app" example="Google Mobile Management">%1$s</xliff:g>.</string>
|
||||
|
||||
<!-- Monitoring dialog: Header indicating that the device is managed by a Device Owner app [CHAR LIMIT=60] -->
|
||||
<string name="monitoring_description_do_header_with_name"><xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> uses <xliff:g id="device_owner_app" example="Google Mobile Management">%2$s</xliff:g> to manage your device.</string>
|
||||
|
||||
<!-- Monitoring dialog: Part of text body explaining what a Device Owner app can do [CHAR LIMIT=130] -->
|
||||
<string name="monitoring_description_do_body">Your administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.</string>
|
||||
|
||||
<!-- Monitoring dialog: Part of text body explaining that a VPN is connected and what it can do, for devices managed by a Device Owner app [CHAR LIMIT=130] -->
|
||||
<string name="monitoring_description_do_body_vpn">You\'re connected to <xliff:g id="vpn_app">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites.</string>
|
||||
|
||||
<!-- Monitoring dialog: Space that separates the body text and the "learn more" link that follows it. [CHAR LIMIT=5] -->
|
||||
<string name="monitoring_description_do_learn_more_separator">" "</string>
|
||||
|
||||
<!-- Monitoring dialog: Link to learn more about what a Device Owner app can do [CHAR LIMIT=55] -->
|
||||
<string name="monitoring_description_do_learn_more">Learn more</string>
|
||||
|
||||
<!-- Monitoring dialog VPN text [CHAR LIMIT=400] -->
|
||||
<string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps, and websites.</string>
|
||||
|
||||
<!-- Monitoring dialog VPN with device owner text [CHAR LIMIT=400] -->
|
||||
<string name="monitoring_description_vpn_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nYou\'re connected to a VPN, which can monitor your network activity, including emails, apps, and websites.\n\nFor more information, contact your administrator.</string>
|
||||
|
||||
<!-- Monitoring dialog VPN with profile owner text [CHAR LIMIT=400] -->
|
||||
<string name="monitoring_description_vpn_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your network activity.</string>
|
||||
|
||||
@@ -1049,9 +1058,6 @@
|
||||
<!-- Monitoring dialog text for multiple apps (in personal and work profiles) [CHAR LIMIT=400] -->
|
||||
<string name="monitoring_description_app_personal_work">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>. It is connected to <xliff:g id="application_work">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps, and websites.\n\nYou\'re also connected to <xliff:g id="application_personal">%3$s</xliff:g>, which can monitor your personal network activity.</string>
|
||||
|
||||
<!-- Monitoring dialog text for single app (with device owner) [CHAR LIMIT=400] -->
|
||||
<string name="monitoring_description_vpn_app_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nYou\'re connected to <xliff:g id="application">%2$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites.\n\nFor more information, contact your administrator.</string>
|
||||
|
||||
<!-- Indication on the keyguard that appears when the user disables trust agents until the next time they unlock manually. [CHAR LIMIT=NONE] -->
|
||||
<string name="keyguard_indication_trust_disabled">Device will stay locked until you manually unlock</string>
|
||||
|
||||
|
||||
@@ -24,10 +24,15 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -52,12 +57,12 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
private SecurityController mSecurityController;
|
||||
private AlertDialog mDialog;
|
||||
private QSTileHost mHost;
|
||||
private Handler mHandler;
|
||||
protected Handler mHandler;
|
||||
private final Handler mMainHandler;
|
||||
|
||||
private boolean mIsVisible;
|
||||
private boolean mIsIconVisible;
|
||||
private int mFooterTextId;
|
||||
private CharSequence mFooterTextContent = null;
|
||||
private int mFooterIconId;
|
||||
|
||||
public QSFooter(QSPanel qsPanel, Context context) {
|
||||
@@ -68,13 +73,14 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
mFooterIcon = (ImageView) mRootView.findViewById(R.id.footer_icon);
|
||||
mFooterIconId = R.drawable.ic_qs_vpn;
|
||||
mContext = context;
|
||||
mMainHandler = new Handler();
|
||||
mMainHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
public void setHost(QSTileHost host) {
|
||||
public void setHostEnvironment(QSTileHost host, SecurityController securityController,
|
||||
Looper looper) {
|
||||
mHost = host;
|
||||
mSecurityController = host.getSecurityController();
|
||||
mHandler = new H(host.getLooper());
|
||||
mSecurityController = securityController;
|
||||
mHandler = new H(looper);
|
||||
}
|
||||
|
||||
public void setListening(boolean listening) {
|
||||
@@ -114,14 +120,21 @@ 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.
|
||||
if (mSecurityController.isDeviceManaged()) {
|
||||
mFooterTextId = R.string.device_owned_footer;
|
||||
final CharSequence organizationName =
|
||||
mSecurityController.getDeviceOwnerOrganizationName();
|
||||
if (organizationName != null) {
|
||||
mFooterTextContent = mContext.getResources().getString(
|
||||
R.string.do_disclosure_with_name, organizationName);
|
||||
} else {
|
||||
mFooterTextContent =
|
||||
mContext.getResources().getString(R.string.do_disclosure_generic);
|
||||
}
|
||||
mIsVisible = true;
|
||||
} else {
|
||||
boolean isBranded = mSecurityController.isVpnBranded();
|
||||
mFooterTextId = isBranded ? R.string.branded_vpn_footer : R.string.vpn_footer;
|
||||
mFooterTextContent = mContext.getResources().getText(
|
||||
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;
|
||||
if (mFooterIconId != footerIconId) {
|
||||
@@ -142,23 +155,36 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
}
|
||||
|
||||
private void createDialog() {
|
||||
String deviceOwner = mSecurityController.getDeviceOwnerName();
|
||||
String profileOwner = mSecurityController.getProfileOwnerName();
|
||||
String primaryVpn = mSecurityController.getPrimaryVpnName();
|
||||
String profileVpn = mSecurityController.getProfileVpnName();
|
||||
boolean managed = mSecurityController.hasProfileOwner();
|
||||
boolean isBranded = deviceOwner == null && mSecurityController.isVpnBranded();
|
||||
final String deviceOwnerPackage = mSecurityController.getDeviceOwnerName();
|
||||
final String profileOwnerPackage = mSecurityController.getProfileOwnerName();
|
||||
final String primaryVpn = mSecurityController.getPrimaryVpnName();
|
||||
final String profileVpn = mSecurityController.getProfileVpnName();
|
||||
final CharSequence deviceOwnerOrganization =
|
||||
mSecurityController.getDeviceOwnerOrganizationName();
|
||||
boolean hasProfileOwner = mSecurityController.hasProfileOwner();
|
||||
boolean isBranded = deviceOwnerPackage == null && mSecurityController.isVpnBranded();
|
||||
|
||||
mDialog = new SystemUIDialog(mContext);
|
||||
if (!isBranded) {
|
||||
mDialog.setTitle(getTitle(deviceOwner));
|
||||
mDialog.setTitle(getTitle(deviceOwnerPackage));
|
||||
}
|
||||
mDialog.setMessage(getMessage(deviceOwner, profileOwner, primaryVpn, profileVpn, managed,
|
||||
isBranded));
|
||||
mDialog.setMessage(getMessage(deviceOwnerPackage, profileOwnerPackage, primaryVpn,
|
||||
profileVpn, deviceOwnerOrganization, hasProfileOwner, isBranded));
|
||||
|
||||
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(isBranded), this);
|
||||
if (mSecurityController.isVpnEnabled() && !mSecurityController.isVpnRestricted()) {
|
||||
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getSettingsButton(), this);
|
||||
}
|
||||
|
||||
// Make the link "learn more" clickable.
|
||||
// TODO: Reaching into SystemUIDialog's internal View hierarchy is ugly and error-prone.
|
||||
// This is a temporary solution. b/33126622 will introduce a custom View hierarchy for this
|
||||
// dialog, allowing us to set the movement method on the appropriate View without any
|
||||
// knowledge of SystemUIDialog's internals.
|
||||
mDialog.create();
|
||||
((TextView) mDialog.getWindow().findViewById(com.android.internal.R.id.message))
|
||||
.setMovementMethod(new LinkMovementMethod());
|
||||
|
||||
mDialog.show();
|
||||
}
|
||||
|
||||
@@ -170,22 +196,35 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
return mContext.getString(isBranded ? android.R.string.ok : R.string.quick_settings_done);
|
||||
}
|
||||
|
||||
private String getMessage(String deviceOwner, String profileOwner, String primaryVpn,
|
||||
String profileVpn, boolean primaryUserIsManaged, boolean isBranded) {
|
||||
// Show a special warning when the device has device owner, but --
|
||||
// TODO See b/25779452 -- device owner doesn't actually have monitoring power.
|
||||
if (deviceOwner != null) {
|
||||
if (primaryVpn != null) {
|
||||
return mContext.getString(R.string.monitoring_description_vpn_app_device_owned,
|
||||
deviceOwner, primaryVpn);
|
||||
protected CharSequence getMessage(String deviceOwnerPackage, String profileOwnerPackage,
|
||||
String primaryVpn, String profileVpn, CharSequence deviceOwnerOrganization,
|
||||
boolean hasProfileOwner, boolean isBranded) {
|
||||
if (deviceOwnerPackage != null) {
|
||||
final SpannableStringBuilder message = new SpannableStringBuilder();
|
||||
if (deviceOwnerOrganization != null) {
|
||||
message.append(mContext.getString(
|
||||
R.string.monitoring_description_do_header_with_name,
|
||||
deviceOwnerOrganization, deviceOwnerPackage));
|
||||
} else {
|
||||
return mContext.getString(R.string.monitoring_description_device_owned,
|
||||
deviceOwner);
|
||||
message.append(mContext.getString(R.string.monitoring_description_do_header_generic,
|
||||
deviceOwnerPackage));
|
||||
}
|
||||
message.append("\n\n");
|
||||
message.append(mContext.getString(R.string.monitoring_description_do_body));
|
||||
if (primaryVpn != null) {
|
||||
message.append("\n\n");
|
||||
message.append(mContext.getString(R.string.monitoring_description_do_body_vpn,
|
||||
primaryVpn));
|
||||
}
|
||||
message.append(mContext.getString(
|
||||
R.string.monitoring_description_do_learn_more_separator));
|
||||
message.append(mContext.getString(R.string.monitoring_description_do_learn_more),
|
||||
new EnterprisePrivacySpan(), 0);
|
||||
return message;
|
||||
} else if (primaryVpn != null) {
|
||||
if (profileVpn != null) {
|
||||
return mContext.getString(R.string.monitoring_description_app_personal_work,
|
||||
profileOwner, profileVpn, primaryVpn);
|
||||
profileOwnerPackage, profileVpn, primaryVpn);
|
||||
} else {
|
||||
if (isBranded) {
|
||||
return mContext.getString(R.string.branded_monitoring_description_app_personal,
|
||||
@@ -197,10 +236,10 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
}
|
||||
} else if (profileVpn != null) {
|
||||
return mContext.getString(R.string.monitoring_description_app_work,
|
||||
profileOwner, profileVpn);
|
||||
} else if (profileOwner != null && primaryUserIsManaged) {
|
||||
profileOwnerPackage, profileVpn);
|
||||
} else if (profileOwnerPackage != null && hasProfileOwner) {
|
||||
return mContext.getString(R.string.monitoring_description_device_owned,
|
||||
profileOwner);
|
||||
profileOwnerPackage);
|
||||
} else {
|
||||
// No device owner, no personal VPN, no work VPN, no user owner. Why are we here?
|
||||
return null;
|
||||
@@ -225,8 +264,8 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
private final Runnable mUpdateDisplayState = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mFooterTextId != 0) {
|
||||
mFooterText.setText(mFooterTextId);
|
||||
if (mFooterTextContent != null) {
|
||||
mFooterText.setText(mFooterTextContent);
|
||||
}
|
||||
mRootView.setVisibility(mIsVisible ? View.VISIBLE : View.GONE);
|
||||
mFooterIcon.setVisibility(mIsIconVisible ? View.VISIBLE : View.INVISIBLE);
|
||||
@@ -267,4 +306,18 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
}
|
||||
}
|
||||
|
||||
protected class EnterprisePrivacySpan extends ClickableSpan {
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
final Intent intent = new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
mDialog.dismiss();
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof EnterprisePrivacySpan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
|
||||
mHost = host;
|
||||
mHost.addCallback(this);
|
||||
setTiles(mHost.getTiles());
|
||||
mFooter.setHost(host);
|
||||
mFooter.setHostEnvironment(host, host.getSecurityController(), host.getLooper());
|
||||
mCustomizePanel = customizer;
|
||||
if (mCustomizePanel != null) {
|
||||
mCustomizePanel.setHost(mHost);
|
||||
|
||||
@@ -23,6 +23,7 @@ public interface SecurityController extends CallbackController<SecurityControlle
|
||||
boolean hasProfileOwner();
|
||||
String getDeviceOwnerName();
|
||||
String getProfileOwnerName();
|
||||
CharSequence getDeviceOwnerOrganizationName();
|
||||
boolean isVpnEnabled();
|
||||
boolean isVpnRestricted();
|
||||
/** Whether the VPN app should use branded VPN iconography. */
|
||||
|
||||
@@ -129,6 +129,11 @@ public class SecurityControllerImpl implements SecurityController {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getDeviceOwnerOrganizationName() {
|
||||
return mDevicePolicyManager.getDeviceOwnerOrganizationName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryVpnName() {
|
||||
VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.qs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Looper;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.policy.SecurityController;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class QSFooterTest extends SysuiTestCase {
|
||||
|
||||
private final String MANAGING_ORGANIZATION = "organization";
|
||||
private final String DEVICE_OWNER_PACKAGE = "TestDPC";
|
||||
private final String VPN_PACKAGE = "TestVPN";
|
||||
|
||||
private ViewGroup mRootView = mock(ViewGroup.class);
|
||||
private TextView mFooterText = mock(TextView.class);
|
||||
private QSFooter mFooter;
|
||||
private Resources mResources;
|
||||
private SecurityController mSecurityController = mock(SecurityController.class);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mRootView.findViewById(R.id.footer_text)).thenReturn(mFooterText);
|
||||
when(mRootView.findViewById(R.id.footer_icon)).thenReturn(mock(ImageView.class));
|
||||
final LayoutInflater layoutInflater = mock(LayoutInflater.class);
|
||||
when(layoutInflater.inflate(eq(R.layout.quick_settings_footer), anyObject(), anyBoolean()))
|
||||
.thenReturn(mRootView);
|
||||
final Context context = mock(Context.class);
|
||||
when(context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).thenReturn(layoutInflater);
|
||||
mResources = mContext.getResources();
|
||||
when(context.getResources()).thenReturn(mResources);
|
||||
mFooter = new QSFooter(null, context);
|
||||
reset(mRootView);
|
||||
mFooter.setHostEnvironment(null, mSecurityController, Looper.getMainLooper());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnmanaged() {
|
||||
when(mSecurityController.isDeviceManaged()).thenReturn(false);
|
||||
when(mSecurityController.isVpnEnabled()).thenReturn(false);
|
||||
when(mSecurityController.isVpnBranded()).thenReturn(false);
|
||||
mFooter.refreshState();
|
||||
|
||||
waitForIdleSync(mFooter.mHandler);
|
||||
verify(mRootView).setVisibility(View.GONE);
|
||||
verifyNoMoreInteractions(mRootView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManagedNoOwnerName() {
|
||||
when(mSecurityController.isDeviceManaged()).thenReturn(true);
|
||||
when(mSecurityController.getDeviceOwnerOrganizationName()).thenReturn(null);
|
||||
mFooter.refreshState();
|
||||
|
||||
waitForIdleSync(mFooter.mHandler);
|
||||
verify(mFooterText).setText(mResources.getString(R.string.do_disclosure_generic));
|
||||
verifyNoMoreInteractions(mFooterText);
|
||||
verify(mRootView).setVisibility(View.VISIBLE);
|
||||
verifyNoMoreInteractions(mRootView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManagedOwnerName() {
|
||||
when(mSecurityController.isDeviceManaged()).thenReturn(true);
|
||||
when(mSecurityController.getDeviceOwnerOrganizationName())
|
||||
.thenReturn(MANAGING_ORGANIZATION);
|
||||
mFooter.refreshState();
|
||||
|
||||
waitForIdleSync(mFooter.mHandler);
|
||||
verify(mFooterText).setText(mResources.getString(R.string.do_disclosure_with_name,
|
||||
MANAGING_ORGANIZATION));
|
||||
verifyNoMoreInteractions(mFooterText);
|
||||
verify(mRootView).setVisibility(View.VISIBLE);
|
||||
verifyNoMoreInteractions(mRootView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessageWithNoOrganizationAndNoVPN() {
|
||||
assertEquals(getExpectedMessage(false /* hasDeviceOwnerOrganization */, false /* hasVPN */),
|
||||
mFooter.getMessage(DEVICE_OWNER_PACKAGE,
|
||||
null /* profileOwnerPackage */,
|
||||
null /* primaryVpn */,
|
||||
null /* profileVpn */,
|
||||
null /* deviceOwnerOrganization */,
|
||||
false /* hasProfileOwner */,
|
||||
false /* isBranded */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessageWithNoOrganizationAndVPN() {
|
||||
assertEquals(getExpectedMessage(false /* hasDeviceOwnerOrganization */, true /* hasVPN */),
|
||||
mFooter.getMessage(DEVICE_OWNER_PACKAGE,
|
||||
null /* profileOwnerPackage */,
|
||||
VPN_PACKAGE,
|
||||
null /* profileVpn */,
|
||||
null /* deviceOwnerOrganization */,
|
||||
false /* hasProfileOwner */,
|
||||
false /* isBranded */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessageWithOrganizationAndNoVPN() {
|
||||
assertEquals(getExpectedMessage(true /* hasDeviceOwnerOrganization */, false /* hasVPN */),
|
||||
mFooter.getMessage(DEVICE_OWNER_PACKAGE,
|
||||
null /* profileOwnerPackage */,
|
||||
null /* primaryVpn */,
|
||||
null /* profileVpn */,
|
||||
MANAGING_ORGANIZATION,
|
||||
false /* hasProfileOwner */,
|
||||
false /* isBranded */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessageWithOrganizationAndVPN() {
|
||||
assertEquals(getExpectedMessage(true /* hasDeviceOwnerOrganization */, true /* hasVPN */),
|
||||
mFooter.getMessage(DEVICE_OWNER_PACKAGE,
|
||||
null /* profileOwnerPackage */,
|
||||
VPN_PACKAGE,
|
||||
null /* profileVpn */,
|
||||
MANAGING_ORGANIZATION,
|
||||
false /* hasProfileOwner */,
|
||||
false /* isBranded */));
|
||||
}
|
||||
|
||||
private CharSequence getExpectedMessage(boolean hasDeviceOwnerOrganization, boolean hasVPN) {
|
||||
final SpannableStringBuilder message = new SpannableStringBuilder();
|
||||
message.append(hasDeviceOwnerOrganization ?
|
||||
mResources.getString(R.string.monitoring_description_do_header_with_name,
|
||||
MANAGING_ORGANIZATION, DEVICE_OWNER_PACKAGE) :
|
||||
mResources.getString(R.string.monitoring_description_do_header_generic,
|
||||
DEVICE_OWNER_PACKAGE));
|
||||
message.append("\n\n");
|
||||
message.append(mResources.getString(R.string.monitoring_description_do_body));
|
||||
if (hasVPN) {
|
||||
message.append("\n\n");
|
||||
message.append(mResources.getString(R.string.monitoring_description_do_body_vpn,
|
||||
VPN_PACKAGE));
|
||||
}
|
||||
message.append(mResources.getString(
|
||||
R.string.monitoring_description_do_learn_more_separator));
|
||||
message.append(mResources.getString(R.string.monitoring_description_do_learn_more),
|
||||
mFooter.new EnterprisePrivacySpan(), 0);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.policy;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.UserManager;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SecurityControllerTest extends SysuiTestCase {
|
||||
private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
|
||||
private SecurityControllerImpl mSecurityController;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
final Context context = mock(Context.class);
|
||||
when(context.getSystemService(Context.DEVICE_POLICY_SERVICE))
|
||||
.thenReturn(mDevicePolicyManager);
|
||||
when(context.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||
.thenReturn(mock(ConnectivityManager.class));
|
||||
final UserManager userManager = mock(UserManager.class);
|
||||
when(userManager.getUserInfo(anyInt())).thenReturn(mock(UserInfo.class));
|
||||
when(context.getSystemService(Context.USER_SERVICE))
|
||||
.thenReturn(userManager);
|
||||
mSecurityController = new SecurityControllerImpl(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsDeviceManaged() {
|
||||
when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
|
||||
assertTrue(mSecurityController.isDeviceManaged());
|
||||
|
||||
when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
|
||||
assertFalse(mSecurityController.isDeviceManaged());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeviceOwnerOrganizationName() {
|
||||
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn("organization");
|
||||
assertEquals("organization", mSecurityController.getDeviceOwnerOrganizationName());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user