diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java index c8033fafbc4eb..944a7cb01cec5 100644 --- a/core/java/android/app/admin/DevicePolicyResources.java +++ b/core/java/android/app/admin/DevicePolicyResources.java @@ -1492,6 +1492,45 @@ public final class DevicePolicyResources { * Content description for the work profile lock screen. */ public static final String WORK_LOCK_ACCESSIBILITY = PREFIX + "WORK_LOCK_ACCESSIBILITY"; + + /** + * Notification text displayed when screenshots are blocked by an IT admin. + */ + public static final String SCREENSHOT_BLOCKED_BY_ADMIN = + PREFIX + "SCREENSHOT_BLOCKED_BY_ADMIN"; + + /** + * Message shown when user is almost at the limit of password attempts where the + * profile will be removed. Accepts number of failed attempts and remaining failed + * attempts as params. + */ + public static final String KEYGUARD_DIALOG_FAILED_ATTEMPTS_ALMOST_ERASING_PROFILE = + PREFIX + "KEYGUARD_DIALOG_FAILED_ATTEMPTS_ALMOST_ERASING_PROFILE"; + + /** + * Message shown in dialog when user has exceeded the maximum attempts and the profile + * will be removed. Accepts number of failed attempts as a param. + */ + public static final String KEYGUARD_DIALOG_FAILED_ATTEMPTS_ERASING_PROFILE = + PREFIX + "KEYGUARD_DIALOG_FAILED_ATTEMPTS_ERASING_PROFILE"; + + /** + * Monitoring dialog subtitle for the section describing VPN. + */ + public static final String QS_DIALOG_MONITORING_VPN_SUBTITLE = + PREFIX + "QS_DIALOG_MONITORING_VPN_SUBTITLE"; + + /** + * Monitoring dialog subtitle for the section describing network logging. + */ + public static final String QS_DIALOG_MONITORING_NETWORK_SUBTITLE = + PREFIX + "QS_DIALOG_MONITORING_NETWORK_SUBTITLE"; + + /** + * Monitoring dialog subtitle for the section describing certificate authorities. + */ + public static final String QS_DIALOG_MONITORING_CA_CERT_SUBTITLE = + PREFIX + "QS_DIALOG_MONITORING_CA_CERT_SUBTITLE"; } /** diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index f8c0590a8d75e..cce516d981a51 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -15,6 +15,8 @@ */ package com.android.keyguard; +import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_DIALOG_FAILED_ATTEMPTS_ALMOST_ERASING_PROFILE; +import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_DIALOG_FAILED_ATTEMPTS_ERASING_PROFILE; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.systemBars; import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP; @@ -32,6 +34,7 @@ import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.app.Activity; import android.app.AlertDialog; +import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -676,7 +679,11 @@ public class KeyguardSecurityContainer extends FrameLayout { attempts, remaining); break; case USER_TYPE_WORK_PROFILE: - message = mContext.getString(R.string.kg_failed_attempts_almost_at_erase_profile, + message = mContext.getSystemService(DevicePolicyManager.class).getResources() + .getString(KEYGUARD_DIALOG_FAILED_ATTEMPTS_ALMOST_ERASING_PROFILE, + () -> mContext.getString( + R.string.kg_failed_attempts_almost_at_erase_profile, + attempts, remaining), attempts, remaining); break; } @@ -695,7 +702,10 @@ public class KeyguardSecurityContainer extends FrameLayout { attempts); break; case USER_TYPE_WORK_PROFILE: - message = mContext.getString(R.string.kg_failed_attempts_now_erasing_profile, + message = mContext.getSystemService(DevicePolicyManager.class).getResources() + .getString(KEYGUARD_DIALOG_FAILED_ATTEMPTS_ERASING_PROFILE, + () -> mContext.getString( + R.string.kg_failed_attempts_now_erasing_profile, attempts), attempts); break; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index dd99db49c1d27..584de6e8c28f5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -22,6 +22,9 @@ import static android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_DIALOG 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; @@ -92,6 +95,7 @@ import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.util.ViewController; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Named; @@ -106,7 +110,7 @@ class QSSecurityFooter extends ViewController private final TextView mFooterText; private final ImageView mPrimaryFooterIcon; - private final Context mContext; + private Context mContext; private final DevicePolicyManager mDpm; private final Callback mCallback = new Callback(); private final SecurityController mSecurityController; @@ -141,6 +145,63 @@ class QSSecurityFooter extends ViewController } }; + private Supplier mManagementTitleSupplier = () -> + mContext == null ? null : mContext.getString(R.string.monitoring_title_device_owned); + + private Supplier mManagementMessageSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.quick_settings_disclosure_management); + + private Supplier mManagementMonitoringStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.quick_settings_disclosure_management_monitoring); + + private Supplier mManagementMultipleVpnStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.quick_settings_disclosure_management_vpns); + + private Supplier mWorkProfileMonitoringStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.quick_settings_disclosure_managed_profile_monitoring); + + private Supplier mWorkProfileNetworkStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.quick_settings_disclosure_managed_profile_network_activity); + + private Supplier mMonitoringSubtitleCaCertStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.monitoring_subtitle_ca_certificate); + + private Supplier mMonitoringSubtitleNetworkStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.monitoring_subtitle_network_logging); + + private Supplier mMonitoringSubtitleVpnStringSupplier = () -> + mContext == null ? null : mContext.getString(R.string.monitoring_subtitle_vpn); + + private Supplier mViewPoliciesButtonStringSupplier = () -> + mContext == null ? null : mContext.getString(R.string.monitoring_button_view_policies); + + private Supplier mManagementDialogStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.monitoring_description_management); + + private Supplier mManagementDialogCaCertStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.monitoring_description_management_ca_certificate); + + private Supplier mWorkProfileDialogCaCertStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.monitoring_description_managed_profile_ca_certificate); + + private Supplier mManagementDialogNetworkStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.monitoring_description_management_network_logging); + + private Supplier mWorkProfileDialogNetworkStringSupplier = () -> + mContext == null ? null : mContext.getString( + R.string.monitoring_description_managed_profile_network_logging); + @Inject QSSecurityFooter(@Named(QS_SECURITY_FOOTER_VIEW) View rootView, UserTracker userTracker, @Main Handler mainHandler, @@ -337,9 +398,7 @@ class QSSecurityFooter extends ViewController private String getManagedDeviceMonitoringText(CharSequence organizationName) { if (organizationName == null) { return mDpm.getResources().getString( - QS_MSG_MANAGEMENT_MONITORING, - () -> mContext.getString( - R.string.quick_settings_disclosure_management_monitoring)); + QS_MSG_MANAGEMENT_MONITORING, mManagementMonitoringStringSupplier); } return mDpm.getResources().getString( QS_MSG_NAMED_MANAGEMENT_MONITORING, @@ -354,9 +413,7 @@ class QSSecurityFooter extends ViewController if (vpnName != null && vpnNameWorkProfile != null) { if (organizationName == null) { return mDpm.getResources().getString( - QS_MSG_MANAGEMENT_MULTIPLE_VPNS, - () -> mContext.getString( - R.string.quick_settings_disclosure_management_vpns)); + QS_MSG_MANAGEMENT_MULTIPLE_VPNS, mManagementMultipleVpnStringSupplier); } return mDpm.getResources().getString( QS_MSG_NAMED_MANAGEMENT_MULTIPLE_VPNS, @@ -386,10 +443,7 @@ class QSSecurityFooter extends ViewController private String getMangedDeviceGeneralText(CharSequence organizationName) { if (organizationName == null) { - return mDpm.getResources().getString( - QS_MSG_MANAGEMENT, - () -> mContext.getString( - R.string.quick_settings_disclosure_management)); + return mDpm.getResources().getString(QS_MSG_MANAGEMENT, mManagementMessageSupplier); } if (isFinancedDevice()) { return mContext.getString( @@ -431,9 +485,7 @@ class QSSecurityFooter extends ViewController if (hasCACertsInWorkProfile && isWorkProfileOn) { if (workProfileOrganizationName == null) { return mDpm.getResources().getString( - QS_MSG_WORK_PROFILE_MONITORING, - () -> mContext.getString( - R.string.quick_settings_disclosure_managed_profile_monitoring)); + QS_MSG_WORK_PROFILE_MONITORING, mWorkProfileMonitoringStringSupplier); } return mDpm.getResources().getString( QS_MSG_NAMED_WORK_PROFILE_MONITORING, @@ -478,10 +530,9 @@ class QSSecurityFooter extends ViewController private String getManagedProfileNetworkActivityText() { return mDpm.getResources().getString( - QS_MSG_WORK_PROFILE_NETWORK, - () -> mContext.getString( - R.string.quick_settings_disclosure_managed_profile_network_activity)); + QS_MSG_WORK_PROFILE_NETWORK, mWorkProfileNetworkStringSupplier); } + @Override public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_NEGATIVE) { @@ -569,6 +620,12 @@ class QSSecurityFooter extends ViewController 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 @@ -581,6 +638,13 @@ class QSSecurityFooter extends ViewController 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 @@ -594,6 +658,11 @@ class QSSecurityFooter extends ViewController 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 @@ -657,8 +726,7 @@ class QSSecurityFooter extends ViewController @VisibleForTesting String getSettingsButton() { return mDpm.getResources().getString( - QS_DIALOG_VIEW_POLICIES, - () -> mContext.getString(R.string.monitoring_button_view_policies)); + QS_DIALOG_VIEW_POLICIES, mViewPoliciesButtonStringSupplier); } private String getPositiveButton() { @@ -692,9 +760,7 @@ class QSSecurityFooter extends ViewController organizationName); } } - return mDpm.getResources().getString( - QS_DIALOG_MANAGEMENT, - () -> mContext.getString(R.string.monitoring_description_management)); + return mDpm.getResources().getString(QS_DIALOG_MANAGEMENT, mManagementDialogStringSupplier); } @Nullable @@ -703,15 +769,11 @@ class QSSecurityFooter extends ViewController if (!(hasCACerts || hasCACertsInWorkProfile)) return null; if (isDeviceManaged) { return mDpm.getResources().getString( - QS_DIALOG_MANAGEMENT_CA_CERT, - () -> mContext.getString( - R.string.monitoring_description_management_ca_certificate)); + QS_DIALOG_MANAGEMENT_CA_CERT, mManagementDialogCaCertStringSupplier); } if (hasCACertsInWorkProfile) { return mDpm.getResources().getString( - QS_DIALOG_WORK_PROFILE_CA_CERT, - () -> mContext.getString( - R.string.monitoring_description_managed_profile_ca_certificate)); + QS_DIALOG_WORK_PROFILE_CA_CERT, mWorkProfileDialogCaCertStringSupplier); } return mContext.getString(R.string.monitoring_description_ca_certificate); } @@ -722,14 +784,10 @@ class QSSecurityFooter extends ViewController if (!isNetworkLoggingEnabled) return null; if (isDeviceManaged) { return mDpm.getResources().getString( - QS_DIALOG_MANAGEMENT_NETWORK, - () -> mContext.getString( - R.string.monitoring_description_management_network_logging)); + QS_DIALOG_MANAGEMENT_NETWORK, mManagementDialogNetworkStringSupplier); } else { return mDpm.getResources().getString( - QS_DIALOG_WORK_PROFILE_NETWORK, - () -> mContext.getString( - R.string.monitoring_description_managed_profile_network_logging)); + QS_DIALOG_WORK_PROFILE_NETWORK, mWorkProfileDialogNetworkStringSupplier); } } @@ -799,7 +857,7 @@ class QSSecurityFooter extends ViewController } else { return mDpm.getResources().getString( QS_DIALOG_MANAGEMENT_TITLE, - () -> mContext.getString(R.string.monitoring_title_device_owned)); + mManagementTitleSupplier); } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index 7f3758e208dbf..2621f6da7afae 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -16,6 +16,7 @@ package com.android.systemui.screenshot; +import static android.app.admin.DevicePolicyResources.Strings.SystemUi.SCREENSHOT_BLOCKED_BY_ADMIN; import static android.content.Intent.ACTION_CLOSE_SYSTEM_DIALOGS; import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_PROCESS_COMPLETE; @@ -54,7 +55,9 @@ import androidx.annotation.NonNull; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ScreenshotHelper; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Background; +import java.util.concurrent.Executor; import java.util.function.Consumer; import javax.inject.Inject; @@ -70,6 +73,7 @@ public class TakeScreenshotService extends Service { private final ScreenshotNotificationsController mNotificationsController; private final Handler mHandler; private final Context mContext; + private final @Background Executor mBgExecutor; private final BroadcastReceiver mCloseSystemDialogs = new BroadcastReceiver() { @Override @@ -97,7 +101,8 @@ public class TakeScreenshotService extends Service { @Inject public TakeScreenshotService(ScreenshotController screenshotController, UserManager userManager, DevicePolicyManager devicePolicyManager, UiEventLogger uiEventLogger, - ScreenshotNotificationsController notificationsController, Context context) { + ScreenshotNotificationsController notificationsController, Context context, + @Background Executor bgExecutor) { if (DEBUG_SERVICE) { Log.d(TAG, "new " + this); } @@ -108,6 +113,7 @@ public class TakeScreenshotService extends Service { mUiEventLogger = uiEventLogger; mNotificationsController = notificationsController; mContext = context; + mBgExecutor = bgExecutor; } @Override @@ -189,12 +195,18 @@ public class TakeScreenshotService extends Service { requestCallback.reportError(); return true; } - if(mDevicePolicyManager.getScreenCaptureDisabled(null, UserHandle.USER_ALL)) { - Log.w(TAG, "Skipping screenshot because an IT admin has disabled " - + "screenshots on the device"); - Toast.makeText(mContext, R.string.screenshot_blocked_by_admin, - Toast.LENGTH_SHORT).show(); - requestCallback.reportError(); + + if (mDevicePolicyManager.getScreenCaptureDisabled(null, UserHandle.USER_ALL)) { + mBgExecutor.execute(() -> { + Log.w(TAG, "Skipping screenshot because an IT admin has disabled " + + "screenshots on the device"); + String blockedByAdminText = mDevicePolicyManager.getResources().getString( + SCREENSHOT_BLOCKED_BY_ADMIN, + () -> mContext.getString(R.string.screenshot_blocked_by_admin)); + mHandler.post(() -> + Toast.makeText(mContext, blockedByAdminText, Toast.LENGTH_SHORT).show()); + requestCallback.reportError(); + }); return true; }