• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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