1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.safetycenter; 18 19 import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED; 20 21 import android.app.PendingIntent; 22 import android.app.settings.SettingsEnums; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.os.UserHandle; 26 import android.safetycenter.SafetyEvent; 27 import android.safetycenter.SafetySourceData; 28 import android.safetycenter.SafetySourceIssue; 29 import android.safetycenter.SafetySourceStatus; 30 import android.safetycenter.SafetySourceStatus.IconAction; 31 32 import com.android.settings.R; 33 import com.android.settings.security.ScreenLockPreferenceDetailsUtils; 34 import com.android.settingslib.RestrictedLockUtils; 35 import com.android.settingslib.RestrictedLockUtilsInternal; 36 37 /** Lock Screen Safety Source for Safety Center. */ 38 public final class LockScreenSafetySource { 39 40 public static final String SAFETY_SOURCE_ID = "AndroidLockScreen"; 41 public static final String NO_SCREEN_LOCK_ISSUE_ID = "NoScreenLockIssue"; 42 public static final String NO_SCREEN_LOCK_ISSUE_TYPE_ID = "NoScreenLockIssueType"; 43 public static final String SET_SCREEN_LOCK_ACTION_ID = "SetScreenLockAction"; 44 45 private static final int REQUEST_CODE_SCREEN_LOCK = 1; 46 private static final int REQUEST_CODE_SCREEN_LOCK_SETTINGS = 2; 47 LockScreenSafetySource()48 private LockScreenSafetySource() { 49 } 50 51 /** Sets lock screen safety data for Safety Center. */ setSafetySourceData(Context context, ScreenLockPreferenceDetailsUtils screenLockPreferenceDetailsUtils, SafetyEvent safetyEvent)52 public static void setSafetySourceData(Context context, 53 ScreenLockPreferenceDetailsUtils screenLockPreferenceDetailsUtils, 54 SafetyEvent safetyEvent) { 55 if (!SafetyCenterManagerWrapper.get().isEnabled(context)) { 56 return; 57 } 58 59 if (!screenLockPreferenceDetailsUtils.isAvailable()) { 60 return; 61 } 62 63 final int userId = UserHandle.myUserId(); 64 final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtilsInternal 65 .checkIfPasswordQualityIsSet(context, userId); 66 final PendingIntent pendingIntent = createPendingIntent(context, 67 screenLockPreferenceDetailsUtils.getLaunchChooseLockGenericFragmentIntent( 68 SettingsEnums.SAFETY_CENTER), REQUEST_CODE_SCREEN_LOCK); 69 final IconAction gearMenuIconAction = createGearMenuIconAction(context, 70 screenLockPreferenceDetailsUtils); 71 final boolean enabled = 72 !screenLockPreferenceDetailsUtils.isPasswordQualityManaged(userId, admin); 73 final boolean isLockPatternSecure = screenLockPreferenceDetailsUtils.isLockPatternSecure(); 74 final int severityLevel = enabled 75 ? isLockPatternSecure 76 ? SafetySourceData.SEVERITY_LEVEL_INFORMATION 77 : SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION 78 : SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED; 79 80 81 final SafetySourceStatus status = new SafetySourceStatus.Builder( 82 context.getString(R.string.unlock_set_unlock_launch_picker_title), 83 screenLockPreferenceDetailsUtils.getSummary(UserHandle.myUserId()), 84 severityLevel) 85 .setPendingIntent(pendingIntent) 86 .setEnabled(enabled) 87 .setIconAction(gearMenuIconAction).build(); 88 final SafetySourceData.Builder safetySourceDataBuilder = 89 new SafetySourceData.Builder().setStatus(status); 90 if (enabled && !isLockPatternSecure) { 91 safetySourceDataBuilder.addIssue(createNoScreenLockIssue(context, pendingIntent)); 92 } 93 final SafetySourceData safetySourceData = safetySourceDataBuilder.build(); 94 95 SafetyCenterManagerWrapper.get().setSafetySourceData( 96 context, 97 SAFETY_SOURCE_ID, 98 safetySourceData, 99 safetyEvent 100 ); 101 } 102 103 /** Notifies Safety Center of a change in lock screen settings. */ onLockScreenChange(Context context)104 public static void onLockScreenChange(Context context) { 105 setSafetySourceData( 106 context, new ScreenLockPreferenceDetailsUtils(context), 107 new SafetyEvent.Builder(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()); 108 109 // Also send refreshed safety center data for biometrics, since changing lockscreen settings 110 // can unset biometrics. 111 BiometricsSafetySource.onBiometricsChanged(context); 112 } 113 createGearMenuIconAction(Context context, ScreenLockPreferenceDetailsUtils screenLockPreferenceDetailsUtils)114 private static IconAction createGearMenuIconAction(Context context, 115 ScreenLockPreferenceDetailsUtils screenLockPreferenceDetailsUtils) { 116 return screenLockPreferenceDetailsUtils.shouldShowGearMenu() ? new IconAction( 117 IconAction.ICON_TYPE_GEAR, 118 createPendingIntent(context, 119 screenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent( 120 SettingsEnums.SAFETY_CENTER), 121 REQUEST_CODE_SCREEN_LOCK_SETTINGS)) 122 : null; 123 } 124 createPendingIntent(Context context, Intent intent, int requestCode)125 private static PendingIntent createPendingIntent(Context context, Intent intent, 126 int requestCode) { 127 return PendingIntent 128 .getActivity( 129 context, 130 requestCode, 131 intent, 132 PendingIntent.FLAG_IMMUTABLE); 133 } 134 createNoScreenLockIssue(Context context, PendingIntent pendingIntent)135 private static SafetySourceIssue createNoScreenLockIssue(Context context, 136 PendingIntent pendingIntent) { 137 final SafetySourceIssue.Action action = new SafetySourceIssue.Action.Builder( 138 SET_SCREEN_LOCK_ACTION_ID, 139 context.getString(R.string.no_screen_lock_issue_action_label), 140 pendingIntent).build(); 141 return new SafetySourceIssue.Builder( 142 NO_SCREEN_LOCK_ISSUE_ID, 143 context.getString(R.string.no_screen_lock_issue_title), 144 context.getString(R.string.no_screen_lock_issue_summary), 145 SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION, 146 NO_SCREEN_LOCK_ISSUE_TYPE_ID) 147 .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE) 148 .addAction(action).build(); 149 } 150 } 151