| /* |
| * Copyright (C) 2022 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.settings.safetycenter; |
| |
| import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED; |
| |
| import android.app.PendingIntent; |
| import android.app.settings.SettingsEnums; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.os.UserHandle; |
| import android.os.UserManager; |
| import android.safetycenter.SafetyEvent; |
| import android.safetycenter.SafetySourceData; |
| import android.safetycenter.SafetySourceIssue; |
| import android.safetycenter.SafetySourceStatus; |
| import android.safetycenter.SafetySourceStatus.IconAction; |
| |
| import com.android.settings.R; |
| import com.android.settings.security.ScreenLockPreferenceDetailsUtils; |
| import com.android.settingslib.RestrictedLockUtils; |
| import com.android.settingslib.RestrictedLockUtilsInternal; |
| |
| /** Lock Screen Safety Source for Safety Center. */ |
| public final class LockScreenSafetySource { |
| |
| public static final String SAFETY_SOURCE_ID = "AndroidLockScreen"; |
| public static final String NO_SCREEN_LOCK_ISSUE_ID = "NoScreenLockIssue"; |
| public static final String NO_SCREEN_LOCK_ISSUE_TYPE_ID = "NoScreenLockIssueType"; |
| public static final String SET_SCREEN_LOCK_ACTION_ID = "SetScreenLockAction"; |
| |
| private static final int REQUEST_CODE_SCREEN_LOCK = 1; |
| private static final int REQUEST_CODE_SCREEN_LOCK_SETTINGS = 2; |
| |
| private LockScreenSafetySource() {} |
| |
| /** Sets lock screen safety data for Safety Center. */ |
| public static void setSafetySourceData( |
| Context context, |
| ScreenLockPreferenceDetailsUtils screenLockPreferenceDetailsUtils, |
| SafetyEvent safetyEvent) { |
| if (!SafetyCenterManagerWrapper.get().isEnabled(context)) { |
| return; |
| } |
| |
| UserManager userManager = context.getSystemService(UserManager.class); |
| if (userManager != null && userManager.isProfile()) { |
| return; // LockScreen source only supports primary profile. |
| } |
| |
| if (!screenLockPreferenceDetailsUtils.isAvailable()) { |
| SafetyCenterManagerWrapper.get() |
| .setSafetySourceData( |
| context, SAFETY_SOURCE_ID, /* safetySourceData= */ null, safetyEvent); |
| return; |
| } |
| |
| final int userId = UserHandle.myUserId(); |
| final RestrictedLockUtils.EnforcedAdmin admin = |
| RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(context, userId); |
| final PendingIntent pendingIntent = |
| createPendingIntent( |
| context, |
| screenLockPreferenceDetailsUtils.getLaunchChooseLockGenericFragmentIntent( |
| SettingsEnums.SAFETY_CENTER), |
| REQUEST_CODE_SCREEN_LOCK); |
| final IconAction gearMenuIconAction = |
| createGearMenuIconAction(context, screenLockPreferenceDetailsUtils); |
| final boolean lockScreenAllowedByAdmin = |
| !screenLockPreferenceDetailsUtils.isPasswordQualityManaged(userId, admin); |
| final boolean isLockPatternSecure = screenLockPreferenceDetailsUtils.isLockPatternSecure(); |
| final int severityLevel = |
| lockScreenAllowedByAdmin |
| ? isLockPatternSecure |
| ? SafetySourceData.SEVERITY_LEVEL_INFORMATION |
| : SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION |
| : SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED; |
| |
| final SafetySourceStatus status = |
| new SafetySourceStatus.Builder( |
| context.getString(R.string.unlock_set_unlock_launch_picker_title), |
| lockScreenAllowedByAdmin |
| ? screenLockPreferenceDetailsUtils.getSummary( |
| UserHandle.myUserId()) |
| : context.getString(R.string.disabled_by_policy_title), |
| severityLevel) |
| .setPendingIntent(lockScreenAllowedByAdmin ? pendingIntent : null) |
| .setEnabled(lockScreenAllowedByAdmin) |
| .setIconAction(lockScreenAllowedByAdmin ? gearMenuIconAction : null) |
| .build(); |
| final SafetySourceData.Builder safetySourceDataBuilder = |
| new SafetySourceData.Builder().setStatus(status); |
| if (lockScreenAllowedByAdmin && !isLockPatternSecure) { |
| safetySourceDataBuilder.addIssue(createNoScreenLockIssue(context, pendingIntent)); |
| } |
| final SafetySourceData safetySourceData = safetySourceDataBuilder.build(); |
| |
| SafetyCenterManagerWrapper.get() |
| .setSafetySourceData(context, SAFETY_SOURCE_ID, safetySourceData, safetyEvent); |
| } |
| |
| /** Notifies Safety Center of a change in lock screen settings. */ |
| public static void onLockScreenChange(Context context) { |
| setSafetySourceData( |
| context, |
| new ScreenLockPreferenceDetailsUtils(context), |
| new SafetyEvent.Builder(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()); |
| |
| // Also send refreshed safety center data for biometrics, since changing lockscreen settings |
| // can unset biometrics. |
| BiometricsSafetySource.onBiometricsChanged(context); |
| } |
| |
| private static IconAction createGearMenuIconAction( |
| Context context, ScreenLockPreferenceDetailsUtils screenLockPreferenceDetailsUtils) { |
| return screenLockPreferenceDetailsUtils.shouldShowGearMenu() |
| ? new IconAction( |
| IconAction.ICON_TYPE_GEAR, |
| createPendingIntent( |
| context, |
| screenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent( |
| SettingsEnums.SAFETY_CENTER), |
| REQUEST_CODE_SCREEN_LOCK_SETTINGS)) |
| : null; |
| } |
| |
| private static PendingIntent createPendingIntent( |
| Context context, Intent intent, int requestCode) { |
| return PendingIntent.getActivity( |
| context, requestCode, intent, PendingIntent.FLAG_IMMUTABLE); |
| } |
| |
| private static SafetySourceIssue createNoScreenLockIssue( |
| Context context, PendingIntent pendingIntent) { |
| final SafetySourceIssue.Action action = |
| new SafetySourceIssue.Action.Builder( |
| SET_SCREEN_LOCK_ACTION_ID, |
| context.getString(R.string.no_screen_lock_issue_action_label), |
| pendingIntent) |
| .build(); |
| // Custom notification deliberately has zero actions |
| final SafetySourceIssue.Notification customNotification = |
| new SafetySourceIssue.Notification.Builder( |
| context.getString(R.string.no_screen_lock_issue_notification_title), |
| context.getString(R.string.no_screen_lock_issue_notification_text)) |
| .build(); |
| return new SafetySourceIssue.Builder( |
| NO_SCREEN_LOCK_ISSUE_ID, |
| context.getString(R.string.no_screen_lock_issue_title), |
| context.getString(R.string.no_screen_lock_issue_summary), |
| SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION, |
| NO_SCREEN_LOCK_ISSUE_TYPE_ID) |
| .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE) |
| .addAction(action) |
| .setIssueActionability(SafetySourceIssue.ISSUE_ACTIONABILITY_MANUAL) |
| .setCustomNotification(customNotification) |
| .setNotificationBehavior(SafetySourceIssue.NOTIFICATION_BEHAVIOR_DELAYED) |
| .build(); |
| } |
| } |