blob: 8a135b81e56215bb35fefdb253b98c736adf4f31 [file] [log] [blame]
Adrian Roos82142c22014-03-27 14:56:59 +01001/*
2 * Copyright (C) 2014 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
17package com.android.server.trust;
18
Adrian Roos82142c22014-03-27 14:56:59 +010019import android.Manifest;
Andrew Scull85a63bc2016-10-24 13:47:47 +010020import android.annotation.UserIdInt;
Adrian Roosbcd07652014-10-22 16:57:16 +020021import android.app.ActivityManager;
Adrian Roosca36b952014-05-16 18:52:29 +020022import android.app.admin.DevicePolicyManager;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020023import android.hardware.biometrics.BiometricSourceType;
Adrian Roos82142c22014-03-27 14:56:59 +010024import android.app.trust.ITrustListener;
25import android.app.trust.ITrustManager;
Adrian Roosca36b952014-05-16 18:52:29 +020026import android.content.BroadcastReceiver;
Adrian Roos82142c22014-03-27 14:56:59 +010027import android.content.ComponentName;
28import android.content.Context;
29import android.content.Intent;
Adrian Roosca36b952014-05-16 18:52:29 +020030import android.content.IntentFilter;
Adrian Roos3870d452014-09-05 18:22:28 +020031import android.content.pm.ApplicationInfo;
Adrian Roos82142c22014-03-27 14:56:59 +010032import android.content.pm.PackageManager;
33import android.content.pm.ResolveInfo;
34import android.content.pm.UserInfo;
35import android.content.res.Resources;
36import android.content.res.TypedArray;
37import android.content.res.XmlResourceParser;
38import android.graphics.drawable.Drawable;
Adrian Roosbcd07652014-10-22 16:57:16 +020039import android.os.Binder;
Adrian Roos5d639782016-07-21 11:43:02 -070040import android.os.Build;
Adrian Roosa4ba56b2014-05-20 12:56:25 +020041import android.os.DeadObjectException;
Adrian Roos82142c22014-03-27 14:56:59 +010042import android.os.Handler;
43import android.os.IBinder;
44import android.os.Message;
Jim Millere303bf42014-08-26 17:12:29 -070045import android.os.PersistableBundle;
Adrian Roos82142c22014-03-27 14:56:59 +010046import android.os.RemoteException;
Adrian Roosc5f95ce2014-07-24 16:00:46 +020047import android.os.SystemClock;
Adrian Roos82142c22014-03-27 14:56:59 +010048import android.os.UserHandle;
49import android.os.UserManager;
Adrian Roos68771eb2016-05-03 14:02:36 -070050import android.os.storage.StorageManager;
Adrian Roos3870d452014-09-05 18:22:28 +020051import android.provider.Settings;
Adrian Roos82142c22014-03-27 14:56:59 +010052import android.service.trust.TrustAgentService;
Zachary Iqbal666484d2017-03-31 19:10:09 -070053import android.text.TextUtils;
Adrian Roos82142c22014-03-27 14:56:59 +010054import android.util.ArraySet;
55import android.util.AttributeSet;
Adrian Roos18ea8932014-05-28 14:53:06 +020056import android.util.Log;
Adrian Roos82142c22014-03-27 14:56:59 +010057import android.util.Slog;
Adrian Roos7046bfd2014-05-16 21:20:54 +020058import android.util.SparseBooleanArray;
Adrian Roos82142c22014-03-27 14:56:59 +010059import android.util.Xml;
Adrian Roos481a6df2014-11-20 19:48:56 +010060import android.view.IWindowManager;
Adrian Roos50bfeec2014-11-20 16:21:11 +010061import android.view.WindowManagerGlobal;
Lingjun Li93a145f2017-01-23 17:13:35 -080062import com.android.internal.annotations.GuardedBy;
63import com.android.internal.content.PackageMonitor;
Lucas Dupinef886542018-01-03 16:03:07 -080064import com.android.internal.policy.IKeyguardDismissCallback;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060065import com.android.internal.util.DumpUtils;
Lingjun Li93a145f2017-01-23 17:13:35 -080066import com.android.internal.widget.LockPatternUtils;
67import com.android.server.SystemService;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020068import java.io.FileDescriptor;
Adrian Roos82142c22014-03-27 14:56:59 +010069import java.io.IOException;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020070import java.io.PrintWriter;
Adrian Roos82142c22014-03-27 14:56:59 +010071import java.util.ArrayList;
72import java.util.List;
Lingjun Li93a145f2017-01-23 17:13:35 -080073import org.xmlpull.v1.XmlPullParser;
74import org.xmlpull.v1.XmlPullParserException;
Adrian Roos82142c22014-03-27 14:56:59 +010075
76/**
77 * Manages trust agents and trust listeners.
78 *
79 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
80 * of each user and notifies them about events that are relevant to them.
81 * It start and stops them based on the value of
82 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
83 *
84 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
85 * trust state changes for any user.
86 *
87 * Trust state and the setting of enabled agents is kept per user and each user has its own
88 * instance of a {@link android.service.trust.TrustAgentService}.
89 */
90public class TrustManagerService extends SystemService {
Adrian Roos82142c22014-03-27 14:56:59 +010091 private static final String TAG = "TrustManagerService";
Adrian Roos5d639782016-07-21 11:43:02 -070092 static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
Adrian Roos82142c22014-03-27 14:56:59 +010093
94 private static final Intent TRUST_AGENT_INTENT =
95 new Intent(TrustAgentService.SERVICE_INTERFACE);
Adrian Roos18ea8932014-05-28 14:53:06 +020096 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
Adrian Roos82142c22014-03-27 14:56:59 +010097
98 private static final int MSG_REGISTER_LISTENER = 1;
99 private static final int MSG_UNREGISTER_LISTENER = 2;
100 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
101 private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
Adrian Roos481a6df2014-11-20 19:48:56 +0100102 private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
103 private static final int MSG_START_USER = 7;
104 private static final int MSG_CLEANUP_USER = 8;
105 private static final int MSG_SWITCH_USER = 9;
Rubin Xu83a15bc2016-08-10 10:53:24 +0100106 private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 10;
107 private static final int MSG_UNLOCK_USER = 11;
Andrew Scull85a63bc2016-10-24 13:47:47 +0100108 private static final int MSG_STOP_USER = 12;
Zachary Iqbal327323d2017-01-12 14:41:13 -0800109 private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700110 private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
Adrian Roosc13723f2016-01-12 20:29:03 +0100111
Adrian Roos517b3a42016-03-03 14:58:33 -0800112 private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
Adrian Roos82142c22014-03-27 14:56:59 +0100113
Adrian Roosb5e47222015-08-14 15:53:06 -0700114 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
115 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
Adrian Roos9dbe1902014-08-13 18:25:52 +0200116 private final Receiver mReceiver = new Receiver();
Adrian Roosb5e47222015-08-14 15:53:06 -0700117
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200118 /* package */ final TrustArchive mArchive = new TrustArchive();
Adrian Roos82142c22014-03-27 14:56:59 +0100119 private final Context mContext;
Adrian Roos3870d452014-09-05 18:22:28 +0200120 private final LockPatternUtils mLockPatternUtils;
Adrian Roosbcd07652014-10-22 16:57:16 +0200121 private final UserManager mUserManager;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100122 private final ActivityManager mActivityManager;
Adrian Roos82142c22014-03-27 14:56:59 +0100123
Adrian Roosbcd07652014-10-22 16:57:16 +0200124 @GuardedBy("mUserIsTrusted")
125 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
Adrian Roos82142c22014-03-27 14:56:59 +0100126
Adrian Roos481a6df2014-11-20 19:48:56 +0100127 @GuardedBy("mDeviceLockedForUser")
128 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
129
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700130 @GuardedBy("mTrustUsuallyManagedForUser")
Adrian Roosc13723f2016-01-12 20:29:03 +0100131 private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
132
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700133 // set to true only if user can skip bouncer
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200134 @GuardedBy("mUsersUnlockedByBiometric")
135 private final SparseBooleanArray mUsersUnlockedByBiometric = new SparseBooleanArray();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700136
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800137 private final StrongAuthTracker mStrongAuthTracker;
138
Adrian Rooscbe614f2014-10-28 20:16:12 +0100139 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700140 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100141
Adrian Roos82142c22014-03-27 14:56:59 +0100142 public TrustManagerService(Context context) {
143 super(context);
144 mContext = context;
145 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100146 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200147 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos517b3a42016-03-03 14:58:33 -0800148 mStrongAuthTracker = new StrongAuthTracker(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100149 }
150
151 @Override
152 public void onStart() {
153 publishBinderService(Context.TRUST_SERVICE, mService);
154 }
155
156 @Override
157 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200158 if (isSafeMode()) {
159 // No trust agents in safe mode.
160 return;
161 }
162 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100163 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200164 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700165 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100166 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
167 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700168 refreshAgentList(UserHandle.USER_ALL);
Xiaohui Chen605733b2016-05-19 16:39:09 -0700169 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200170 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700171 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100172 }
173 }
174
175 // Agent management
176
177 private static final class AgentInfo {
178 CharSequence label;
179 Drawable icon;
180 ComponentName component; // service that implements ITrustAgent
Lingjun Li20914d72016-11-14 15:39:13 -0800181 SettingsAttrs settings; // setting to launch to modify agent.
Adrian Roos82142c22014-03-27 14:56:59 +0100182 TrustAgentWrapper agent;
183 int userId;
184
185 @Override
186 public boolean equals(Object other) {
187 if (!(other instanceof AgentInfo)) {
188 return false;
189 }
190 AgentInfo o = (AgentInfo) other;
191 return component.equals(o.component) && userId == o.userId;
192 }
193
194 @Override
195 public int hashCode() {
196 return component.hashCode() * 31 + userId;
197 }
198 }
199
200 private void updateTrustAll() {
201 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
202 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700203 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100204 }
205 }
206
Adrian Roos94e15a52015-04-16 12:23:18 -0700207 public void updateTrust(int userId, int flags) {
Adrian Roosc13723f2016-01-12 20:29:03 +0100208 boolean managed = aggregateIsTrustManaged(userId);
209 dispatchOnTrustManagedChanged(managed, userId);
210 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
211 && isTrustUsuallyManagedInternal(userId) != managed) {
212 updateTrustUsuallyManaged(userId, managed);
213 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200214 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100215 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200216 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100217 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200218 mUserIsTrusted.put(userId, trusted);
219 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700220 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100221 if (changed) {
222 refreshDeviceLockedForUser(userId);
223 }
Adrian Roos82142c22014-03-27 14:56:59 +0100224 }
225
Adrian Roosc13723f2016-01-12 20:29:03 +0100226 private void updateTrustUsuallyManaged(int userId, boolean managed) {
227 synchronized (mTrustUsuallyManagedForUser) {
228 mTrustUsuallyManagedForUser.put(userId, managed);
229 }
230 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
231 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
232 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
233 mHandler.sendMessageDelayed(
234 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
235 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
236 }
237
Lingjun Li93a145f2017-01-23 17:13:35 -0800238 public long addEscrowToken(byte[] token, int userId) {
239 return mLockPatternUtils.addEscrowToken(token, userId);
240 }
241
242 public boolean removeEscrowToken(long handle, int userId) {
243 return mLockPatternUtils.removeEscrowToken(handle, userId);
244 }
245
246 public boolean isEscrowTokenActive(long handle, int userId) {
247 return mLockPatternUtils.isEscrowTokenActive(handle, userId);
248 }
249
250 public void unlockUserWithToken(long handle, byte[] token, int userId) {
251 mLockPatternUtils.unlockUserWithToken(handle, token, userId);
252 }
253
Lucas Dupinef886542018-01-03 16:03:07 -0800254 void showKeyguardErrorMessage(CharSequence message) {
255 dispatchOnTrustError(message);
256 }
257
Adrian Roos517b3a42016-03-03 14:58:33 -0800258 void refreshAgentList(int userIdOrAll) {
259 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100260 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200261 return;
262 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800263 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
264 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
Adrian Roose681c272014-09-08 14:03:47 +0200265 + " must be USER_ALL or a specific user.", new Throwable("here"));
Adrian Roos517b3a42016-03-03 14:58:33 -0800266 userIdOrAll = UserHandle.USER_ALL;
Adrian Roose681c272014-09-08 14:03:47 +0200267 }
Adrian Roos82142c22014-03-27 14:56:59 +0100268 PackageManager pm = mContext.getPackageManager();
269
Marco Fucci4e68f112014-08-29 12:31:48 -0700270 List<UserInfo> userInfos;
Adrian Roos517b3a42016-03-03 14:58:33 -0800271 if (userIdOrAll == UserHandle.USER_ALL) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700272 userInfos = mUserManager.getUsers(true /* excludeDying */);
273 } else {
274 userInfos = new ArrayList<>();
Adrian Roos517b3a42016-03-03 14:58:33 -0800275 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
Marco Fucci4e68f112014-08-29 12:31:48 -0700276 }
Adrian Roos3870d452014-09-05 18:22:28 +0200277 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100278
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200279 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
280 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100281
282 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100283 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
284 || userInfo.guestToRemove) continue;
Adrian Roos5d639782016-07-21 11:43:02 -0700285 if (!userInfo.supportsSwitchToByUser()) {
286 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
287 + ": switchToByUser=false");
288 continue;
289 }
Adrian Roos5d639782016-07-21 11:43:02 -0700290 if (!mActivityManager.isUserRunning(userInfo.id)) {
291 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
292 + ": user not started");
293 continue;
294 }
295 if (!lockPatternUtils.isSecure(userInfo.id)) {
296 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
297 + ": no secure credential");
298 continue;
299 }
Lingjun Li20914d72016-11-14 15:39:13 -0800300
Adrian Roos8f211582014-07-29 15:09:57 +0200301 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
302 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700303 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200304 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
305
Adrian Roos82142c22014-03-27 14:56:59 +0100306 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200307 if (enabledAgents == null) {
Adrian Roos5d639782016-07-21 11:43:02 -0700308 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
309 + ": no agents enabled by user");
Adrian Roos82142c22014-03-27 14:56:59 +0100310 continue;
311 }
Adrian Roos3870d452014-09-05 18:22:28 +0200312 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100313 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100314 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100315
Adrian Roos5d639782016-07-21 11:43:02 -0700316 if (!enabledAgents.contains(name)) {
317 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
318 + name.flattenToShortString() + " u"+ userInfo.id
319 + ": not enabled by user");
320 continue;
321 }
Adrian Roos8f211582014-07-29 15:09:57 +0200322 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700323 List<PersistableBundle> config =
324 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200325 // Disable agent if no features are enabled.
Adrian Roos5d639782016-07-21 11:43:02 -0700326 if (config == null || config.isEmpty()) {
327 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
328 + name.flattenToShortString() + " u"+ userInfo.id
329 + ": not allowed by DPM");
330 continue;
331 }
Adrian Roos8f211582014-07-29 15:09:57 +0200332 }
Adrian Roos82142c22014-03-27 14:56:59 +0100333 AgentInfo agentInfo = new AgentInfo();
334 agentInfo.component = name;
335 agentInfo.userId = userInfo.id;
336 if (!mActiveAgents.contains(agentInfo)) {
337 agentInfo.label = resolveInfo.loadLabel(pm);
338 agentInfo.icon = resolveInfo.loadIcon(pm);
Lingjun Li20914d72016-11-14 15:39:13 -0800339 agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
Lingjun Li20914d72016-11-14 15:39:13 -0800340 } else {
341 int index = mActiveAgents.indexOf(agentInfo);
342 agentInfo = mActiveAgents.valueAt(index);
343 }
344
345 boolean directUnlock = resolveInfo.serviceInfo.directBootAware
346 && agentInfo.settings.canUnlockProfile;
347
348 if (directUnlock) {
349 if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
350 + "of user " + userInfo.id + "can unlock user profile.");
351 }
352
Jeff Sharkeya65e6492017-06-21 13:45:11 -0600353 if (!mUserManager.isUserUnlockingOrUnlocked(userInfo.id)
Lingjun Li20914d72016-11-14 15:39:13 -0800354 && !directUnlock) {
355 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
Lingjun Li93a145f2017-01-23 17:13:35 -0800356 + "'s trust agent " + name + ": FBE still locked and "
Lingjun Li20914d72016-11-14 15:39:13 -0800357 + " the agent cannot unlock user profile.");
358 continue;
359 }
360
361 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
362 int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
Zachary Iqbal327323d2017-01-12 14:41:13 -0800363 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
364 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
365 || !directUnlock) {
366 if (DEBUG)
367 Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
368 + ": prevented by StrongAuthTracker = 0x"
369 + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
370 userInfo.id)));
371 continue;
372 }
Lingjun Li20914d72016-11-14 15:39:13 -0800373 }
374 }
375
Adrian Roosb884bb22017-05-03 11:33:51 -0700376 if (agentInfo.agent == null) {
377 agentInfo.agent = new TrustAgentWrapper(mContext, this,
378 new Intent().setComponent(name), userInfo.getUserHandle());
379 }
380
Lingjun Li20914d72016-11-14 15:39:13 -0800381 if (!mActiveAgents.contains(agentInfo)) {
Adrian Roos82142c22014-03-27 14:56:59 +0100382 mActiveAgents.add(agentInfo);
383 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200384 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100385 }
386 }
387 }
388
389 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200390 for (int i = 0; i < obsoleteAgents.size(); i++) {
391 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roos517b3a42016-03-03 14:58:33 -0800392 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
Adrian Roose681c272014-09-08 14:03:47 +0200393 if (info.agent.isManagingTrust()) {
394 trustMayHaveChanged = true;
395 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100396 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200397 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100398 }
Adrian Roos82142c22014-03-27 14:56:59 +0100399 }
400
401 if (trustMayHaveChanged) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800402 if (userIdOrAll == UserHandle.USER_ALL) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100403 updateTrustAll();
404 } else {
Adrian Roos517b3a42016-03-03 14:58:33 -0800405 updateTrust(userIdOrAll, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100406 }
Adrian Roos82142c22014-03-27 14:56:59 +0100407 }
408 }
409
Adrian Roos481a6df2014-11-20 19:48:56 +0100410 boolean isDeviceLockedInner(int userId) {
411 synchronized (mDeviceLockedForUser) {
412 return mDeviceLockedForUser.get(userId, true);
413 }
414 }
415
416 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700417 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100418 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100419 + " must be USER_ALL or a specific user.", new Throwable("here"));
420 userId = UserHandle.USER_ALL;
421 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100422 List<UserInfo> userInfos;
423 if (userId == UserHandle.USER_ALL) {
424 userInfos = mUserManager.getUsers(true /* excludeDying */);
425 } else {
426 userInfos = new ArrayList<>();
427 userInfos.add(mUserManager.getUserInfo(userId));
428 }
429
430 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
431
432 for (int i = 0; i < userInfos.size(); i++) {
433 UserInfo info = userInfos.get(i);
434
435 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700436 || !info.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100437 continue;
438 }
439
440 int id = info.id;
441 boolean secure = mLockPatternUtils.isSecure(id);
442 boolean trusted = aggregateIsTrusted(id);
443 boolean showingKeyguard = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200444 boolean biometricAuthenticated = false;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700445
Adrian Roos481a6df2014-11-20 19:48:56 +0100446 if (mCurrentUser == id) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200447 synchronized(mUsersUnlockedByBiometric) {
448 biometricAuthenticated = mUsersUnlockedByBiometric.get(id, false);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700449 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100450 try {
451 showingKeyguard = wm.isKeyguardLocked();
452 } catch (RemoteException e) {
453 }
454 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700455 boolean deviceLocked = secure && showingKeyguard && !trusted &&
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200456 !biometricAuthenticated;
Andrew Scull85a63bc2016-10-24 13:47:47 +0100457 setDeviceLockedForUser(id, deviceLocked);
458 }
459 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100460
Andrew Scull85a63bc2016-10-24 13:47:47 +0100461 private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
462 final boolean changed;
463 synchronized (mDeviceLockedForUser) {
464 changed = isDeviceLockedInner(userId) != locked;
465 mDeviceLockedForUser.put(userId, locked);
466 }
467 if (changed) {
468 dispatchDeviceLocked(userId, locked);
Adrian Roos481a6df2014-11-20 19:48:56 +0100469 }
470 }
471
472 private void dispatchDeviceLocked(int userId, boolean isLocked) {
473 for (int i = 0; i < mActiveAgents.size(); i++) {
474 AgentInfo agent = mActiveAgents.valueAt(i);
475 if (agent.userId == userId) {
476 if (isLocked) {
477 agent.agent.onDeviceLocked();
478 } else{
479 agent.agent.onDeviceUnlocked();
480 }
481 }
482 }
483 }
484
Marco Fucci4e68f112014-08-29 12:31:48 -0700485 void updateDevicePolicyFeatures() {
Adrian Roos9d6fc922016-08-10 17:09:55 -0700486 boolean changed = false;
Adrian Roos8f211582014-07-29 15:09:57 +0200487 for (int i = 0; i < mActiveAgents.size(); i++) {
488 AgentInfo info = mActiveAgents.valueAt(i);
489 if (info.agent.isConnected()) {
490 info.agent.updateDevicePolicyFeatures();
Adrian Roos9d6fc922016-08-10 17:09:55 -0700491 changed = true;
Adrian Roos8f211582014-07-29 15:09:57 +0200492 }
493 }
Adrian Roos9d6fc922016-08-10 17:09:55 -0700494 if (changed) {
495 mArchive.logDevicePolicyChanged();
496 }
Adrian Roos8f211582014-07-29 15:09:57 +0200497 }
498
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200499 private void removeAgentsOfPackage(String packageName) {
500 boolean trustMayHaveChanged = false;
501 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
502 AgentInfo info = mActiveAgents.valueAt(i);
503 if (packageName.equals(info.component.getPackageName())) {
504 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200505 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200506 trustMayHaveChanged = true;
507 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100508 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200509 mActiveAgents.removeAt(i);
510 }
511 }
512 if (trustMayHaveChanged) {
513 updateTrustAll();
514 }
515 }
516
517 public void resetAgent(ComponentName name, int userId) {
518 boolean trustMayHaveChanged = false;
519 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
520 AgentInfo info = mActiveAgents.valueAt(i);
521 if (name.equals(info.component) && userId == info.userId) {
522 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200523 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200524 trustMayHaveChanged = true;
525 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100526 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200527 mActiveAgents.removeAt(i);
528 }
529 }
530 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700531 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200532 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700533 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200534 }
535
Lingjun Li20914d72016-11-14 15:39:13 -0800536 private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) {
Adrian Roos82142c22014-03-27 14:56:59 +0100537 if (resolveInfo == null || resolveInfo.serviceInfo == null
538 || resolveInfo.serviceInfo.metaData == null) return null;
539 String cn = null;
Lingjun Li20914d72016-11-14 15:39:13 -0800540 boolean canUnlockProfile = false;
541
Adrian Roos82142c22014-03-27 14:56:59 +0100542 XmlResourceParser parser = null;
543 Exception caughtException = null;
544 try {
545 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
546 TrustAgentService.TRUST_AGENT_META_DATA);
547 if (parser == null) {
548 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
549 return null;
550 }
551 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
552 AttributeSet attrs = Xml.asAttributeSet(parser);
553 int type;
554 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
555 && type != XmlPullParser.START_TAG) {
556 // Drain preamble.
557 }
558 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200559 if (!"trust-agent".equals(nodeName)) {
560 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100561 return null;
562 }
563 TypedArray sa = res
564 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
565 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
Lingjun Li20914d72016-11-14 15:39:13 -0800566 canUnlockProfile = sa.getBoolean(
567 com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
Adrian Roos82142c22014-03-27 14:56:59 +0100568 sa.recycle();
569 } catch (PackageManager.NameNotFoundException e) {
570 caughtException = e;
571 } catch (IOException e) {
572 caughtException = e;
573 } catch (XmlPullParserException e) {
574 caughtException = e;
575 } finally {
576 if (parser != null) parser.close();
577 }
578 if (caughtException != null) {
579 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
580 return null;
581 }
582 if (cn == null) {
583 return null;
584 }
585 if (cn.indexOf('/') < 0) {
586 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
587 }
Lingjun Li20914d72016-11-14 15:39:13 -0800588 return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
Adrian Roos82142c22014-03-27 14:56:59 +0100589 }
590
591 private ComponentName getComponentName(ResolveInfo resolveInfo) {
592 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
593 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
594 }
595
Adrian Roos3870d452014-09-05 18:22:28 +0200596 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200597 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
598 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
599 return;
600 }
601 PackageManager pm = mContext.getPackageManager();
602 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700603 ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
604 boolean shouldUseDefaultAgent = defaultAgent != null;
Adrian Roos2f19ad42017-07-05 16:09:22 +0200605 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
Zachary Iqbal666484d2017-03-31 19:10:09 -0700606
607 if (shouldUseDefaultAgent) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200608 discoveredAgents.add(defaultAgent);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700609 Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
610 } else { // A default agent is not set; perform regular trust agent discovery
611 for (ResolveInfo resolveInfo : resolveInfos) {
612 ComponentName componentName = getComponentName(resolveInfo);
613 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
614 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
615 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
616 + "is not a system package.");
617 continue;
618 }
619 discoveredAgents.add(componentName);
Adrian Roos3870d452014-09-05 18:22:28 +0200620 }
Adrian Roos3870d452014-09-05 18:22:28 +0200621 }
Adrian Roos2f19ad42017-07-05 16:09:22 +0200622
623 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
624 if (previouslyEnabledAgents != null) {
625 discoveredAgents.addAll(previouslyEnabledAgents);
626 }
627 utils.setEnabledTrustAgents(discoveredAgents, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200628 Settings.Secure.putIntForUser(mContext.getContentResolver(),
629 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
630 }
631
Zachary Iqbal666484d2017-03-31 19:10:09 -0700632 /**
633 * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
634 * is no trust agent set.
635 */
636 private static ComponentName getDefaultFactoryTrustAgent(Context context) {
637 String defaultTrustAgent = context.getResources()
638 .getString(com.android.internal.R.string.config_defaultTrustAgent);
639 if (TextUtils.isEmpty(defaultTrustAgent)) {
640 return null;
641 }
642 return ComponentName.unflattenFromString(defaultTrustAgent);
643 }
644
Adrian Roos3870d452014-09-05 18:22:28 +0200645 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
646 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
Lingjun Li20914d72016-11-14 15:39:13 -0800647 PackageManager.GET_META_DATA |
Adrian Roos68771eb2016-05-03 14:02:36 -0700648 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
649 userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200650 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
651 for (ResolveInfo resolveInfo : resolveInfos) {
652 if (resolveInfo.serviceInfo == null) continue;
653 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
654 String packageName = resolveInfo.serviceInfo.packageName;
655 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
656 != PackageManager.PERMISSION_GRANTED) {
657 ComponentName name = getComponentName(resolveInfo);
658 Log.w(TAG, "Skipping agent " + name + " because package does not have"
659 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
660 continue;
661 }
662 allowedAgents.add(resolveInfo);
663 }
664 return allowedAgents;
665 }
666
Adrian Roos82142c22014-03-27 14:56:59 +0100667 // Agent dispatch and aggregation
668
669 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700670 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200671 return false;
672 }
Adrian Roos82142c22014-03-27 14:56:59 +0100673 for (int i = 0; i < mActiveAgents.size(); i++) {
674 AgentInfo info = mActiveAgents.valueAt(i);
675 if (info.userId == userId) {
676 if (info.agent.isTrusted()) {
677 return true;
678 }
679 }
680 }
681 return false;
682 }
683
Adrian Roos7861c662014-07-25 15:37:28 +0200684 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700685 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200686 return false;
687 }
688 for (int i = 0; i < mActiveAgents.size(); i++) {
689 AgentInfo info = mActiveAgents.valueAt(i);
690 if (info.userId == userId) {
691 if (info.agent.isManagingTrust()) {
692 return true;
693 }
694 }
695 }
696 return false;
697 }
698
Adrian Roos82142c22014-03-27 14:56:59 +0100699 private void dispatchUnlockAttempt(boolean successful, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800700 if (successful) {
701 mStrongAuthTracker.allowTrustFromUnlock(userId);
702 }
703
Adrian Roos82142c22014-03-27 14:56:59 +0100704 for (int i = 0; i < mActiveAgents.size(); i++) {
705 AgentInfo info = mActiveAgents.valueAt(i);
706 if (info.userId == userId) {
707 info.agent.onUnlockAttempt(successful);
708 }
709 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200710 }
711
Zachary Iqbal327323d2017-01-12 14:41:13 -0800712 private void dispatchUnlockLockout(int timeoutMs, int userId) {
713 for (int i = 0; i < mActiveAgents.size(); i++) {
714 AgentInfo info = mActiveAgents.valueAt(i);
715 if (info.userId == userId) {
716 info.agent.onUnlockLockout(timeoutMs);
717 }
718 }
719 }
720
Adrian Roos82142c22014-03-27 14:56:59 +0100721 // Listeners
722
723 private void addListener(ITrustListener listener) {
724 for (int i = 0; i < mTrustListeners.size(); i++) {
725 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
726 return;
727 }
728 }
729 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200730 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100731 }
732
733 private void removeListener(ITrustListener listener) {
734 for (int i = 0; i < mTrustListeners.size(); i++) {
735 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700736 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100737 return;
738 }
739 }
740 }
741
Adrian Roos94e15a52015-04-16 12:23:18 -0700742 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800743 if (DEBUG) {
744 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
745 + Integer.toHexString(flags) + ")");
746 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700747 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100748 for (int i = 0; i < mTrustListeners.size(); i++) {
749 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700750 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200751 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200752 Slog.d(TAG, "Removing dead TrustListener.");
753 mTrustListeners.remove(i);
754 i--;
755 } catch (RemoteException e) {
756 Slog.e(TAG, "Exception while notifying TrustListener.", e);
757 }
758 }
759 }
760
761 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800762 if (DEBUG) {
763 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
764 }
Adrian Roos7861c662014-07-25 15:37:28 +0200765 for (int i = 0; i < mTrustListeners.size(); i++) {
766 try {
767 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
768 } catch (DeadObjectException e) {
769 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200770 mTrustListeners.remove(i);
771 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100772 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200773 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100774 }
775 }
776 }
777
Lucas Dupinef886542018-01-03 16:03:07 -0800778 private void dispatchOnTrustError(CharSequence message) {
779 if (DEBUG) {
780 Log.i(TAG, "onTrustError(" + message + ")");
781 }
782 for (int i = 0; i < mTrustListeners.size(); i++) {
783 try {
784 mTrustListeners.get(i).onTrustError(message);
785 } catch (DeadObjectException e) {
786 Slog.d(TAG, "Removing dead TrustListener.");
787 mTrustListeners.remove(i);
788 i--;
789 } catch (RemoteException e) {
790 Slog.e(TAG, "Exception while notifying TrustListener.", e);
791 }
792 }
793 }
794
Adrian Rooscbe614f2014-10-28 20:16:12 +0100795 // User lifecycle
796
797 @Override
798 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100799 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100800 }
801
802 @Override
803 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100804 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
805 }
806
807 @Override
808 public void onSwitchUser(int userId) {
809 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100810 }
811
Adrian Roos68771eb2016-05-03 14:02:36 -0700812 @Override
813 public void onUnlockUser(int userId) {
814 mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
815 }
816
Andrew Scull85a63bc2016-10-24 13:47:47 +0100817 @Override
818 public void onStopUser(@UserIdInt int userId) {
819 mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
820 }
821
Adrian Roos82142c22014-03-27 14:56:59 +0100822 // Plumbing
823
824 private final IBinder mService = new ITrustManager.Stub() {
825 @Override
826 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
827 enforceReportPermission();
828 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
829 .sendToTarget();
830 }
831
832 @Override
Zachary Iqbal327323d2017-01-12 14:41:13 -0800833 public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
834 enforceReportPermission();
835 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
836 .sendToTarget();
837 }
838
839 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100840 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
841 enforceReportPermission();
842 // coalesce refresh messages.
843 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
844 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
845 }
846
847 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100848 public void reportKeyguardShowingChanged() throws RemoteException {
849 enforceReportPermission();
850 // coalesce refresh messages.
851 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
852 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
Jorim Jaggi5277dea2017-05-18 02:05:29 +0200853
854 // Make sure handler processes the message before returning, such that isDeviceLocked
855 // after this call will retrieve the correct value.
856 mHandler.runWithScissors(() -> {}, 0);
Adrian Roos481a6df2014-11-20 19:48:56 +0100857 }
858
859 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100860 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
861 enforceListenerPermission();
862 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
863 }
864
865 @Override
866 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
867 enforceListenerPermission();
868 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
869 }
870
Adrian Roosbcd07652014-10-22 16:57:16 +0200871 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100872 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200873 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100874 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +0100875
Clara Bayarri078e91b2016-01-15 16:57:35 +0000876 long token = Binder.clearCallingIdentity();
877 try {
878 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
879 userId = resolveProfileParent(userId);
880 }
881 return isDeviceLockedInner(userId);
882 } finally {
883 Binder.restoreCallingIdentity(token);
884 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200885 }
886
Adrian Roos82893682015-04-02 16:17:46 +0200887 @Override
888 public boolean isDeviceSecure(int userId) throws RemoteException {
889 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
890 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +0200891
892 long token = Binder.clearCallingIdentity();
893 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +0000894 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
895 userId = resolveProfileParent(userId);
896 }
Clara Bayarria1771112015-12-18 16:29:18 +0000897 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200898 } finally {
899 Binder.restoreCallingIdentity(token);
900 }
901 }
902
Adrian Roos82142c22014-03-27 14:56:59 +0100903 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200904 mContext.enforceCallingOrSelfPermission(
905 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100906 }
907
908 private void enforceListenerPermission() {
909 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
910 "register trust listener");
911 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200912
913 @Override
914 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600915 if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
Adrian Roos49d53452014-10-24 15:48:39 +0200916 if (isSafeMode()) {
917 fout.println("disabled because the system is in safe mode.");
918 return;
919 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100920 if (!mTrustAgentsCanRun) {
921 fout.println("disabled because the third-party apps can't run yet.");
922 return;
923 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200924 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200925 mHandler.runWithScissors(new Runnable() {
926 @Override
927 public void run() {
928 fout.println("Trust manager state:");
929 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100930 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200931 }
932 }
933 }, 1500);
934 }
935
936 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
937 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
938 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700939 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100940 fout.println("(managed profile)");
941 fout.println(" disabled because switching to this user is not possible.");
942 return;
943 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200944 if (isCurrent) {
945 fout.print(" (current)");
946 }
947 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200948 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100949 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -0700950 fout.print(", strongAuthRequired=" + dumpHex(
951 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200952 fout.println();
953 fout.println(" Enabled agents:");
954 boolean duplicateSimpleNames = false;
955 ArraySet<String> simpleNames = new ArraySet<String>();
956 for (AgentInfo info : mActiveAgents) {
957 if (info.userId != user.id) { continue; }
958 boolean trusted = info.agent.isTrusted();
959 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200960 fout.print(" bound=" + dumpBool(info.agent.isBound()));
961 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200962 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
963 fout.print(", trusted=" + dumpBool(trusted));
964 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200965 if (trusted) {
966 fout.println(" message=\"" + info.agent.getMessage() + "\"");
967 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200968 if (!info.agent.isConnected()) {
969 String restartTime = TrustArchive.formatDuration(
970 info.agent.getScheduledRestartUptimeMillis()
971 - SystemClock.uptimeMillis());
972 fout.println(" restartScheduledAt=" + restartTime);
973 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200974 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
975 duplicateSimpleNames = true;
976 }
977 }
978 fout.println(" Events:");
979 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
980 fout.println();
981 }
982
983 private String dumpBool(boolean b) {
984 return b ? "1" : "0";
985 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700986
987 private String dumpHex(int i) {
988 return "0x" + Integer.toHexString(i);
989 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000990
991 @Override
Rubin Xu83a15bc2016-08-10 10:53:24 +0100992 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarri00a9b892016-01-13 16:17:09 +0000993 enforceReportPermission();
Rubin Xue0781332016-08-19 11:20:34 +0100994 final long identity = Binder.clearCallingIdentity();
995 try {
996 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
997 synchronized (mDeviceLockedForUser) {
998 mDeviceLockedForUser.put(userId, locked);
999 }
1000 if (locked) {
1001 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001002 ActivityManager.getService().notifyLockedProfile(userId);
Rubin Xue0781332016-08-19 11:20:34 +01001003 } catch (RemoteException e) {
1004 }
Rubin Xu83a15bc2016-08-10 10:53:24 +01001005 }
Robin Lee92b83c62016-08-31 13:27:51 +01001006 final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
1007 lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1008 lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1009 mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
1010 Manifest.permission.TRUST_LISTENER, /* options */ null);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001011 }
Rubin Xue0781332016-08-19 11:20:34 +01001012 } finally {
1013 Binder.restoreCallingIdentity(identity);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001014 }
Clara Bayarri56878a92015-10-29 15:43:55 +00001015 }
Adrian Roosc13723f2016-01-12 20:29:03 +01001016
1017 @Override
1018 public boolean isTrustUsuallyManaged(int userId) {
1019 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1020 "query trust state");
1021 return isTrustUsuallyManagedInternal(userId);
1022 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001023
1024 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001025 public void unlockedByBiometricForUser(int userId, BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001026 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001027 synchronized(mUsersUnlockedByBiometric) {
1028 mUsersUnlockedByBiometric.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001029 }
1030 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
1031 0 /* arg2 */).sendToTarget();
1032 }
1033
1034 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001035 public void clearAllBiometricRecognized(BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001036 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001037 synchronized(mUsersUnlockedByBiometric) {
1038 mUsersUnlockedByBiometric.clear();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001039 }
1040 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
1041 0 /* arg2 */).sendToTarget();
1042 }
Adrian Roos82142c22014-03-27 14:56:59 +01001043 };
1044
Adrian Roosc13723f2016-01-12 20:29:03 +01001045 private boolean isTrustUsuallyManagedInternal(int userId) {
1046 synchronized (mTrustUsuallyManagedForUser) {
1047 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1048 if (i >= 0) {
1049 return mTrustUsuallyManagedForUser.valueAt(i);
1050 }
1051 }
1052 // It's not in memory yet, get the value from persisted storage instead
1053 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
1054 synchronized (mTrustUsuallyManagedForUser) {
1055 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1056 if (i >= 0) {
1057 // Someone set the trust usually managed in the mean time. Better use that.
1058 return mTrustUsuallyManagedForUser.valueAt(i);
1059 } else {
1060 // .. otherwise it's safe to cache the fetched value now.
1061 mTrustUsuallyManagedForUser.put(userId, persistedValue);
1062 return persistedValue;
1063 }
1064 }
1065 }
1066
Adrian Roosbcd07652014-10-22 16:57:16 +02001067 private int resolveProfileParent(int userId) {
1068 long identity = Binder.clearCallingIdentity();
1069 try {
1070 UserInfo parent = mUserManager.getProfileParent(userId);
1071 if (parent != null) {
1072 return parent.getUserHandle().getIdentifier();
1073 }
1074 return userId;
1075 } finally {
1076 Binder.restoreCallingIdentity(identity);
1077 }
1078 }
1079
Adrian Roos82142c22014-03-27 14:56:59 +01001080 private final Handler mHandler = new Handler() {
1081 @Override
1082 public void handleMessage(Message msg) {
1083 switch (msg.what) {
1084 case MSG_REGISTER_LISTENER:
1085 addListener((ITrustListener) msg.obj);
1086 break;
1087 case MSG_UNREGISTER_LISTENER:
1088 removeListener((ITrustListener) msg.obj);
1089 break;
1090 case MSG_DISPATCH_UNLOCK_ATTEMPT:
1091 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
1092 break;
Zachary Iqbal327323d2017-01-12 14:41:13 -08001093 case MSG_DISPATCH_UNLOCK_LOCKOUT:
1094 dispatchUnlockLockout(msg.arg1, msg.arg2);
1095 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001096 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -07001097 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +01001098 // This is also called when the security mode of a user changes.
1099 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001100 break;
Adrian Roos481a6df2014-11-20 19:48:56 +01001101 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +01001102 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +01001103 break;
1104 case MSG_START_USER:
1105 case MSG_CLEANUP_USER:
Adrian Roos68771eb2016-05-03 14:02:36 -07001106 case MSG_UNLOCK_USER:
Adrian Roos481a6df2014-11-20 19:48:56 +01001107 refreshAgentList(msg.arg1);
1108 break;
1109 case MSG_SWITCH_USER:
1110 mCurrentUser = msg.arg1;
1111 refreshDeviceLockedForUser(UserHandle.USER_ALL);
1112 break;
Andrew Scull85a63bc2016-10-24 13:47:47 +01001113 case MSG_STOP_USER:
1114 setDeviceLockedForUser(msg.arg1, true);
1115 break;
Adrian Roosc13723f2016-01-12 20:29:03 +01001116 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
1117 SparseBooleanArray usuallyManaged;
1118 synchronized (mTrustUsuallyManagedForUser) {
1119 usuallyManaged = mTrustUsuallyManagedForUser.clone();
1120 }
1121
1122 for (int i = 0; i < usuallyManaged.size(); i++) {
1123 int userId = usuallyManaged.keyAt(i);
1124 boolean value = usuallyManaged.valueAt(i);
1125 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
1126 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
1127 }
1128 }
Adrian Roos68771eb2016-05-03 14:02:36 -07001129 break;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001130 case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
1131 refreshDeviceLockedForUser(msg.arg1);
1132 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001133 }
1134 }
1135 };
1136
1137 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1138 @Override
1139 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -07001140 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001141 }
1142
1143 @Override
1144 public boolean onPackageChanged(String packageName, int uid, String[] components) {
1145 // We're interested in all changes, even if just some components get enabled / disabled.
1146 return true;
1147 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001148
1149 @Override
1150 public void onPackageDisappeared(String packageName, int reason) {
1151 removeAgentsOfPackage(packageName);
1152 }
Adrian Roos82142c22014-03-27 14:56:59 +01001153 };
Adrian Roosca36b952014-05-16 18:52:29 +02001154
Lingjun Li20914d72016-11-14 15:39:13 -08001155 private static class SettingsAttrs {
1156 public ComponentName componentName;
1157 public boolean canUnlockProfile;
1158
1159 public SettingsAttrs(
1160 ComponentName componentName,
1161 boolean canUnlockProfile) {
1162 this.componentName = componentName;
1163 this.canUnlockProfile = canUnlockProfile;
1164 }
1165 };
1166
Adrian Roos9dbe1902014-08-13 18:25:52 +02001167 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +02001168
1169 @Override
1170 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +02001171 String action = intent.getAction();
1172 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -07001173 refreshAgentList(getSendingUserId());
1174 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +02001175 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +01001176 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +02001177 if (userId > 0) {
1178 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +02001179 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001180 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
1181 int userId = getUserId(intent);
1182 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001183 synchronized (mUserIsTrusted) {
1184 mUserIsTrusted.delete(userId);
1185 }
1186 synchronized (mDeviceLockedForUser) {
1187 mDeviceLockedForUser.delete(userId);
1188 }
Adrian Roosae025822016-11-03 14:46:13 -07001189 synchronized (mTrustUsuallyManagedForUser) {
1190 mTrustUsuallyManagedForUser.delete(userId);
1191 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001192 synchronized (mUsersUnlockedByBiometric) {
1193 mUsersUnlockedByBiometric.delete(userId);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001194 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001195 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +01001196 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001197 }
1198 }
1199 }
1200
1201 private int getUserId(Intent intent) {
1202 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
1203 if (userId > 0) {
1204 return userId;
1205 } else {
1206 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
1207 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +02001208 }
1209 }
1210
1211 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +02001212 IntentFilter filter = new IntentFilter();
1213 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Adrian Roos3870d452014-09-05 18:22:28 +02001214 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001215 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +02001216 context.registerReceiverAsUser(this,
1217 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +02001218 filter,
Adrian Roosca36b952014-05-16 18:52:29 +02001219 null /* permission */,
1220 null /* scheduler */);
1221 }
1222 }
Adrian Roos517b3a42016-03-03 14:58:33 -08001223
1224 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1225
1226 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1227
1228 public StrongAuthTracker(Context context) {
1229 super(context);
1230 }
1231
1232 @Override
1233 public void onStrongAuthRequiredChanged(int userId) {
1234 mStartFromSuccessfulUnlock.delete(userId);
1235
1236 if (DEBUG) {
1237 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1238 + " trustAllowed=" + isTrustAllowedForUser(userId)
1239 + " agentsCanRun=" + canAgentsRunForUser(userId));
1240 }
1241
1242 refreshAgentList(userId);
1243
1244 // The list of active trust agents may not have changed, if there was a previous call
1245 // to allowTrustFromUnlock, so we update the trust here too.
1246 updateTrust(userId, 0 /* flags */);
1247 }
1248
1249 boolean canAgentsRunForUser(int userId) {
1250 return mStartFromSuccessfulUnlock.get(userId)
1251 || super.isTrustAllowedForUser(userId);
1252 }
1253
1254 /**
1255 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1256 * changes again. Must only be called when we know about a successful unlock already
1257 * before the underlying StrongAuthTracker.
1258 *
1259 * Note that this only changes whether trust agents can be started, not the actual trusted
1260 * value.
1261 */
1262 void allowTrustFromUnlock(int userId) {
1263 if (userId < UserHandle.USER_SYSTEM) {
1264 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1265 }
1266 boolean previous = canAgentsRunForUser(userId);
1267 mStartFromSuccessfulUnlock.put(userId, true);
1268
1269 if (DEBUG) {
1270 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1271 + " trustAllowed=" + isTrustAllowedForUser(userId)
1272 + " agentsCanRun=" + canAgentsRunForUser(userId));
1273 }
1274
1275 if (canAgentsRunForUser(userId) != previous) {
1276 refreshAgentList(userId);
1277 }
1278 }
1279 }
Adrian Roos82142c22014-03-27 14:56:59 +01001280}