Extract QSSecurityFooterUtils out of QSSecurityFooter
This CL extracts QSSecurityFooterUtils out of QSSecurityFooter to make it usable outside of QSSecurityFooter, which is a ViewController scoped to the Quick Settings fragment. This will make the utils usable outside this controller, e.g. in an Interactor/ViewModel not scope to QS. Bug: 242040009 Test: atest QSSecurityFooterTest Change-Id: If8289c9f28525f35603d03ed0ba3e646b7c06df8
This commit is contained in:
@@ -15,122 +15,59 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.qs;
|
package com.android.systemui.qs;
|
||||||
|
|
||||||
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_CA_CERT;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_NETWORK;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_TITLE;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_TWO_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MONITORING_CA_CERT_SUBTITLE;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MONITORING_NETWORK_SUBTITLE;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MONITORING_VPN_SUBTITLE;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_NAMED_MANAGEMENT;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_PERSONAL_PROFILE_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_VIEW_POLICIES;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_WORK_PROFILE_CA_CERT;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_WORK_PROFILE_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_WORK_PROFILE_NETWORK;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT_MONITORING;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT_MULTIPLE_VPNS;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT_MONITORING;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT_MULTIPLE_VPNS;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_WORK_PROFILE_MONITORING;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_PERSONAL_PROFILE_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_MONITORING;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_NAMED_VPN;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_NETWORK;
|
|
||||||
|
|
||||||
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_SECURITY_FOOTER_VIEW;
|
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_SECURITY_FOOTER_VIEW;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.app.admin.DeviceAdminInfo;
|
|
||||||
import android.app.admin.DevicePolicyEventLogger;
|
import android.app.admin.DevicePolicyEventLogger;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.UserInfo;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.text.SpannableStringBuilder;
|
|
||||||
import android.text.method.LinkMovementMethod;
|
|
||||||
import android.text.style.ClickableSpan;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.Window;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import com.android.internal.jank.InteractionJankMonitor;
|
|
||||||
import com.android.internal.util.FrameworkStatsLog;
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
import com.android.systemui.FontSizeUtils;
|
import com.android.systemui.FontSizeUtils;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.DialogCuj;
|
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.common.shared.model.Icon;
|
import com.android.systemui.common.shared.model.Icon;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
|
||||||
import com.android.systemui.qs.dagger.QSScope;
|
import com.android.systemui.qs.dagger.QSScope;
|
||||||
import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig;
|
import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig;
|
||||||
import com.android.systemui.security.data.model.SecurityModel;
|
import com.android.systemui.security.data.model.SecurityModel;
|
||||||
import com.android.systemui.settings.UserTracker;
|
|
||||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
|
||||||
import com.android.systemui.statusbar.policy.SecurityController;
|
import com.android.systemui.statusbar.policy.SecurityController;
|
||||||
import com.android.systemui.util.ViewController;
|
import com.android.systemui.util.ViewController;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
/** Helper class for the configuration of the QS security footer button. */
|
/** ViewController for the footer actions. */
|
||||||
|
// TODO(b/242040009): Remove this class.
|
||||||
@QSScope
|
@QSScope
|
||||||
public class QSSecurityFooter extends ViewController<View>
|
public class QSSecurityFooter extends ViewController<View>
|
||||||
implements OnClickListener, DialogInterface.OnClickListener,
|
implements OnClickListener, VisibilityChangedDispatcher {
|
||||||
VisibilityChangedDispatcher {
|
|
||||||
protected static final String TAG = "QSSecurityFooter";
|
protected static final String TAG = "QSSecurityFooter";
|
||||||
protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
|
||||||
private static final boolean DEBUG_FORCE_VISIBLE = false;
|
|
||||||
|
|
||||||
private static final String INTERACTION_JANK_TAG = "managed_device_info";
|
|
||||||
|
|
||||||
private final TextView mFooterText;
|
private final TextView mFooterText;
|
||||||
private final ImageView mPrimaryFooterIcon;
|
private final ImageView mPrimaryFooterIcon;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private final DevicePolicyManager mDpm;
|
|
||||||
private final Callback mCallback = new Callback();
|
private final Callback mCallback = new Callback();
|
||||||
private final SecurityController mSecurityController;
|
private final SecurityController mSecurityController;
|
||||||
private final ActivityStarter mActivityStarter;
|
|
||||||
private final Handler mMainHandler;
|
private final Handler mMainHandler;
|
||||||
private final UserTracker mUserTracker;
|
|
||||||
private final DialogLaunchAnimator mDialogLaunchAnimator;
|
|
||||||
private final BroadcastDispatcher mBroadcastDispatcher;
|
private final BroadcastDispatcher mBroadcastDispatcher;
|
||||||
|
private final QSSecurityFooterUtils mQSSecurityFooterUtils;
|
||||||
|
|
||||||
private final AtomicBoolean mShouldUseSettingsButton = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
private AlertDialog mDialog;
|
|
||||||
protected H mHandler;
|
protected H mHandler;
|
||||||
|
|
||||||
private boolean mIsVisible;
|
private boolean mIsVisible;
|
||||||
@@ -152,82 +89,21 @@ public class QSSecurityFooter extends ViewController<View>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private Supplier<String> mManagementTitleSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(R.string.monitoring_title_device_owned);
|
|
||||||
|
|
||||||
private Supplier<String> mManagementMessageSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_management);
|
|
||||||
|
|
||||||
private Supplier<String> mManagementMonitoringStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_management_monitoring);
|
|
||||||
|
|
||||||
private Supplier<String> mManagementMultipleVpnStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_management_vpns);
|
|
||||||
|
|
||||||
private Supplier<String> mWorkProfileMonitoringStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_managed_profile_monitoring);
|
|
||||||
|
|
||||||
private Supplier<String> mWorkProfileNetworkStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_managed_profile_network_activity);
|
|
||||||
|
|
||||||
private Supplier<String> mMonitoringSubtitleCaCertStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.monitoring_subtitle_ca_certificate);
|
|
||||||
|
|
||||||
private Supplier<String> mMonitoringSubtitleNetworkStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.monitoring_subtitle_network_logging);
|
|
||||||
|
|
||||||
private Supplier<String> mMonitoringSubtitleVpnStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(R.string.monitoring_subtitle_vpn);
|
|
||||||
|
|
||||||
private Supplier<String> mViewPoliciesButtonStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(R.string.monitoring_button_view_policies);
|
|
||||||
|
|
||||||
private Supplier<String> mManagementDialogStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.monitoring_description_management);
|
|
||||||
|
|
||||||
private Supplier<String> mManagementDialogCaCertStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.monitoring_description_management_ca_certificate);
|
|
||||||
|
|
||||||
private Supplier<String> mWorkProfileDialogCaCertStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.monitoring_description_managed_profile_ca_certificate);
|
|
||||||
|
|
||||||
private Supplier<String> mManagementDialogNetworkStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.monitoring_description_management_network_logging);
|
|
||||||
|
|
||||||
private Supplier<String> mWorkProfileDialogNetworkStringSupplier = () ->
|
|
||||||
mContext == null ? null : mContext.getString(
|
|
||||||
R.string.monitoring_description_managed_profile_network_logging);
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
QSSecurityFooter(@Named(QS_SECURITY_FOOTER_VIEW) View rootView,
|
QSSecurityFooter(@Named(QS_SECURITY_FOOTER_VIEW) View rootView,
|
||||||
UserTracker userTracker, @Main Handler mainHandler,
|
@Main Handler mainHandler, SecurityController securityController,
|
||||||
ActivityStarter activityStarter, SecurityController securityController,
|
@Background Looper bgLooper, BroadcastDispatcher broadcastDispatcher,
|
||||||
DialogLaunchAnimator dialogLaunchAnimator, @Background Looper bgLooper,
|
QSSecurityFooterUtils qSSecurityFooterUtils) {
|
||||||
BroadcastDispatcher broadcastDispatcher) {
|
|
||||||
super(rootView);
|
super(rootView);
|
||||||
mFooterText = mView.findViewById(R.id.footer_text);
|
mFooterText = mView.findViewById(R.id.footer_text);
|
||||||
mPrimaryFooterIcon = mView.findViewById(R.id.primary_footer_icon);
|
mPrimaryFooterIcon = mView.findViewById(R.id.primary_footer_icon);
|
||||||
mFooterIcon = new Icon.Resource(R.drawable.ic_info_outline);
|
mFooterIcon = new Icon.Resource(R.drawable.ic_info_outline);
|
||||||
mContext = rootView.getContext();
|
mContext = rootView.getContext();
|
||||||
mDpm = rootView.getContext().getSystemService(DevicePolicyManager.class);
|
|
||||||
mMainHandler = mainHandler;
|
|
||||||
mActivityStarter = activityStarter;
|
|
||||||
mSecurityController = securityController;
|
mSecurityController = securityController;
|
||||||
|
mMainHandler = mainHandler;
|
||||||
mHandler = new H(bgLooper);
|
mHandler = new H(bgLooper);
|
||||||
mUserTracker = userTracker;
|
|
||||||
mDialogLaunchAnimator = dialogLaunchAnimator;
|
|
||||||
mBroadcastDispatcher = broadcastDispatcher;
|
mBroadcastDispatcher = broadcastDispatcher;
|
||||||
|
mQSSecurityFooterUtils = qSSecurityFooterUtils;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -292,16 +168,7 @@ public class QSSecurityFooter extends ViewController<View>
|
|||||||
|
|
||||||
// TODO(b/242040009): Remove this.
|
// TODO(b/242040009): Remove this.
|
||||||
public void showDeviceMonitoringDialog() {
|
public void showDeviceMonitoringDialog() {
|
||||||
showDeviceMonitoringDialog(mContext, mView);
|
mQSSecurityFooterUtils.showDeviceMonitoringDialog(mContext, mView);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the device monitoring dialog, and expand it from {@code view} if it's not null.
|
|
||||||
*
|
|
||||||
* Important: {@code view} must be associated to the same {@link Context} as the QSFragment.
|
|
||||||
*/
|
|
||||||
public void showDeviceMonitoringDialog(Context quickSettingsContext, @Nullable View view) {
|
|
||||||
createDialog(quickSettingsContext, view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshState() {
|
public void refreshState() {
|
||||||
@@ -310,7 +177,7 @@ public class QSSecurityFooter extends ViewController<View>
|
|||||||
|
|
||||||
private void handleRefreshState() {
|
private void handleRefreshState() {
|
||||||
SecurityModel securityModel = SecurityModel.create(mSecurityController);
|
SecurityModel securityModel = SecurityModel.create(mSecurityController);
|
||||||
SecurityButtonConfig buttonConfig = getButtonConfig(securityModel);
|
SecurityButtonConfig buttonConfig = mQSSecurityFooterUtils.getButtonConfig(securityModel);
|
||||||
|
|
||||||
if (buttonConfig == null) {
|
if (buttonConfig == null) {
|
||||||
mIsVisible = false;
|
mIsVisible = false;
|
||||||
@@ -326,577 +193,6 @@ public class QSSecurityFooter extends ViewController<View>
|
|||||||
mMainHandler.post(mUpdateDisplayState);
|
mMainHandler.post(mUpdateDisplayState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the {@link SecurityButtonConfig} of the security button, or {@code null} if no
|
|
||||||
* security button should be shown.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public SecurityButtonConfig getButtonConfig(SecurityModel securityModel) {
|
|
||||||
final boolean isDeviceManaged = securityModel.isDeviceManaged();
|
|
||||||
final UserInfo currentUser = mUserTracker.getUserInfo();
|
|
||||||
final boolean isDemoDevice = UserManager.isDeviceInDemoMode(mContext) && currentUser != null
|
|
||||||
&& currentUser.isDemo();
|
|
||||||
final boolean hasWorkProfile = securityModel.getHasWorkProfile();
|
|
||||||
final boolean hasCACerts = securityModel.getHasCACertInCurrentUser();
|
|
||||||
final boolean hasCACertsInWorkProfile = securityModel.getHasCACertInWorkProfile();
|
|
||||||
final boolean isNetworkLoggingEnabled = securityModel.isNetworkLoggingEnabled();
|
|
||||||
final String vpnName = securityModel.getPrimaryVpnName();
|
|
||||||
final String vpnNameWorkProfile = securityModel.getWorkProfileVpnName();
|
|
||||||
final CharSequence organizationName = securityModel.getDeviceOwnerOrganizationName();
|
|
||||||
final CharSequence workProfileOrganizationName =
|
|
||||||
securityModel.getWorkProfileOrganizationName();
|
|
||||||
final boolean isProfileOwnerOfOrganizationOwnedDevice =
|
|
||||||
securityModel.isProfileOwnerOfOrganizationOwnedDevice();
|
|
||||||
final boolean isParentalControlsEnabled = securityModel.isParentalControlsEnabled();
|
|
||||||
final boolean isWorkProfileOn = securityModel.isWorkProfileOn();
|
|
||||||
final boolean hasDisclosableWorkProfilePolicy = hasCACertsInWorkProfile
|
|
||||||
|| vpnNameWorkProfile != null || (hasWorkProfile && isNetworkLoggingEnabled);
|
|
||||||
// Update visibility of footer
|
|
||||||
boolean isVisible = (isDeviceManaged && !isDemoDevice)
|
|
||||||
|| hasCACerts
|
|
||||||
|| vpnName != null
|
|
||||||
|| isProfileOwnerOfOrganizationOwnedDevice
|
|
||||||
|| isParentalControlsEnabled
|
|
||||||
|| (hasDisclosableWorkProfilePolicy && isWorkProfileOn);
|
|
||||||
if (!isVisible && !DEBUG_FORCE_VISIBLE) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the view to be untappable if the device is an organization-owned device with a
|
|
||||||
// managed profile and there is either:
|
|
||||||
// a) no policy set which requires a privacy disclosure.
|
|
||||||
// b) a specific work policy set but the work profile is turned off.
|
|
||||||
boolean isClickable = !(isProfileOwnerOfOrganizationOwnedDevice
|
|
||||||
&& (!hasDisclosableWorkProfilePolicy || !isWorkProfileOn));
|
|
||||||
|
|
||||||
String text = getFooterText(isDeviceManaged, hasWorkProfile,
|
|
||||||
hasCACerts, hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName,
|
|
||||||
vpnNameWorkProfile, organizationName, workProfileOrganizationName,
|
|
||||||
isProfileOwnerOfOrganizationOwnedDevice, isParentalControlsEnabled,
|
|
||||||
isWorkProfileOn).toString();
|
|
||||||
|
|
||||||
Icon icon;
|
|
||||||
if (isParentalControlsEnabled) {
|
|
||||||
icon = new Icon.Loaded(securityModel.getDeviceAdminIcon());
|
|
||||||
} else if (vpnName != null || vpnNameWorkProfile != null) {
|
|
||||||
if (securityModel.isVpnBranded()) {
|
|
||||||
icon = new Icon.Resource(R.drawable.stat_sys_branded_vpn);
|
|
||||||
} else {
|
|
||||||
icon = new Icon.Resource(R.drawable.stat_sys_vpn_ic);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
icon = new Icon.Resource(R.drawable.ic_info_outline);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SecurityButtonConfig(icon, text, isClickable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected CharSequence getFooterText(boolean isDeviceManaged, boolean hasWorkProfile,
|
|
||||||
boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled,
|
|
||||||
String vpnName, String vpnNameWorkProfile, CharSequence organizationName,
|
|
||||||
CharSequence workProfileOrganizationName,
|
|
||||||
boolean isProfileOwnerOfOrganizationOwnedDevice, boolean isParentalControlsEnabled,
|
|
||||||
boolean isWorkProfileOn) {
|
|
||||||
if (isParentalControlsEnabled) {
|
|
||||||
return mContext.getString(R.string.quick_settings_disclosure_parental_controls);
|
|
||||||
}
|
|
||||||
if (isDeviceManaged || DEBUG_FORCE_VISIBLE) {
|
|
||||||
return getManagedDeviceFooterText(hasCACerts, hasCACertsInWorkProfile,
|
|
||||||
isNetworkLoggingEnabled, vpnName, vpnNameWorkProfile, organizationName);
|
|
||||||
}
|
|
||||||
return getManagedAndPersonalProfileFooterText(hasWorkProfile, hasCACerts,
|
|
||||||
hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName, vpnNameWorkProfile,
|
|
||||||
workProfileOrganizationName, isProfileOwnerOfOrganizationOwnedDevice,
|
|
||||||
isWorkProfileOn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getManagedDeviceFooterText(
|
|
||||||
boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled,
|
|
||||||
String vpnName, String vpnNameWorkProfile, CharSequence organizationName) {
|
|
||||||
if (hasCACerts || hasCACertsInWorkProfile || isNetworkLoggingEnabled) {
|
|
||||||
return getManagedDeviceMonitoringText(organizationName);
|
|
||||||
}
|
|
||||||
if (vpnName != null || vpnNameWorkProfile != null) {
|
|
||||||
return getManagedDeviceVpnText(vpnName, vpnNameWorkProfile, organizationName);
|
|
||||||
}
|
|
||||||
return getMangedDeviceGeneralText(organizationName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getManagedDeviceMonitoringText(CharSequence organizationName) {
|
|
||||||
if (organizationName == null) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_MANAGEMENT_MONITORING, mManagementMonitoringStringSupplier);
|
|
||||||
}
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_NAMED_MANAGEMENT_MONITORING,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_named_management_monitoring,
|
|
||||||
organizationName),
|
|
||||||
organizationName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getManagedDeviceVpnText(
|
|
||||||
String vpnName, String vpnNameWorkProfile, CharSequence organizationName) {
|
|
||||||
if (vpnName != null && vpnNameWorkProfile != null) {
|
|
||||||
if (organizationName == null) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_MANAGEMENT_MULTIPLE_VPNS, mManagementMultipleVpnStringSupplier);
|
|
||||||
}
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_NAMED_MANAGEMENT_MULTIPLE_VPNS,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_named_management_vpns,
|
|
||||||
organizationName),
|
|
||||||
organizationName);
|
|
||||||
}
|
|
||||||
String name = vpnName != null ? vpnName : vpnNameWorkProfile;
|
|
||||||
if (organizationName == null) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_MANAGEMENT_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_management_named_vpn,
|
|
||||||
name),
|
|
||||||
name);
|
|
||||||
}
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_NAMED_MANAGEMENT_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_named_management_named_vpn,
|
|
||||||
organizationName,
|
|
||||||
name),
|
|
||||||
organizationName,
|
|
||||||
name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getMangedDeviceGeneralText(CharSequence organizationName) {
|
|
||||||
if (organizationName == null) {
|
|
||||||
return mDpm.getResources().getString(QS_MSG_MANAGEMENT, mManagementMessageSupplier);
|
|
||||||
}
|
|
||||||
if (isFinancedDevice()) {
|
|
||||||
return mContext.getString(
|
|
||||||
R.string.quick_settings_financed_disclosure_named_management,
|
|
||||||
organizationName);
|
|
||||||
} else {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_NAMED_MANAGEMENT,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_named_management,
|
|
||||||
organizationName),
|
|
||||||
organizationName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getManagedAndPersonalProfileFooterText(boolean hasWorkProfile,
|
|
||||||
boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled,
|
|
||||||
String vpnName, String vpnNameWorkProfile, CharSequence workProfileOrganizationName,
|
|
||||||
boolean isProfileOwnerOfOrganizationOwnedDevice, boolean isWorkProfileOn) {
|
|
||||||
if (hasCACerts || (hasCACertsInWorkProfile && isWorkProfileOn)) {
|
|
||||||
return getMonitoringText(
|
|
||||||
hasCACerts, hasCACertsInWorkProfile, workProfileOrganizationName,
|
|
||||||
isWorkProfileOn);
|
|
||||||
}
|
|
||||||
if (vpnName != null || (vpnNameWorkProfile != null && isWorkProfileOn)) {
|
|
||||||
return getVpnText(hasWorkProfile, vpnName, vpnNameWorkProfile, isWorkProfileOn);
|
|
||||||
}
|
|
||||||
if (hasWorkProfile && isNetworkLoggingEnabled && isWorkProfileOn) {
|
|
||||||
return getManagedProfileNetworkActivityText();
|
|
||||||
}
|
|
||||||
if (isProfileOwnerOfOrganizationOwnedDevice) {
|
|
||||||
return getMangedDeviceGeneralText(workProfileOrganizationName);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getMonitoringText(boolean hasCACerts, boolean hasCACertsInWorkProfile,
|
|
||||||
CharSequence workProfileOrganizationName, boolean isWorkProfileOn) {
|
|
||||||
if (hasCACertsInWorkProfile && isWorkProfileOn) {
|
|
||||||
if (workProfileOrganizationName == null) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_WORK_PROFILE_MONITORING, mWorkProfileMonitoringStringSupplier);
|
|
||||||
}
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_NAMED_WORK_PROFILE_MONITORING,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_named_managed_profile_monitoring,
|
|
||||||
workProfileOrganizationName),
|
|
||||||
workProfileOrganizationName);
|
|
||||||
}
|
|
||||||
if (hasCACerts) {
|
|
||||||
return mContext.getString(R.string.quick_settings_disclosure_monitoring);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getVpnText(boolean hasWorkProfile, String vpnName, String vpnNameWorkProfile,
|
|
||||||
boolean isWorkProfileOn) {
|
|
||||||
if (vpnName != null && vpnNameWorkProfile != null) {
|
|
||||||
return mContext.getString(R.string.quick_settings_disclosure_vpns);
|
|
||||||
}
|
|
||||||
if (vpnNameWorkProfile != null && isWorkProfileOn) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_WORK_PROFILE_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_managed_profile_named_vpn,
|
|
||||||
vpnNameWorkProfile),
|
|
||||||
vpnNameWorkProfile);
|
|
||||||
}
|
|
||||||
if (vpnName != null) {
|
|
||||||
if (hasWorkProfile) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_PERSONAL_PROFILE_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.quick_settings_disclosure_personal_profile_named_vpn,
|
|
||||||
vpnName),
|
|
||||||
vpnName);
|
|
||||||
}
|
|
||||||
return mContext.getString(R.string.quick_settings_disclosure_named_vpn,
|
|
||||||
vpnName);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getManagedProfileNetworkActivityText() {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_MSG_WORK_PROFILE_NETWORK, mWorkProfileNetworkStringSupplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
|
||||||
final Intent intent = new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS);
|
|
||||||
dialog.dismiss();
|
|
||||||
// This dismisses the shade on opening the activity
|
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createDialog(Context quickSettingsContext, @Nullable View view) {
|
|
||||||
mShouldUseSettingsButton.set(false);
|
|
||||||
mHandler.post(() -> {
|
|
||||||
String settingsButtonText = getSettingsButton();
|
|
||||||
final View dialogView = createDialogView();
|
|
||||||
mMainHandler.post(() -> {
|
|
||||||
mDialog = new SystemUIDialog(quickSettingsContext, 0);
|
|
||||||
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
|
|
||||||
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, mShouldUseSettingsButton.get()
|
|
||||||
? settingsButtonText : getNegativeButton(), this);
|
|
||||||
|
|
||||||
mDialog.setView(dialogView);
|
|
||||||
if (view != null && view.isAggregatedVisible()) {
|
|
||||||
mDialogLaunchAnimator.showFromView(mDialog, view, new DialogCuj(
|
|
||||||
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG));
|
|
||||||
} else {
|
|
||||||
mDialog.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
Dialog getDialog() {
|
|
||||||
return mDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
View createDialogView() {
|
|
||||||
if (mSecurityController.isParentalControlsEnabled()) {
|
|
||||||
return createParentalControlsDialogView();
|
|
||||||
}
|
|
||||||
return createOrganizationDialogView();
|
|
||||||
}
|
|
||||||
|
|
||||||
private View createOrganizationDialogView() {
|
|
||||||
final boolean isDeviceManaged = mSecurityController.isDeviceManaged();
|
|
||||||
final boolean hasWorkProfile = mSecurityController.hasWorkProfile();
|
|
||||||
final CharSequence deviceOwnerOrganization =
|
|
||||||
mSecurityController.getDeviceOwnerOrganizationName();
|
|
||||||
final boolean hasCACerts = mSecurityController.hasCACertInCurrentUser();
|
|
||||||
final boolean hasCACertsInWorkProfile = mSecurityController.hasCACertInWorkProfile();
|
|
||||||
final boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled();
|
|
||||||
final String vpnName = mSecurityController.getPrimaryVpnName();
|
|
||||||
final String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName();
|
|
||||||
|
|
||||||
View dialogView = LayoutInflater.from(mContext)
|
|
||||||
.inflate(R.layout.quick_settings_footer_dialog, null, false);
|
|
||||||
|
|
||||||
// device management section
|
|
||||||
TextView deviceManagementSubtitle =
|
|
||||||
dialogView.findViewById(R.id.device_management_subtitle);
|
|
||||||
deviceManagementSubtitle.setText(getManagementTitle(deviceOwnerOrganization));
|
|
||||||
|
|
||||||
CharSequence managementMessage = getManagementMessage(isDeviceManaged,
|
|
||||||
deviceOwnerOrganization);
|
|
||||||
if (managementMessage == null) {
|
|
||||||
dialogView.findViewById(R.id.device_management_disclosures).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
dialogView.findViewById(R.id.device_management_disclosures).setVisibility(View.VISIBLE);
|
|
||||||
TextView deviceManagementWarning =
|
|
||||||
(TextView) dialogView.findViewById(R.id.device_management_warning);
|
|
||||||
deviceManagementWarning.setText(managementMessage);
|
|
||||||
mShouldUseSettingsButton.set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ca certificate section
|
|
||||||
CharSequence caCertsMessage = getCaCertsMessage(isDeviceManaged, hasCACerts,
|
|
||||||
hasCACertsInWorkProfile);
|
|
||||||
if (caCertsMessage == null) {
|
|
||||||
dialogView.findViewById(R.id.ca_certs_disclosures).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
dialogView.findViewById(R.id.ca_certs_disclosures).setVisibility(View.VISIBLE);
|
|
||||||
TextView caCertsWarning = (TextView) dialogView.findViewById(R.id.ca_certs_warning);
|
|
||||||
caCertsWarning.setText(caCertsMessage);
|
|
||||||
// Make "Open trusted credentials"-link clickable
|
|
||||||
caCertsWarning.setMovementMethod(new LinkMovementMethod());
|
|
||||||
|
|
||||||
TextView caCertsSubtitle = (TextView) dialogView.findViewById(R.id.ca_certs_subtitle);
|
|
||||||
String caCertsSubtitleMessage = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MONITORING_CA_CERT_SUBTITLE, mMonitoringSubtitleCaCertStringSupplier);
|
|
||||||
caCertsSubtitle.setText(caCertsSubtitleMessage);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// network logging section
|
|
||||||
CharSequence networkLoggingMessage = getNetworkLoggingMessage(isDeviceManaged,
|
|
||||||
isNetworkLoggingEnabled);
|
|
||||||
if (networkLoggingMessage == null) {
|
|
||||||
dialogView.findViewById(R.id.network_logging_disclosures).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
dialogView.findViewById(R.id.network_logging_disclosures).setVisibility(View.VISIBLE);
|
|
||||||
TextView networkLoggingWarning =
|
|
||||||
(TextView) dialogView.findViewById(R.id.network_logging_warning);
|
|
||||||
networkLoggingWarning.setText(networkLoggingMessage);
|
|
||||||
|
|
||||||
TextView networkLoggingSubtitle = (TextView) dialogView.findViewById(
|
|
||||||
R.id.network_logging_subtitle);
|
|
||||||
String networkLoggingSubtitleMessage = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MONITORING_NETWORK_SUBTITLE,
|
|
||||||
mMonitoringSubtitleNetworkStringSupplier);
|
|
||||||
networkLoggingSubtitle.setText(networkLoggingSubtitleMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// vpn section
|
|
||||||
CharSequence vpnMessage = getVpnMessage(isDeviceManaged, hasWorkProfile, vpnName,
|
|
||||||
vpnNameWorkProfile);
|
|
||||||
if (vpnMessage == null) {
|
|
||||||
dialogView.findViewById(R.id.vpn_disclosures).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
dialogView.findViewById(R.id.vpn_disclosures).setVisibility(View.VISIBLE);
|
|
||||||
TextView vpnWarning = (TextView) dialogView.findViewById(R.id.vpn_warning);
|
|
||||||
vpnWarning.setText(vpnMessage);
|
|
||||||
// Make "Open VPN Settings"-link clickable
|
|
||||||
vpnWarning.setMovementMethod(new LinkMovementMethod());
|
|
||||||
|
|
||||||
TextView vpnSubtitle = (TextView) dialogView.findViewById(R.id.vpn_subtitle);
|
|
||||||
String vpnSubtitleMessage = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MONITORING_VPN_SUBTITLE, mMonitoringSubtitleVpnStringSupplier);
|
|
||||||
vpnSubtitle.setText(vpnSubtitleMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: if a new section is added, should update configSubtitleVisibility to include
|
|
||||||
// the handling of the subtitle
|
|
||||||
configSubtitleVisibility(managementMessage != null,
|
|
||||||
caCertsMessage != null,
|
|
||||||
networkLoggingMessage != null,
|
|
||||||
vpnMessage != null,
|
|
||||||
dialogView);
|
|
||||||
|
|
||||||
return dialogView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private View createParentalControlsDialogView() {
|
|
||||||
View dialogView = LayoutInflater.from(mContext)
|
|
||||||
.inflate(R.layout.quick_settings_footer_dialog_parental_controls, null, false);
|
|
||||||
|
|
||||||
DeviceAdminInfo info = mSecurityController.getDeviceAdminInfo();
|
|
||||||
Drawable icon = mSecurityController.getIcon(info);
|
|
||||||
if (icon != null) {
|
|
||||||
ImageView imageView = (ImageView) dialogView.findViewById(R.id.parental_controls_icon);
|
|
||||||
imageView.setImageDrawable(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView parentalControlsTitle =
|
|
||||||
(TextView) dialogView.findViewById(R.id.parental_controls_title);
|
|
||||||
parentalControlsTitle.setText(mSecurityController.getLabel(info));
|
|
||||||
|
|
||||||
return dialogView;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void configSubtitleVisibility(boolean showDeviceManagement, boolean showCaCerts,
|
|
||||||
boolean showNetworkLogging, boolean showVpn, View dialogView) {
|
|
||||||
// Device Management title should always been shown
|
|
||||||
// When there is a Device Management message, all subtitles should be shown
|
|
||||||
if (showDeviceManagement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Hide the subtitle if there is only 1 message shown
|
|
||||||
int mSectionCountExcludingDeviceMgt = 0;
|
|
||||||
if (showCaCerts) { mSectionCountExcludingDeviceMgt++; }
|
|
||||||
if (showNetworkLogging) { mSectionCountExcludingDeviceMgt++; }
|
|
||||||
if (showVpn) { mSectionCountExcludingDeviceMgt++; }
|
|
||||||
|
|
||||||
// No work needed if there is no sections or more than 1 section
|
|
||||||
if (mSectionCountExcludingDeviceMgt != 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (showCaCerts) {
|
|
||||||
dialogView.findViewById(R.id.ca_certs_subtitle).setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if (showNetworkLogging) {
|
|
||||||
dialogView.findViewById(R.id.network_logging_subtitle).setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if (showVpn) {
|
|
||||||
dialogView.findViewById(R.id.vpn_subtitle).setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should not be called on the main thread to avoid making an IPC.
|
|
||||||
@VisibleForTesting
|
|
||||||
String getSettingsButton() {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_VIEW_POLICIES, mViewPoliciesButtonStringSupplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getPositiveButton() {
|
|
||||||
return mContext.getString(R.string.ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private String getNegativeButton() {
|
|
||||||
if (mSecurityController.isParentalControlsEnabled()) {
|
|
||||||
return mContext.getString(R.string.monitoring_button_view_controls);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected CharSequence getManagementMessage(boolean isDeviceManaged,
|
|
||||||
CharSequence organizationName) {
|
|
||||||
if (!isDeviceManaged) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (organizationName != null) {
|
|
||||||
if (isFinancedDevice()) {
|
|
||||||
return mContext.getString(R.string.monitoring_financed_description_named_management,
|
|
||||||
organizationName, organizationName);
|
|
||||||
} else {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_NAMED_MANAGEMENT,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.monitoring_description_named_management,
|
|
||||||
organizationName),
|
|
||||||
organizationName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mDpm.getResources().getString(QS_DIALOG_MANAGEMENT, mManagementDialogStringSupplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected CharSequence getCaCertsMessage(boolean isDeviceManaged, boolean hasCACerts,
|
|
||||||
boolean hasCACertsInWorkProfile) {
|
|
||||||
if (!(hasCACerts || hasCACertsInWorkProfile)) return null;
|
|
||||||
if (isDeviceManaged) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MANAGEMENT_CA_CERT, mManagementDialogCaCertStringSupplier);
|
|
||||||
}
|
|
||||||
if (hasCACertsInWorkProfile) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_WORK_PROFILE_CA_CERT, mWorkProfileDialogCaCertStringSupplier);
|
|
||||||
}
|
|
||||||
return mContext.getString(R.string.monitoring_description_ca_certificate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected CharSequence getNetworkLoggingMessage(boolean isDeviceManaged,
|
|
||||||
boolean isNetworkLoggingEnabled) {
|
|
||||||
if (!isNetworkLoggingEnabled) return null;
|
|
||||||
if (isDeviceManaged) {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MANAGEMENT_NETWORK, mManagementDialogNetworkStringSupplier);
|
|
||||||
} else {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_WORK_PROFILE_NETWORK, mWorkProfileDialogNetworkStringSupplier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected CharSequence getVpnMessage(boolean isDeviceManaged, boolean hasWorkProfile,
|
|
||||||
String vpnName, String vpnNameWorkProfile) {
|
|
||||||
if (vpnName == null && vpnNameWorkProfile == null) return null;
|
|
||||||
final SpannableStringBuilder message = new SpannableStringBuilder();
|
|
||||||
if (isDeviceManaged) {
|
|
||||||
if (vpnName != null && vpnNameWorkProfile != null) {
|
|
||||||
String namedVpns = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MANAGEMENT_TWO_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.monitoring_description_two_named_vpns,
|
|
||||||
vpnName, vpnNameWorkProfile),
|
|
||||||
vpnName, vpnNameWorkProfile);
|
|
||||||
message.append(namedVpns);
|
|
||||||
} else {
|
|
||||||
String name = vpnName != null ? vpnName : vpnNameWorkProfile;
|
|
||||||
String namedVp = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MANAGEMENT_NAMED_VPN,
|
|
||||||
() -> mContext.getString(R.string.monitoring_description_named_vpn, name),
|
|
||||||
name);
|
|
||||||
message.append(namedVp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (vpnName != null && vpnNameWorkProfile != null) {
|
|
||||||
String namedVpns = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MANAGEMENT_TWO_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.monitoring_description_two_named_vpns,
|
|
||||||
vpnName, vpnNameWorkProfile),
|
|
||||||
vpnName, vpnNameWorkProfile);
|
|
||||||
message.append(namedVpns);
|
|
||||||
} else if (vpnNameWorkProfile != null) {
|
|
||||||
String namedVpn = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_WORK_PROFILE_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.monitoring_description_managed_profile_named_vpn,
|
|
||||||
vpnNameWorkProfile),
|
|
||||||
vpnNameWorkProfile);
|
|
||||||
message.append(namedVpn);
|
|
||||||
} else if (hasWorkProfile) {
|
|
||||||
String namedVpn = mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_PERSONAL_PROFILE_NAMED_VPN,
|
|
||||||
() -> mContext.getString(
|
|
||||||
R.string.monitoring_description_personal_profile_named_vpn,
|
|
||||||
vpnName),
|
|
||||||
vpnName);
|
|
||||||
message.append(namedVpn);
|
|
||||||
} else {
|
|
||||||
message.append(mContext.getString(R.string.monitoring_description_named_vpn,
|
|
||||||
vpnName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
message.append(mContext.getString(R.string.monitoring_description_vpn_settings_separator));
|
|
||||||
message.append(mContext.getString(R.string.monitoring_description_vpn_settings),
|
|
||||||
new VpnSpan(), 0);
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
CharSequence getManagementTitle(CharSequence deviceOwnerOrganization) {
|
|
||||||
if (deviceOwnerOrganization != null && isFinancedDevice()) {
|
|
||||||
return mContext.getString(R.string.monitoring_title_financed_device,
|
|
||||||
deviceOwnerOrganization);
|
|
||||||
} else {
|
|
||||||
return mDpm.getResources().getString(
|
|
||||||
QS_DIALOG_MANAGEMENT_TITLE,
|
|
||||||
mManagementTitleSupplier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isFinancedDevice() {
|
|
||||||
return mSecurityController.isDeviceManaged()
|
|
||||||
&& mSecurityController.getDeviceOwnerType(
|
|
||||||
mSecurityController.getDeviceOwnerComponentOnAnyUser())
|
|
||||||
== DEVICE_OWNER_TYPE_FINANCED;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Runnable mUpdatePrimaryIcon = new Runnable() {
|
private final Runnable mUpdatePrimaryIcon = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -914,7 +210,7 @@ public class QSSecurityFooter extends ViewController<View>
|
|||||||
if (mFooterTextContent != null) {
|
if (mFooterTextContent != null) {
|
||||||
mFooterText.setText(mFooterTextContent);
|
mFooterText.setText(mFooterTextContent);
|
||||||
}
|
}
|
||||||
mView.setVisibility(mIsVisible || DEBUG_FORCE_VISIBLE ? View.VISIBLE : View.GONE);
|
mView.setVisibility(mIsVisible ? View.VISIBLE : View.GONE);
|
||||||
if (mVisibilityChangedListener != null) {
|
if (mVisibilityChangedListener != null) {
|
||||||
mVisibilityChangedListener.onVisibilityChanged(mView.getVisibility());
|
mVisibilityChangedListener.onVisibilityChanged(mView.getVisibility());
|
||||||
}
|
}
|
||||||
@@ -961,25 +257,4 @@ public class QSSecurityFooter extends ViewController<View>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class VpnSpan extends ClickableSpan {
|
|
||||||
@Override
|
|
||||||
public void onClick(View widget) {
|
|
||||||
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
|
|
||||||
mDialog.dismiss();
|
|
||||||
// This dismisses the shade on opening the activity
|
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// for testing, to compare two CharSequences containing VpnSpans
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object object) {
|
|
||||||
return object instanceof VpnSpan;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return 314159257; // prime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,792 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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 static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_CA_CERT;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_NETWORK;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_TITLE;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MANAGEMENT_TWO_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MONITORING_CA_CERT_SUBTITLE;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MONITORING_NETWORK_SUBTITLE;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_MONITORING_VPN_SUBTITLE;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_NAMED_MANAGEMENT;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_PERSONAL_PROFILE_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_VIEW_POLICIES;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_WORK_PROFILE_CA_CERT;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_WORK_PROFILE_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG_WORK_PROFILE_NETWORK;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT_MONITORING;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT_MULTIPLE_VPNS;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_MANAGEMENT_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT_MONITORING;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT_MULTIPLE_VPNS;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_MANAGEMENT_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_NAMED_WORK_PROFILE_MONITORING;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_PERSONAL_PROFILE_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_MONITORING;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_NAMED_VPN;
|
||||||
|
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_MSG_WORK_PROFILE_NETWORK;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.admin.DeviceAdminInfo;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.UserInfo;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.UserManager;
|
||||||
|
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.Window;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.internal.jank.InteractionJankMonitor;
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.animation.DialogCuj;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
|
import com.android.systemui.common.shared.model.Icon;
|
||||||
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
|
import com.android.systemui.dagger.qualifiers.Application;
|
||||||
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
|
import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig;
|
||||||
|
import com.android.systemui.security.data.model.SecurityModel;
|
||||||
|
import com.android.systemui.settings.UserTracker;
|
||||||
|
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||||
|
import com.android.systemui.statusbar.policy.SecurityController;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
/** Helper class for the configuration of the QS security footer button. */
|
||||||
|
@SysUISingleton
|
||||||
|
public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
|
||||||
|
protected static final String TAG = "QSSecurityFooterUtils";
|
||||||
|
protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
private static final boolean DEBUG_FORCE_VISIBLE = false;
|
||||||
|
|
||||||
|
private static final String INTERACTION_JANK_TAG = "managed_device_info";
|
||||||
|
|
||||||
|
@Application private Context mContext;
|
||||||
|
private final DevicePolicyManager mDpm;
|
||||||
|
|
||||||
|
private final SecurityController mSecurityController;
|
||||||
|
private final ActivityStarter mActivityStarter;
|
||||||
|
private final Handler mMainHandler;
|
||||||
|
private final UserTracker mUserTracker;
|
||||||
|
private final DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
|
||||||
|
private final AtomicBoolean mShouldUseSettingsButton = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
protected Handler mBgHandler;
|
||||||
|
private AlertDialog mDialog;
|
||||||
|
|
||||||
|
private Supplier<String> mManagementTitleSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(R.string.monitoring_title_device_owned);
|
||||||
|
|
||||||
|
private Supplier<String> mManagementMessageSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_management);
|
||||||
|
|
||||||
|
private Supplier<String> mManagementMonitoringStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_management_monitoring);
|
||||||
|
|
||||||
|
private Supplier<String> mManagementMultipleVpnStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_management_vpns);
|
||||||
|
|
||||||
|
private Supplier<String> mWorkProfileMonitoringStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_managed_profile_monitoring);
|
||||||
|
|
||||||
|
private Supplier<String> mWorkProfileNetworkStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_managed_profile_network_activity);
|
||||||
|
|
||||||
|
private Supplier<String> mMonitoringSubtitleCaCertStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.monitoring_subtitle_ca_certificate);
|
||||||
|
|
||||||
|
private Supplier<String> mMonitoringSubtitleNetworkStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.monitoring_subtitle_network_logging);
|
||||||
|
|
||||||
|
private Supplier<String> mMonitoringSubtitleVpnStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(R.string.monitoring_subtitle_vpn);
|
||||||
|
|
||||||
|
private Supplier<String> mViewPoliciesButtonStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(R.string.monitoring_button_view_policies);
|
||||||
|
|
||||||
|
private Supplier<String> mManagementDialogStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.monitoring_description_management);
|
||||||
|
|
||||||
|
private Supplier<String> mManagementDialogCaCertStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.monitoring_description_management_ca_certificate);
|
||||||
|
|
||||||
|
private Supplier<String> mWorkProfileDialogCaCertStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.monitoring_description_managed_profile_ca_certificate);
|
||||||
|
|
||||||
|
private Supplier<String> mManagementDialogNetworkStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.monitoring_description_management_network_logging);
|
||||||
|
|
||||||
|
private Supplier<String> mWorkProfileDialogNetworkStringSupplier = () ->
|
||||||
|
mContext == null ? null : mContext.getString(
|
||||||
|
R.string.monitoring_description_managed_profile_network_logging);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
QSSecurityFooterUtils(
|
||||||
|
@Application Context context, UserTracker userTracker, @Main Handler mainHandler,
|
||||||
|
ActivityStarter activityStarter, SecurityController securityController,
|
||||||
|
@Background Looper bgLooper, DialogLaunchAnimator dialogLaunchAnimator) {
|
||||||
|
mContext = context;
|
||||||
|
mDpm = mContext.getSystemService(DevicePolicyManager.class);
|
||||||
|
mUserTracker = userTracker;
|
||||||
|
mMainHandler = mainHandler;
|
||||||
|
mActivityStarter = activityStarter;
|
||||||
|
mSecurityController = securityController;
|
||||||
|
mBgHandler = new Handler(bgLooper);
|
||||||
|
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Show the device monitoring dialog. */
|
||||||
|
public void showDeviceMonitoringDialog(Context quickSettingsContext, @Nullable View view) {
|
||||||
|
createDialog(quickSettingsContext, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link SecurityButtonConfig} of the security button, or {@code null} if no
|
||||||
|
* security button should be shown.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public SecurityButtonConfig getButtonConfig(SecurityModel securityModel) {
|
||||||
|
final boolean isDeviceManaged = securityModel.isDeviceManaged();
|
||||||
|
final UserInfo currentUser = mUserTracker.getUserInfo();
|
||||||
|
final boolean isDemoDevice = UserManager.isDeviceInDemoMode(mContext) && currentUser != null
|
||||||
|
&& currentUser.isDemo();
|
||||||
|
final boolean hasWorkProfile = securityModel.getHasWorkProfile();
|
||||||
|
final boolean hasCACerts = securityModel.getHasCACertInCurrentUser();
|
||||||
|
final boolean hasCACertsInWorkProfile = securityModel.getHasCACertInWorkProfile();
|
||||||
|
final boolean isNetworkLoggingEnabled = securityModel.isNetworkLoggingEnabled();
|
||||||
|
final String vpnName = securityModel.getPrimaryVpnName();
|
||||||
|
final String vpnNameWorkProfile = securityModel.getWorkProfileVpnName();
|
||||||
|
final CharSequence organizationName = securityModel.getDeviceOwnerOrganizationName();
|
||||||
|
final CharSequence workProfileOrganizationName =
|
||||||
|
securityModel.getWorkProfileOrganizationName();
|
||||||
|
final boolean isProfileOwnerOfOrganizationOwnedDevice =
|
||||||
|
securityModel.isProfileOwnerOfOrganizationOwnedDevice();
|
||||||
|
final boolean isParentalControlsEnabled = securityModel.isParentalControlsEnabled();
|
||||||
|
final boolean isWorkProfileOn = securityModel.isWorkProfileOn();
|
||||||
|
final boolean hasDisclosableWorkProfilePolicy = hasCACertsInWorkProfile
|
||||||
|
|| vpnNameWorkProfile != null || (hasWorkProfile && isNetworkLoggingEnabled);
|
||||||
|
// Update visibility of footer
|
||||||
|
boolean isVisible = (isDeviceManaged && !isDemoDevice)
|
||||||
|
|| hasCACerts
|
||||||
|
|| vpnName != null
|
||||||
|
|| isProfileOwnerOfOrganizationOwnedDevice
|
||||||
|
|| isParentalControlsEnabled
|
||||||
|
|| (hasDisclosableWorkProfilePolicy && isWorkProfileOn);
|
||||||
|
if (!isVisible && !DEBUG_FORCE_VISIBLE) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the view to be untappable if the device is an organization-owned device with a
|
||||||
|
// managed profile and there is either:
|
||||||
|
// a) no policy set which requires a privacy disclosure.
|
||||||
|
// b) a specific work policy set but the work profile is turned off.
|
||||||
|
boolean isClickable = !(isProfileOwnerOfOrganizationOwnedDevice
|
||||||
|
&& (!hasDisclosableWorkProfilePolicy || !isWorkProfileOn));
|
||||||
|
|
||||||
|
String text = getFooterText(isDeviceManaged, hasWorkProfile,
|
||||||
|
hasCACerts, hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName,
|
||||||
|
vpnNameWorkProfile, organizationName, workProfileOrganizationName,
|
||||||
|
isProfileOwnerOfOrganizationOwnedDevice, isParentalControlsEnabled,
|
||||||
|
isWorkProfileOn).toString();
|
||||||
|
|
||||||
|
Icon icon;
|
||||||
|
if (isParentalControlsEnabled) {
|
||||||
|
icon = new Icon.Loaded(securityModel.getDeviceAdminIcon());
|
||||||
|
} else if (vpnName != null || vpnNameWorkProfile != null) {
|
||||||
|
if (securityModel.isVpnBranded()) {
|
||||||
|
icon = new Icon.Resource(R.drawable.stat_sys_branded_vpn);
|
||||||
|
} else {
|
||||||
|
icon = new Icon.Resource(R.drawable.stat_sys_vpn_ic);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
icon = new Icon.Resource(R.drawable.ic_info_outline);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SecurityButtonConfig(icon, text, isClickable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected CharSequence getFooterText(boolean isDeviceManaged, boolean hasWorkProfile,
|
||||||
|
boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled,
|
||||||
|
String vpnName, String vpnNameWorkProfile, CharSequence organizationName,
|
||||||
|
CharSequence workProfileOrganizationName,
|
||||||
|
boolean isProfileOwnerOfOrganizationOwnedDevice, boolean isParentalControlsEnabled,
|
||||||
|
boolean isWorkProfileOn) {
|
||||||
|
if (isParentalControlsEnabled) {
|
||||||
|
return mContext.getString(R.string.quick_settings_disclosure_parental_controls);
|
||||||
|
}
|
||||||
|
if (isDeviceManaged || DEBUG_FORCE_VISIBLE) {
|
||||||
|
return getManagedDeviceFooterText(hasCACerts, hasCACertsInWorkProfile,
|
||||||
|
isNetworkLoggingEnabled, vpnName, vpnNameWorkProfile, organizationName);
|
||||||
|
}
|
||||||
|
return getManagedAndPersonalProfileFooterText(hasWorkProfile, hasCACerts,
|
||||||
|
hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName, vpnNameWorkProfile,
|
||||||
|
workProfileOrganizationName, isProfileOwnerOfOrganizationOwnedDevice,
|
||||||
|
isWorkProfileOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getManagedDeviceFooterText(
|
||||||
|
boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled,
|
||||||
|
String vpnName, String vpnNameWorkProfile, CharSequence organizationName) {
|
||||||
|
if (hasCACerts || hasCACertsInWorkProfile || isNetworkLoggingEnabled) {
|
||||||
|
return getManagedDeviceMonitoringText(organizationName);
|
||||||
|
}
|
||||||
|
if (vpnName != null || vpnNameWorkProfile != null) {
|
||||||
|
return getManagedDeviceVpnText(vpnName, vpnNameWorkProfile, organizationName);
|
||||||
|
}
|
||||||
|
return getMangedDeviceGeneralText(organizationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getManagedDeviceMonitoringText(CharSequence organizationName) {
|
||||||
|
if (organizationName == null) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_MANAGEMENT_MONITORING, mManagementMonitoringStringSupplier);
|
||||||
|
}
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_NAMED_MANAGEMENT_MONITORING,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_named_management_monitoring,
|
||||||
|
organizationName),
|
||||||
|
organizationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getManagedDeviceVpnText(
|
||||||
|
String vpnName, String vpnNameWorkProfile, CharSequence organizationName) {
|
||||||
|
if (vpnName != null && vpnNameWorkProfile != null) {
|
||||||
|
if (organizationName == null) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_MANAGEMENT_MULTIPLE_VPNS, mManagementMultipleVpnStringSupplier);
|
||||||
|
}
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_NAMED_MANAGEMENT_MULTIPLE_VPNS,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_named_management_vpns,
|
||||||
|
organizationName),
|
||||||
|
organizationName);
|
||||||
|
}
|
||||||
|
String name = vpnName != null ? vpnName : vpnNameWorkProfile;
|
||||||
|
if (organizationName == null) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_MANAGEMENT_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_management_named_vpn,
|
||||||
|
name),
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_NAMED_MANAGEMENT_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_named_management_named_vpn,
|
||||||
|
organizationName,
|
||||||
|
name),
|
||||||
|
organizationName,
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMangedDeviceGeneralText(CharSequence organizationName) {
|
||||||
|
if (organizationName == null) {
|
||||||
|
return mDpm.getResources().getString(QS_MSG_MANAGEMENT, mManagementMessageSupplier);
|
||||||
|
}
|
||||||
|
if (isFinancedDevice()) {
|
||||||
|
return mContext.getString(
|
||||||
|
R.string.quick_settings_financed_disclosure_named_management,
|
||||||
|
organizationName);
|
||||||
|
} else {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_NAMED_MANAGEMENT,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_named_management,
|
||||||
|
organizationName),
|
||||||
|
organizationName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getManagedAndPersonalProfileFooterText(boolean hasWorkProfile,
|
||||||
|
boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled,
|
||||||
|
String vpnName, String vpnNameWorkProfile, CharSequence workProfileOrganizationName,
|
||||||
|
boolean isProfileOwnerOfOrganizationOwnedDevice, boolean isWorkProfileOn) {
|
||||||
|
if (hasCACerts || (hasCACertsInWorkProfile && isWorkProfileOn)) {
|
||||||
|
return getMonitoringText(
|
||||||
|
hasCACerts, hasCACertsInWorkProfile, workProfileOrganizationName,
|
||||||
|
isWorkProfileOn);
|
||||||
|
}
|
||||||
|
if (vpnName != null || (vpnNameWorkProfile != null && isWorkProfileOn)) {
|
||||||
|
return getVpnText(hasWorkProfile, vpnName, vpnNameWorkProfile, isWorkProfileOn);
|
||||||
|
}
|
||||||
|
if (hasWorkProfile && isNetworkLoggingEnabled && isWorkProfileOn) {
|
||||||
|
return getManagedProfileNetworkActivityText();
|
||||||
|
}
|
||||||
|
if (isProfileOwnerOfOrganizationOwnedDevice) {
|
||||||
|
return getMangedDeviceGeneralText(workProfileOrganizationName);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMonitoringText(boolean hasCACerts, boolean hasCACertsInWorkProfile,
|
||||||
|
CharSequence workProfileOrganizationName, boolean isWorkProfileOn) {
|
||||||
|
if (hasCACertsInWorkProfile && isWorkProfileOn) {
|
||||||
|
if (workProfileOrganizationName == null) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_WORK_PROFILE_MONITORING, mWorkProfileMonitoringStringSupplier);
|
||||||
|
}
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_NAMED_WORK_PROFILE_MONITORING,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_named_managed_profile_monitoring,
|
||||||
|
workProfileOrganizationName),
|
||||||
|
workProfileOrganizationName);
|
||||||
|
}
|
||||||
|
if (hasCACerts) {
|
||||||
|
return mContext.getString(R.string.quick_settings_disclosure_monitoring);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getVpnText(boolean hasWorkProfile, String vpnName, String vpnNameWorkProfile,
|
||||||
|
boolean isWorkProfileOn) {
|
||||||
|
if (vpnName != null && vpnNameWorkProfile != null) {
|
||||||
|
return mContext.getString(R.string.quick_settings_disclosure_vpns);
|
||||||
|
}
|
||||||
|
if (vpnNameWorkProfile != null && isWorkProfileOn) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_WORK_PROFILE_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_managed_profile_named_vpn,
|
||||||
|
vpnNameWorkProfile),
|
||||||
|
vpnNameWorkProfile);
|
||||||
|
}
|
||||||
|
if (vpnName != null) {
|
||||||
|
if (hasWorkProfile) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_PERSONAL_PROFILE_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.quick_settings_disclosure_personal_profile_named_vpn,
|
||||||
|
vpnName),
|
||||||
|
vpnName);
|
||||||
|
}
|
||||||
|
return mContext.getString(R.string.quick_settings_disclosure_named_vpn,
|
||||||
|
vpnName);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getManagedProfileNetworkActivityText() {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_MSG_WORK_PROFILE_NETWORK, mWorkProfileNetworkStringSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS);
|
||||||
|
dialog.dismiss();
|
||||||
|
// This dismisses the shade on opening the activity
|
||||||
|
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createDialog(Context quickSettingsContext, @Nullable View view) {
|
||||||
|
mShouldUseSettingsButton.set(false);
|
||||||
|
mBgHandler.post(() -> {
|
||||||
|
String settingsButtonText = getSettingsButton();
|
||||||
|
final View dialogView = createDialogView();
|
||||||
|
mMainHandler.post(() -> {
|
||||||
|
mDialog = new SystemUIDialog(quickSettingsContext, 0);
|
||||||
|
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
|
||||||
|
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, mShouldUseSettingsButton.get()
|
||||||
|
? settingsButtonText : getNegativeButton(), this);
|
||||||
|
|
||||||
|
mDialog.setView(dialogView);
|
||||||
|
if (view != null && view.isAggregatedVisible()) {
|
||||||
|
mDialogLaunchAnimator.showFromView(mDialog, view, new DialogCuj(
|
||||||
|
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG));
|
||||||
|
} else {
|
||||||
|
mDialog.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
Dialog getDialog() {
|
||||||
|
return mDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
View createDialogView() {
|
||||||
|
if (mSecurityController.isParentalControlsEnabled()) {
|
||||||
|
return createParentalControlsDialogView();
|
||||||
|
}
|
||||||
|
return createOrganizationDialogView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private View createOrganizationDialogView() {
|
||||||
|
final boolean isDeviceManaged = mSecurityController.isDeviceManaged();
|
||||||
|
final boolean hasWorkProfile = mSecurityController.hasWorkProfile();
|
||||||
|
final CharSequence deviceOwnerOrganization =
|
||||||
|
mSecurityController.getDeviceOwnerOrganizationName();
|
||||||
|
final boolean hasCACerts = mSecurityController.hasCACertInCurrentUser();
|
||||||
|
final boolean hasCACertsInWorkProfile = mSecurityController.hasCACertInWorkProfile();
|
||||||
|
final boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled();
|
||||||
|
final String vpnName = mSecurityController.getPrimaryVpnName();
|
||||||
|
final String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName();
|
||||||
|
|
||||||
|
View dialogView = LayoutInflater.from(mContext)
|
||||||
|
.inflate(R.layout.quick_settings_footer_dialog, null, false);
|
||||||
|
|
||||||
|
// device management section
|
||||||
|
TextView deviceManagementSubtitle =
|
||||||
|
dialogView.findViewById(R.id.device_management_subtitle);
|
||||||
|
deviceManagementSubtitle.setText(getManagementTitle(deviceOwnerOrganization));
|
||||||
|
|
||||||
|
CharSequence managementMessage = getManagementMessage(isDeviceManaged,
|
||||||
|
deviceOwnerOrganization);
|
||||||
|
if (managementMessage == null) {
|
||||||
|
dialogView.findViewById(R.id.device_management_disclosures).setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
dialogView.findViewById(R.id.device_management_disclosures).setVisibility(View.VISIBLE);
|
||||||
|
TextView deviceManagementWarning =
|
||||||
|
(TextView) dialogView.findViewById(R.id.device_management_warning);
|
||||||
|
deviceManagementWarning.setText(managementMessage);
|
||||||
|
mShouldUseSettingsButton.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ca certificate section
|
||||||
|
CharSequence caCertsMessage = getCaCertsMessage(isDeviceManaged, hasCACerts,
|
||||||
|
hasCACertsInWorkProfile);
|
||||||
|
if (caCertsMessage == null) {
|
||||||
|
dialogView.findViewById(R.id.ca_certs_disclosures).setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
dialogView.findViewById(R.id.ca_certs_disclosures).setVisibility(View.VISIBLE);
|
||||||
|
TextView caCertsWarning = (TextView) dialogView.findViewById(R.id.ca_certs_warning);
|
||||||
|
caCertsWarning.setText(caCertsMessage);
|
||||||
|
// Make "Open trusted credentials"-link clickable
|
||||||
|
caCertsWarning.setMovementMethod(new LinkMovementMethod());
|
||||||
|
|
||||||
|
TextView caCertsSubtitle = (TextView) dialogView.findViewById(R.id.ca_certs_subtitle);
|
||||||
|
String caCertsSubtitleMessage = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MONITORING_CA_CERT_SUBTITLE, mMonitoringSubtitleCaCertStringSupplier);
|
||||||
|
caCertsSubtitle.setText(caCertsSubtitleMessage);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// network logging section
|
||||||
|
CharSequence networkLoggingMessage = getNetworkLoggingMessage(isDeviceManaged,
|
||||||
|
isNetworkLoggingEnabled);
|
||||||
|
if (networkLoggingMessage == null) {
|
||||||
|
dialogView.findViewById(R.id.network_logging_disclosures).setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
dialogView.findViewById(R.id.network_logging_disclosures).setVisibility(View.VISIBLE);
|
||||||
|
TextView networkLoggingWarning =
|
||||||
|
(TextView) dialogView.findViewById(R.id.network_logging_warning);
|
||||||
|
networkLoggingWarning.setText(networkLoggingMessage);
|
||||||
|
|
||||||
|
TextView networkLoggingSubtitle = (TextView) dialogView.findViewById(
|
||||||
|
R.id.network_logging_subtitle);
|
||||||
|
String networkLoggingSubtitleMessage = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MONITORING_NETWORK_SUBTITLE,
|
||||||
|
mMonitoringSubtitleNetworkStringSupplier);
|
||||||
|
networkLoggingSubtitle.setText(networkLoggingSubtitleMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vpn section
|
||||||
|
CharSequence vpnMessage = getVpnMessage(isDeviceManaged, hasWorkProfile, vpnName,
|
||||||
|
vpnNameWorkProfile);
|
||||||
|
if (vpnMessage == null) {
|
||||||
|
dialogView.findViewById(R.id.vpn_disclosures).setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
dialogView.findViewById(R.id.vpn_disclosures).setVisibility(View.VISIBLE);
|
||||||
|
TextView vpnWarning = (TextView) dialogView.findViewById(R.id.vpn_warning);
|
||||||
|
vpnWarning.setText(vpnMessage);
|
||||||
|
// Make "Open VPN Settings"-link clickable
|
||||||
|
vpnWarning.setMovementMethod(new LinkMovementMethod());
|
||||||
|
|
||||||
|
TextView vpnSubtitle = (TextView) dialogView.findViewById(R.id.vpn_subtitle);
|
||||||
|
String vpnSubtitleMessage = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MONITORING_VPN_SUBTITLE, mMonitoringSubtitleVpnStringSupplier);
|
||||||
|
vpnSubtitle.setText(vpnSubtitleMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: if a new section is added, should update configSubtitleVisibility to include
|
||||||
|
// the handling of the subtitle
|
||||||
|
configSubtitleVisibility(managementMessage != null,
|
||||||
|
caCertsMessage != null,
|
||||||
|
networkLoggingMessage != null,
|
||||||
|
vpnMessage != null,
|
||||||
|
dialogView);
|
||||||
|
|
||||||
|
return dialogView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private View createParentalControlsDialogView() {
|
||||||
|
View dialogView = LayoutInflater.from(mContext)
|
||||||
|
.inflate(R.layout.quick_settings_footer_dialog_parental_controls, null, false);
|
||||||
|
|
||||||
|
DeviceAdminInfo info = mSecurityController.getDeviceAdminInfo();
|
||||||
|
Drawable icon = mSecurityController.getIcon(info);
|
||||||
|
if (icon != null) {
|
||||||
|
ImageView imageView = (ImageView) dialogView.findViewById(R.id.parental_controls_icon);
|
||||||
|
imageView.setImageDrawable(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextView parentalControlsTitle =
|
||||||
|
(TextView) dialogView.findViewById(R.id.parental_controls_title);
|
||||||
|
parentalControlsTitle.setText(mSecurityController.getLabel(info));
|
||||||
|
|
||||||
|
return dialogView;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void configSubtitleVisibility(boolean showDeviceManagement, boolean showCaCerts,
|
||||||
|
boolean showNetworkLogging, boolean showVpn, View dialogView) {
|
||||||
|
// Device Management title should always been shown
|
||||||
|
// When there is a Device Management message, all subtitles should be shown
|
||||||
|
if (showDeviceManagement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Hide the subtitle if there is only 1 message shown
|
||||||
|
int mSectionCountExcludingDeviceMgt = 0;
|
||||||
|
if (showCaCerts) {
|
||||||
|
mSectionCountExcludingDeviceMgt++;
|
||||||
|
}
|
||||||
|
if (showNetworkLogging) {
|
||||||
|
mSectionCountExcludingDeviceMgt++;
|
||||||
|
}
|
||||||
|
if (showVpn) {
|
||||||
|
mSectionCountExcludingDeviceMgt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No work needed if there is no sections or more than 1 section
|
||||||
|
if (mSectionCountExcludingDeviceMgt != 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (showCaCerts) {
|
||||||
|
dialogView.findViewById(R.id.ca_certs_subtitle).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (showNetworkLogging) {
|
||||||
|
dialogView.findViewById(R.id.network_logging_subtitle).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (showVpn) {
|
||||||
|
dialogView.findViewById(R.id.vpn_subtitle).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not be called on the main thread to avoid making an IPC.
|
||||||
|
@VisibleForTesting
|
||||||
|
String getSettingsButton() {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_VIEW_POLICIES, mViewPoliciesButtonStringSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPositiveButton() {
|
||||||
|
return mContext.getString(R.string.ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private String getNegativeButton() {
|
||||||
|
if (mSecurityController.isParentalControlsEnabled()) {
|
||||||
|
return mContext.getString(R.string.monitoring_button_view_controls);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected CharSequence getManagementMessage(boolean isDeviceManaged,
|
||||||
|
CharSequence organizationName) {
|
||||||
|
if (!isDeviceManaged) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (organizationName != null) {
|
||||||
|
if (isFinancedDevice()) {
|
||||||
|
return mContext.getString(R.string.monitoring_financed_description_named_management,
|
||||||
|
organizationName, organizationName);
|
||||||
|
} else {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_NAMED_MANAGEMENT,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.monitoring_description_named_management,
|
||||||
|
organizationName),
|
||||||
|
organizationName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mDpm.getResources().getString(QS_DIALOG_MANAGEMENT, mManagementDialogStringSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected CharSequence getCaCertsMessage(boolean isDeviceManaged, boolean hasCACerts,
|
||||||
|
boolean hasCACertsInWorkProfile) {
|
||||||
|
if (!(hasCACerts || hasCACertsInWorkProfile)) return null;
|
||||||
|
if (isDeviceManaged) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MANAGEMENT_CA_CERT, mManagementDialogCaCertStringSupplier);
|
||||||
|
}
|
||||||
|
if (hasCACertsInWorkProfile) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_WORK_PROFILE_CA_CERT, mWorkProfileDialogCaCertStringSupplier);
|
||||||
|
}
|
||||||
|
return mContext.getString(R.string.monitoring_description_ca_certificate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected CharSequence getNetworkLoggingMessage(boolean isDeviceManaged,
|
||||||
|
boolean isNetworkLoggingEnabled) {
|
||||||
|
if (!isNetworkLoggingEnabled) return null;
|
||||||
|
if (isDeviceManaged) {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MANAGEMENT_NETWORK, mManagementDialogNetworkStringSupplier);
|
||||||
|
} else {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_WORK_PROFILE_NETWORK, mWorkProfileDialogNetworkStringSupplier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected CharSequence getVpnMessage(boolean isDeviceManaged, boolean hasWorkProfile,
|
||||||
|
String vpnName, String vpnNameWorkProfile) {
|
||||||
|
if (vpnName == null && vpnNameWorkProfile == null) return null;
|
||||||
|
final SpannableStringBuilder message = new SpannableStringBuilder();
|
||||||
|
if (isDeviceManaged) {
|
||||||
|
if (vpnName != null && vpnNameWorkProfile != null) {
|
||||||
|
String namedVpns = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MANAGEMENT_TWO_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.monitoring_description_two_named_vpns,
|
||||||
|
vpnName, vpnNameWorkProfile),
|
||||||
|
vpnName, vpnNameWorkProfile);
|
||||||
|
message.append(namedVpns);
|
||||||
|
} else {
|
||||||
|
String name = vpnName != null ? vpnName : vpnNameWorkProfile;
|
||||||
|
String namedVp = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MANAGEMENT_NAMED_VPN,
|
||||||
|
() -> mContext.getString(R.string.monitoring_description_named_vpn, name),
|
||||||
|
name);
|
||||||
|
message.append(namedVp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vpnName != null && vpnNameWorkProfile != null) {
|
||||||
|
String namedVpns = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MANAGEMENT_TWO_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.monitoring_description_two_named_vpns,
|
||||||
|
vpnName, vpnNameWorkProfile),
|
||||||
|
vpnName, vpnNameWorkProfile);
|
||||||
|
message.append(namedVpns);
|
||||||
|
} else if (vpnNameWorkProfile != null) {
|
||||||
|
String namedVpn = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_WORK_PROFILE_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.monitoring_description_managed_profile_named_vpn,
|
||||||
|
vpnNameWorkProfile),
|
||||||
|
vpnNameWorkProfile);
|
||||||
|
message.append(namedVpn);
|
||||||
|
} else if (hasWorkProfile) {
|
||||||
|
String namedVpn = mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_PERSONAL_PROFILE_NAMED_VPN,
|
||||||
|
() -> mContext.getString(
|
||||||
|
R.string.monitoring_description_personal_profile_named_vpn,
|
||||||
|
vpnName),
|
||||||
|
vpnName);
|
||||||
|
message.append(namedVpn);
|
||||||
|
} else {
|
||||||
|
message.append(mContext.getString(R.string.monitoring_description_named_vpn,
|
||||||
|
vpnName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message.append(mContext.getString(R.string.monitoring_description_vpn_settings_separator));
|
||||||
|
message.append(mContext.getString(R.string.monitoring_description_vpn_settings),
|
||||||
|
new VpnSpan(), 0);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
CharSequence getManagementTitle(CharSequence deviceOwnerOrganization) {
|
||||||
|
if (deviceOwnerOrganization != null && isFinancedDevice()) {
|
||||||
|
return mContext.getString(R.string.monitoring_title_financed_device,
|
||||||
|
deviceOwnerOrganization);
|
||||||
|
} else {
|
||||||
|
return mDpm.getResources().getString(
|
||||||
|
QS_DIALOG_MANAGEMENT_TITLE,
|
||||||
|
mManagementTitleSupplier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFinancedDevice() {
|
||||||
|
return mSecurityController.isDeviceManaged()
|
||||||
|
&& mSecurityController.getDeviceOwnerType(
|
||||||
|
mSecurityController.getDeviceOwnerComponentOnAnyUser())
|
||||||
|
== DEVICE_OWNER_TYPE_FINANCED;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class VpnSpan extends ClickableSpan {
|
||||||
|
@Override
|
||||||
|
public void onClick(View widget) {
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
|
||||||
|
mDialog.dismiss();
|
||||||
|
// This dismisses the shade on opening the activity
|
||||||
|
mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for testing, to compare two CharSequences containing VpnSpans
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
return object instanceof VpnSpan;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 314159257; // prime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,6 +100,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
private TextView mFooterText;
|
private TextView mFooterText;
|
||||||
private TestableImageView mPrimaryFooterIcon;
|
private TestableImageView mPrimaryFooterIcon;
|
||||||
private QSSecurityFooter mFooter;
|
private QSSecurityFooter mFooter;
|
||||||
|
private QSSecurityFooterUtils mFooterUtils;
|
||||||
@Mock
|
@Mock
|
||||||
private SecurityController mSecurityController;
|
private SecurityController mSecurityController;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -118,13 +119,15 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mTestableLooper = TestableLooper.get(this);
|
mTestableLooper = TestableLooper.get(this);
|
||||||
Looper looper = mTestableLooper.getLooper();
|
Looper looper = mTestableLooper.getLooper();
|
||||||
|
Handler mainHandler = new Handler(looper);
|
||||||
when(mUserTracker.getUserInfo()).thenReturn(mock(UserInfo.class));
|
when(mUserTracker.getUserInfo()).thenReturn(mock(UserInfo.class));
|
||||||
mRootView = (ViewGroup) new LayoutInflaterBuilder(mContext)
|
mRootView = (ViewGroup) new LayoutInflaterBuilder(mContext)
|
||||||
.replace("ImageView", TestableImageView.class)
|
.replace("ImageView", TestableImageView.class)
|
||||||
.build().inflate(R.layout.quick_settings_security_footer, null, false);
|
.build().inflate(R.layout.quick_settings_security_footer, null, false);
|
||||||
mFooter = new QSSecurityFooter(mRootView, mUserTracker, new Handler(looper),
|
mFooterUtils = new QSSecurityFooterUtils(getContext(), mUserTracker, mainHandler,
|
||||||
mActivityStarter, mSecurityController, mDialogLaunchAnimator, looper,
|
mActivityStarter, mSecurityController, looper, mDialogLaunchAnimator);
|
||||||
mBroadcastDispatcher);
|
mFooter = new QSSecurityFooter(mRootView, mainHandler, mSecurityController, looper,
|
||||||
|
mBroadcastDispatcher, mFooterUtils);
|
||||||
mFooterText = mRootView.findViewById(R.id.footer_text);
|
mFooterText = mRootView.findViewById(R.id.footer_text);
|
||||||
mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
|
mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
|
||||||
|
|
||||||
@@ -520,7 +523,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
when(mSecurityController.isDeviceManaged()).thenReturn(true);
|
when(mSecurityController.isDeviceManaged()).thenReturn(true);
|
||||||
|
|
||||||
assertEquals(mContext.getString(R.string.monitoring_title_device_owned),
|
assertEquals(mContext.getString(R.string.monitoring_title_device_owned),
|
||||||
mFooter.getManagementTitle(MANAGING_ORGANIZATION));
|
mFooterUtils.getManagementTitle(MANAGING_ORGANIZATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -531,12 +534,12 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
|
|
||||||
assertEquals(mContext.getString(R.string.monitoring_title_financed_device,
|
assertEquals(mContext.getString(R.string.monitoring_title_financed_device,
|
||||||
MANAGING_ORGANIZATION),
|
MANAGING_ORGANIZATION),
|
||||||
mFooter.getManagementTitle(MANAGING_ORGANIZATION));
|
mFooterUtils.getManagementTitle(MANAGING_ORGANIZATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetManagementMessage_noManagement() {
|
public void testGetManagementMessage_noManagement() {
|
||||||
assertEquals(null, mFooter.getManagementMessage(
|
assertEquals(null, mFooterUtils.getManagementMessage(
|
||||||
/* isDeviceManaged= */ false, MANAGING_ORGANIZATION));
|
/* isDeviceManaged= */ false, MANAGING_ORGANIZATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,10 +547,10 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
public void testGetManagementMessage_deviceOwner() {
|
public void testGetManagementMessage_deviceOwner() {
|
||||||
assertEquals(mContext.getString(R.string.monitoring_description_named_management,
|
assertEquals(mContext.getString(R.string.monitoring_description_named_management,
|
||||||
MANAGING_ORGANIZATION),
|
MANAGING_ORGANIZATION),
|
||||||
mFooter.getManagementMessage(
|
mFooterUtils.getManagementMessage(
|
||||||
/* isDeviceManaged= */ true, MANAGING_ORGANIZATION));
|
/* isDeviceManaged= */ true, MANAGING_ORGANIZATION));
|
||||||
assertEquals(mContext.getString(R.string.monitoring_description_management),
|
assertEquals(mContext.getString(R.string.monitoring_description_management),
|
||||||
mFooter.getManagementMessage(
|
mFooterUtils.getManagementMessage(
|
||||||
/* isDeviceManaged= */ true,
|
/* isDeviceManaged= */ true,
|
||||||
/* organizationName= */ null));
|
/* organizationName= */ null));
|
||||||
}
|
}
|
||||||
@@ -560,68 +563,68 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
|
|
||||||
assertEquals(mContext.getString(R.string.monitoring_financed_description_named_management,
|
assertEquals(mContext.getString(R.string.monitoring_financed_description_named_management,
|
||||||
MANAGING_ORGANIZATION, MANAGING_ORGANIZATION),
|
MANAGING_ORGANIZATION, MANAGING_ORGANIZATION),
|
||||||
mFooter.getManagementMessage(
|
mFooterUtils.getManagementMessage(
|
||||||
/* isDeviceManaged= */ true, MANAGING_ORGANIZATION));
|
/* isDeviceManaged= */ true, MANAGING_ORGANIZATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetCaCertsMessage() {
|
public void testGetCaCertsMessage() {
|
||||||
assertEquals(null, mFooter.getCaCertsMessage(true, false, false));
|
assertEquals(null, mFooterUtils.getCaCertsMessage(true, false, false));
|
||||||
assertEquals(null, mFooter.getCaCertsMessage(false, false, false));
|
assertEquals(null, mFooterUtils.getCaCertsMessage(false, false, false));
|
||||||
assertEquals(mContext.getString(R.string.monitoring_description_management_ca_certificate),
|
assertEquals(mContext.getString(R.string.monitoring_description_management_ca_certificate),
|
||||||
mFooter.getCaCertsMessage(true, true, true));
|
mFooterUtils.getCaCertsMessage(true, true, true));
|
||||||
assertEquals(mContext.getString(R.string.monitoring_description_management_ca_certificate),
|
assertEquals(mContext.getString(R.string.monitoring_description_management_ca_certificate),
|
||||||
mFooter.getCaCertsMessage(true, false, true));
|
mFooterUtils.getCaCertsMessage(true, false, true));
|
||||||
assertEquals(mContext.getString(
|
assertEquals(mContext.getString(
|
||||||
R.string.monitoring_description_managed_profile_ca_certificate),
|
R.string.monitoring_description_managed_profile_ca_certificate),
|
||||||
mFooter.getCaCertsMessage(false, false, true));
|
mFooterUtils.getCaCertsMessage(false, false, true));
|
||||||
assertEquals(mContext.getString(
|
assertEquals(mContext.getString(
|
||||||
R.string.monitoring_description_ca_certificate),
|
R.string.monitoring_description_ca_certificate),
|
||||||
mFooter.getCaCertsMessage(false, true, false));
|
mFooterUtils.getCaCertsMessage(false, true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetNetworkLoggingMessage() {
|
public void testGetNetworkLoggingMessage() {
|
||||||
// Test network logging message on a device with a device owner.
|
// Test network logging message on a device with a device owner.
|
||||||
// Network traffic may be monitored on the device.
|
// Network traffic may be monitored on the device.
|
||||||
assertEquals(null, mFooter.getNetworkLoggingMessage(true, false));
|
assertEquals(null, mFooterUtils.getNetworkLoggingMessage(true, false));
|
||||||
assertEquals(mContext.getString(R.string.monitoring_description_management_network_logging),
|
assertEquals(mContext.getString(R.string.monitoring_description_management_network_logging),
|
||||||
mFooter.getNetworkLoggingMessage(true, true));
|
mFooterUtils.getNetworkLoggingMessage(true, true));
|
||||||
|
|
||||||
// Test network logging message on a device with a managed profile owner
|
// Test network logging message on a device with a managed profile owner
|
||||||
// Network traffic may be monitored on the work profile.
|
// Network traffic may be monitored on the work profile.
|
||||||
assertEquals(null, mFooter.getNetworkLoggingMessage(false, false));
|
assertEquals(null, mFooterUtils.getNetworkLoggingMessage(false, false));
|
||||||
assertEquals(
|
assertEquals(
|
||||||
mContext.getString(R.string.monitoring_description_managed_profile_network_logging),
|
mContext.getString(R.string.monitoring_description_managed_profile_network_logging),
|
||||||
mFooter.getNetworkLoggingMessage(false, true));
|
mFooterUtils.getNetworkLoggingMessage(false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetVpnMessage() {
|
public void testGetVpnMessage() {
|
||||||
assertEquals(null, mFooter.getVpnMessage(true, true, null, null));
|
assertEquals(null, mFooterUtils.getVpnMessage(true, true, null, null));
|
||||||
assertEquals(addLink(mContext.getString(R.string.monitoring_description_two_named_vpns,
|
assertEquals(addLink(mContext.getString(R.string.monitoring_description_two_named_vpns,
|
||||||
VPN_PACKAGE, VPN_PACKAGE_2)),
|
VPN_PACKAGE, VPN_PACKAGE_2)),
|
||||||
mFooter.getVpnMessage(true, true, VPN_PACKAGE, VPN_PACKAGE_2));
|
mFooterUtils.getVpnMessage(true, true, VPN_PACKAGE, VPN_PACKAGE_2));
|
||||||
assertEquals(addLink(mContext.getString(R.string.monitoring_description_two_named_vpns,
|
assertEquals(addLink(mContext.getString(R.string.monitoring_description_two_named_vpns,
|
||||||
VPN_PACKAGE, VPN_PACKAGE_2)),
|
VPN_PACKAGE, VPN_PACKAGE_2)),
|
||||||
mFooter.getVpnMessage(false, true, VPN_PACKAGE, VPN_PACKAGE_2));
|
mFooterUtils.getVpnMessage(false, true, VPN_PACKAGE, VPN_PACKAGE_2));
|
||||||
assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
|
assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
|
||||||
VPN_PACKAGE)),
|
VPN_PACKAGE)),
|
||||||
mFooter.getVpnMessage(true, false, VPN_PACKAGE, null));
|
mFooterUtils.getVpnMessage(true, false, VPN_PACKAGE, null));
|
||||||
assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
|
assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
|
||||||
VPN_PACKAGE)),
|
VPN_PACKAGE)),
|
||||||
mFooter.getVpnMessage(false, false, VPN_PACKAGE, null));
|
mFooterUtils.getVpnMessage(false, false, VPN_PACKAGE, null));
|
||||||
assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
|
assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
|
||||||
VPN_PACKAGE_2)),
|
VPN_PACKAGE_2)),
|
||||||
mFooter.getVpnMessage(true, true, null, VPN_PACKAGE_2));
|
mFooterUtils.getVpnMessage(true, true, null, VPN_PACKAGE_2));
|
||||||
assertEquals(addLink(mContext.getString(
|
assertEquals(addLink(mContext.getString(
|
||||||
R.string.monitoring_description_managed_profile_named_vpn,
|
R.string.monitoring_description_managed_profile_named_vpn,
|
||||||
VPN_PACKAGE_2)),
|
VPN_PACKAGE_2)),
|
||||||
mFooter.getVpnMessage(false, true, null, VPN_PACKAGE_2));
|
mFooterUtils.getVpnMessage(false, true, null, VPN_PACKAGE_2));
|
||||||
assertEquals(addLink(mContext.getString(
|
assertEquals(addLink(mContext.getString(
|
||||||
R.string.monitoring_description_personal_profile_named_vpn,
|
R.string.monitoring_description_personal_profile_named_vpn,
|
||||||
VPN_PACKAGE)),
|
VPN_PACKAGE)),
|
||||||
mFooter.getVpnMessage(false, true, VPN_PACKAGE, null));
|
mFooterUtils.getVpnMessage(false, true, VPN_PACKAGE, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -631,19 +634,19 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
|
|
||||||
// Device Management subtitle should be shown when there is Device Management section only
|
// Device Management subtitle should be shown when there is Device Management section only
|
||||||
// Other sections visibility will be set somewhere else so it will not be tested here
|
// Other sections visibility will be set somewhere else so it will not be tested here
|
||||||
mFooter.configSubtitleVisibility(true, false, false, false, view);
|
mFooterUtils.configSubtitleVisibility(true, false, false, false, view);
|
||||||
assertEquals(View.VISIBLE,
|
assertEquals(View.VISIBLE,
|
||||||
view.findViewById(R.id.device_management_subtitle).getVisibility());
|
view.findViewById(R.id.device_management_subtitle).getVisibility());
|
||||||
|
|
||||||
// If there are multiple sections, all subtitles should be shown
|
// If there are multiple sections, all subtitles should be shown
|
||||||
mFooter.configSubtitleVisibility(true, true, false, false, view);
|
mFooterUtils.configSubtitleVisibility(true, true, false, false, view);
|
||||||
assertEquals(View.VISIBLE,
|
assertEquals(View.VISIBLE,
|
||||||
view.findViewById(R.id.device_management_subtitle).getVisibility());
|
view.findViewById(R.id.device_management_subtitle).getVisibility());
|
||||||
assertEquals(View.VISIBLE,
|
assertEquals(View.VISIBLE,
|
||||||
view.findViewById(R.id.ca_certs_subtitle).getVisibility());
|
view.findViewById(R.id.ca_certs_subtitle).getVisibility());
|
||||||
|
|
||||||
// If there are multiple sections, all subtitles should be shown
|
// If there are multiple sections, all subtitles should be shown
|
||||||
mFooter.configSubtitleVisibility(true, true, true, true, view);
|
mFooterUtils.configSubtitleVisibility(true, true, true, true, view);
|
||||||
assertEquals(View.VISIBLE,
|
assertEquals(View.VISIBLE,
|
||||||
view.findViewById(R.id.device_management_subtitle).getVisibility());
|
view.findViewById(R.id.device_management_subtitle).getVisibility());
|
||||||
assertEquals(View.VISIBLE,
|
assertEquals(View.VISIBLE,
|
||||||
@@ -655,7 +658,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
|
|
||||||
// If there are multiple sections, all subtitles should be shown, event if there is no
|
// If there are multiple sections, all subtitles should be shown, event if there is no
|
||||||
// Device Management section
|
// Device Management section
|
||||||
mFooter.configSubtitleVisibility(false, true, true, true, view);
|
mFooterUtils.configSubtitleVisibility(false, true, true, true, view);
|
||||||
assertEquals(View.VISIBLE,
|
assertEquals(View.VISIBLE,
|
||||||
view.findViewById(R.id.ca_certs_subtitle).getVisibility());
|
view.findViewById(R.id.ca_certs_subtitle).getVisibility());
|
||||||
assertEquals(View.VISIBLE,
|
assertEquals(View.VISIBLE,
|
||||||
@@ -664,13 +667,13 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
view.findViewById(R.id.vpn_subtitle).getVisibility());
|
view.findViewById(R.id.vpn_subtitle).getVisibility());
|
||||||
|
|
||||||
// If there is only 1 section, the title should be hidden
|
// If there is only 1 section, the title should be hidden
|
||||||
mFooter.configSubtitleVisibility(false, true, false, false, view);
|
mFooterUtils.configSubtitleVisibility(false, true, false, false, view);
|
||||||
assertEquals(View.GONE,
|
assertEquals(View.GONE,
|
||||||
view.findViewById(R.id.ca_certs_subtitle).getVisibility());
|
view.findViewById(R.id.ca_certs_subtitle).getVisibility());
|
||||||
mFooter.configSubtitleVisibility(false, false, true, false, view);
|
mFooterUtils.configSubtitleVisibility(false, false, true, false, view);
|
||||||
assertEquals(View.GONE,
|
assertEquals(View.GONE,
|
||||||
view.findViewById(R.id.network_logging_subtitle).getVisibility());
|
view.findViewById(R.id.network_logging_subtitle).getVisibility());
|
||||||
mFooter.configSubtitleVisibility(false, false, false, true, view);
|
mFooterUtils.configSubtitleVisibility(false, false, false, true, view);
|
||||||
assertEquals(View.GONE,
|
assertEquals(View.GONE,
|
||||||
view.findViewById(R.id.vpn_subtitle).getVisibility());
|
view.findViewById(R.id.vpn_subtitle).getVisibility());
|
||||||
}
|
}
|
||||||
@@ -722,7 +725,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
when(mSecurityController.isParentalControlsEnabled()).thenReturn(true);
|
when(mSecurityController.isParentalControlsEnabled()).thenReturn(true);
|
||||||
when(mSecurityController.getLabel(any())).thenReturn(PARENTAL_CONTROLS_LABEL);
|
when(mSecurityController.getLabel(any())).thenReturn(PARENTAL_CONTROLS_LABEL);
|
||||||
|
|
||||||
View view = mFooter.createDialogView();
|
View view = mFooterUtils.createDialogView();
|
||||||
TextView textView = (TextView) view.findViewById(R.id.parental_controls_title);
|
TextView textView = (TextView) view.findViewById(R.id.parental_controls_title);
|
||||||
assertEquals(PARENTAL_CONTROLS_LABEL, textView.getText());
|
assertEquals(PARENTAL_CONTROLS_LABEL, textView.getText());
|
||||||
}
|
}
|
||||||
@@ -745,7 +748,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
|
when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
|
||||||
.thenReturn(DEVICE_OWNER_TYPE_FINANCED);
|
.thenReturn(DEVICE_OWNER_TYPE_FINANCED);
|
||||||
|
|
||||||
View view = mFooter.createDialogView();
|
View view = mFooterUtils.createDialogView();
|
||||||
|
|
||||||
TextView managementSubtitle = view.findViewById(R.id.device_management_subtitle);
|
TextView managementSubtitle = view.findViewById(R.id.device_management_subtitle);
|
||||||
assertEquals(View.VISIBLE, managementSubtitle.getVisibility());
|
assertEquals(View.VISIBLE, managementSubtitle.getVisibility());
|
||||||
@@ -756,7 +759,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
assertEquals(mContext.getString(R.string.monitoring_financed_description_named_management,
|
assertEquals(mContext.getString(R.string.monitoring_financed_description_named_management,
|
||||||
MANAGING_ORGANIZATION, MANAGING_ORGANIZATION), managementMessage.getText());
|
MANAGING_ORGANIZATION, MANAGING_ORGANIZATION), managementMessage.getText());
|
||||||
assertEquals(mContext.getString(R.string.monitoring_button_view_policies),
|
assertEquals(mContext.getString(R.string.monitoring_button_view_policies),
|
||||||
mFooter.getSettingsButton());
|
mFooterUtils.getSettingsButton());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -776,7 +779,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
AlertDialog dialog = dialogCaptor.getValue();
|
AlertDialog dialog = dialogCaptor.getValue();
|
||||||
dialog.create();
|
dialog.create();
|
||||||
|
|
||||||
assertEquals(mFooter.getSettingsButton(),
|
assertEquals(mFooterUtils.getSettingsButton(),
|
||||||
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getText());
|
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getText());
|
||||||
|
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
@@ -819,8 +822,8 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG));
|
new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG));
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
assertTrue(mFooter.getDialog().isShowing());
|
assertTrue(mFooterUtils.getDialog().isShowing());
|
||||||
mFooter.getDialog().dismiss();
|
mFooterUtils.getDialog().dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharSequence addLink(CharSequence description) {
|
private CharSequence addLink(CharSequence description) {
|
||||||
@@ -828,7 +831,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
message.append(description);
|
message.append(description);
|
||||||
message.append(mContext.getString(R.string.monitoring_description_vpn_settings_separator));
|
message.append(mContext.getString(R.string.monitoring_description_vpn_settings_separator));
|
||||||
message.append(mContext.getString(R.string.monitoring_description_vpn_settings),
|
message.append(mContext.getString(R.string.monitoring_description_vpn_settings),
|
||||||
mFooter.new VpnSpan(), 0);
|
mFooterUtils.new VpnSpan(), 0);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user