blob: 423ec4c869c12dae0934e2669517a01b221026aa [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;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -080022import android.app.AlarmManager;
23import android.app.AlarmManager.OnAlarmListener;
Adrian Roosca36b952014-05-16 18:52:29 +020024import android.app.admin.DevicePolicyManager;
Adrian Roos82142c22014-03-27 14:56:59 +010025import android.app.trust.ITrustListener;
26import android.app.trust.ITrustManager;
Adrian Roosca36b952014-05-16 18:52:29 +020027import android.content.BroadcastReceiver;
Adrian Roos82142c22014-03-27 14:56:59 +010028import android.content.ComponentName;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -080029import android.content.ContentResolver;
Adrian Roos82142c22014-03-27 14:56:59 +010030import android.content.Context;
31import android.content.Intent;
Adrian Roosca36b952014-05-16 18:52:29 +020032import android.content.IntentFilter;
Adrian Roos3870d452014-09-05 18:22:28 +020033import android.content.pm.ApplicationInfo;
Adrian Roos82142c22014-03-27 14:56:59 +010034import android.content.pm.PackageManager;
35import android.content.pm.ResolveInfo;
36import android.content.pm.UserInfo;
37import android.content.res.Resources;
38import android.content.res.TypedArray;
39import android.content.res.XmlResourceParser;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -080040import android.database.ContentObserver;
Adrian Roos82142c22014-03-27 14:56:59 +010041import android.graphics.drawable.Drawable;
Dmitry Dementyev38579682019-01-22 13:41:34 -080042import android.hardware.biometrics.BiometricSourceType;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -080043import android.net.Uri;
Adrian Roosbcd07652014-10-22 16:57:16 +020044import android.os.Binder;
Adrian Roos5d639782016-07-21 11:43:02 -070045import android.os.Build;
Adrian Roosa4ba56b2014-05-20 12:56:25 +020046import android.os.DeadObjectException;
Adrian Roos82142c22014-03-27 14:56:59 +010047import android.os.Handler;
48import android.os.IBinder;
49import android.os.Message;
Jim Millere303bf42014-08-26 17:12:29 -070050import android.os.PersistableBundle;
Adrian Roos82142c22014-03-27 14:56:59 +010051import android.os.RemoteException;
Adrian Roosc5f95ce2014-07-24 16:00:46 +020052import android.os.SystemClock;
Adrian Roos82142c22014-03-27 14:56:59 +010053import android.os.UserHandle;
54import android.os.UserManager;
Adrian Roos3870d452014-09-05 18:22:28 +020055import android.provider.Settings;
Adrian Roos82142c22014-03-27 14:56:59 +010056import android.service.trust.TrustAgentService;
Zachary Iqbal666484d2017-03-31 19:10:09 -070057import android.text.TextUtils;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -080058import android.util.ArrayMap;
Adrian Roos82142c22014-03-27 14:56:59 +010059import android.util.ArraySet;
60import android.util.AttributeSet;
Adrian Roos18ea8932014-05-28 14:53:06 +020061import android.util.Log;
Adrian Roos82142c22014-03-27 14:56:59 +010062import android.util.Slog;
Adrian Roos7046bfd2014-05-16 21:20:54 +020063import android.util.SparseBooleanArray;
Adrian Roos82142c22014-03-27 14:56:59 +010064import android.util.Xml;
Adrian Roos481a6df2014-11-20 19:48:56 +010065import android.view.IWindowManager;
Adrian Roos50bfeec2014-11-20 16:21:11 +010066import android.view.WindowManagerGlobal;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -080067
Lingjun Li93a145f2017-01-23 17:13:35 -080068import com.android.internal.annotations.GuardedBy;
69import com.android.internal.content.PackageMonitor;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060070import com.android.internal.util.DumpUtils;
Lingjun Li93a145f2017-01-23 17:13:35 -080071import com.android.internal.widget.LockPatternUtils;
72import com.android.server.SystemService;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -080073
Dmitry Dementyev38579682019-01-22 13:41:34 -080074import org.xmlpull.v1.XmlPullParser;
75import org.xmlpull.v1.XmlPullParserException;
76
Adrian Roos7a4f3d42014-05-02 12:12:20 +020077import java.io.FileDescriptor;
Adrian Roos82142c22014-03-27 14:56:59 +010078import java.io.IOException;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020079import java.io.PrintWriter;
Adrian Roos82142c22014-03-27 14:56:59 +010080import java.util.ArrayList;
81import java.util.List;
Dmitry Dementyev38579682019-01-22 13:41:34 -080082
Adrian Roos82142c22014-03-27 14:56:59 +010083
84/**
85 * Manages trust agents and trust listeners.
86 *
87 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
88 * of each user and notifies them about events that are relevant to them.
89 * It start and stops them based on the value of
90 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
91 *
92 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
93 * trust state changes for any user.
94 *
95 * Trust state and the setting of enabled agents is kept per user and each user has its own
96 * instance of a {@link android.service.trust.TrustAgentService}.
97 */
98public class TrustManagerService extends SystemService {
Adrian Roos82142c22014-03-27 14:56:59 +010099 private static final String TAG = "TrustManagerService";
Adrian Roos5d639782016-07-21 11:43:02 -0700100 static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
Adrian Roos82142c22014-03-27 14:56:59 +0100101
102 private static final Intent TRUST_AGENT_INTENT =
103 new Intent(TrustAgentService.SERVICE_INTERFACE);
Adrian Roos18ea8932014-05-28 14:53:06 +0200104 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
Adrian Roos82142c22014-03-27 14:56:59 +0100105
106 private static final int MSG_REGISTER_LISTENER = 1;
107 private static final int MSG_UNREGISTER_LISTENER = 2;
108 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
109 private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
Adrian Roos481a6df2014-11-20 19:48:56 +0100110 private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
111 private static final int MSG_START_USER = 7;
112 private static final int MSG_CLEANUP_USER = 8;
113 private static final int MSG_SWITCH_USER = 9;
Rubin Xu83a15bc2016-08-10 10:53:24 +0100114 private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 10;
115 private static final int MSG_UNLOCK_USER = 11;
Andrew Scull85a63bc2016-10-24 13:47:47 +0100116 private static final int MSG_STOP_USER = 12;
Zachary Iqbal327323d2017-01-12 14:41:13 -0800117 private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700118 private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800119 private static final int MSG_SCHEDULE_TRUST_TIMEOUT = 15;
Adrian Roosc13723f2016-01-12 20:29:03 +0100120
Adrian Roos517b3a42016-03-03 14:58:33 -0800121 private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800122 private static final String TRUST_TIMEOUT_ALARM_TAG = "TrustManagerService.trustTimeoutForUser";
Dmitry Dementyev38579682019-01-22 13:41:34 -0800123 private static final long TRUST_TIMEOUT_IN_MILLIS = 4 * 60 * 60 * 1000;
Adrian Roos82142c22014-03-27 14:56:59 +0100124
Adrian Roosb5e47222015-08-14 15:53:06 -0700125 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
126 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
Adrian Roos9dbe1902014-08-13 18:25:52 +0200127 private final Receiver mReceiver = new Receiver();
Adrian Roosb5e47222015-08-14 15:53:06 -0700128
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200129 /* package */ final TrustArchive mArchive = new TrustArchive();
Adrian Roos82142c22014-03-27 14:56:59 +0100130 private final Context mContext;
Adrian Roos3870d452014-09-05 18:22:28 +0200131 private final LockPatternUtils mLockPatternUtils;
Adrian Roosbcd07652014-10-22 16:57:16 +0200132 private final UserManager mUserManager;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100133 private final ActivityManager mActivityManager;
Adrian Roos82142c22014-03-27 14:56:59 +0100134
Adrian Roosbcd07652014-10-22 16:57:16 +0200135 @GuardedBy("mUserIsTrusted")
136 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
Adrian Roos82142c22014-03-27 14:56:59 +0100137
Adrian Roos481a6df2014-11-20 19:48:56 +0100138 @GuardedBy("mDeviceLockedForUser")
139 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
140
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700141 @GuardedBy("mTrustUsuallyManagedForUser")
Adrian Roosc13723f2016-01-12 20:29:03 +0100142 private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
143
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700144 // set to true only if user can skip bouncer
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200145 @GuardedBy("mUsersUnlockedByBiometric")
146 private final SparseBooleanArray mUsersUnlockedByBiometric = new SparseBooleanArray();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700147
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800148 private final ArrayMap<Integer, TrustTimeoutAlarmListener> mTrustTimeoutAlarmListenerForUser =
149 new ArrayMap<>();
150 private AlarmManager mAlarmManager;
151 private final SettingsObserver mSettingsObserver;
152
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800153 private final StrongAuthTracker mStrongAuthTracker;
154
Adrian Rooscbe614f2014-10-28 20:16:12 +0100155 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700156 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100157
Adrian Roos82142c22014-03-27 14:56:59 +0100158 public TrustManagerService(Context context) {
159 super(context);
160 mContext = context;
161 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100162 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200163 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos517b3a42016-03-03 14:58:33 -0800164 mStrongAuthTracker = new StrongAuthTracker(context);
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800165 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
166 mSettingsObserver = new SettingsObserver(mHandler);
Adrian Roos82142c22014-03-27 14:56:59 +0100167 }
168
169 @Override
170 public void onStart() {
171 publishBinderService(Context.TRUST_SERVICE, mService);
172 }
173
174 @Override
175 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200176 if (isSafeMode()) {
177 // No trust agents in safe mode.
178 return;
179 }
180 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100181 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200182 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700183 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100184 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
185 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700186 refreshAgentList(UserHandle.USER_ALL);
Xiaohui Chen605733b2016-05-19 16:39:09 -0700187 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200188 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700189 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100190 }
191 }
192
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800193 // Extend unlock config and logic
194
195 private final class SettingsObserver extends ContentObserver {
196 private final Uri TRUST_AGENTS_EXTEND_UNLOCK =
197 Settings.Secure.getUriFor(Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK);
198
199 private final Uri LOCK_SCREEN_WHEN_TRUST_LOST =
200 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST);
201
202 private final ContentResolver mContentResolver;
203 private boolean mTrustAgentsExtendUnlock;
204 private boolean mLockWhenTrustLost;
205
206 /**
207 * Creates a settings observer
208 *
209 * @param handler The handler to run {@link #onChange} on, or null if none.
210 */
211 SettingsObserver(Handler handler) {
212 super(handler);
213 mContentResolver = getContext().getContentResolver();
214 updateContentObserver();
215 }
216
217 void updateContentObserver() {
218 mContentResolver.unregisterContentObserver(this);
219 mContentResolver.registerContentObserver(TRUST_AGENTS_EXTEND_UNLOCK,
220 false /* notifyForDescendents */,
221 this /* observer */,
222 mCurrentUser);
223 mContentResolver.registerContentObserver(LOCK_SCREEN_WHEN_TRUST_LOST,
224 false /* notifyForDescendents */,
225 this /* observer */,
226 mCurrentUser);
227
228 // Update the value immediately
229 onChange(true /* selfChange */, TRUST_AGENTS_EXTEND_UNLOCK);
230 onChange(true /* selfChange */, LOCK_SCREEN_WHEN_TRUST_LOST);
231 }
232
233 @Override
234 public void onChange(boolean selfChange, Uri uri) {
235 if (TRUST_AGENTS_EXTEND_UNLOCK.equals(uri)) {
236 mTrustAgentsExtendUnlock =
237 Settings.Secure.getIntForUser(
238 mContentResolver,
239 Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
240 0 /* default */,
241 mCurrentUser) != 0;
242 } else if (LOCK_SCREEN_WHEN_TRUST_LOST.equals(uri)) {
243 mLockWhenTrustLost =
244 Settings.Secure.getIntForUser(
245 mContentResolver,
246 Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST,
247 0 /* default */,
248 mCurrentUser) != 0;
249 }
250 }
251
252 boolean getTrustAgentsExtendUnlock() {
253 return mTrustAgentsExtendUnlock;
254 }
255
256 boolean getLockWhenTrustLost() {
257 return mLockWhenTrustLost;
258 }
259 }
260
261 private void maybeLockScreen(int userId) {
262 if (userId != mCurrentUser) {
263 return;
264 }
265
266 if (mSettingsObserver.getLockWhenTrustLost()) {
267 if (DEBUG) Slog.d(TAG, "Locking device because trust was lost");
268 try {
269 WindowManagerGlobal.getWindowManagerService().lockNow(null);
270 } catch (RemoteException e) {
271 Slog.e(TAG, "Error locking screen when trust was lost");
272 }
273
274 // If active unlocking is not allowed, cancel any pending trust timeouts because the
275 // screen is already locked.
276 TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
277 if (alarm != null && mSettingsObserver.getTrustAgentsExtendUnlock()) {
278 mAlarmManager.cancel(alarm);
279 alarm.setQueued(false /* isQueued */);
280 }
281 }
282 }
283
284 private void scheduleTrustTimeout(int userId, boolean override) {
285 int shouldOverride = override ? 1 : 0;
286 if (override) {
287 shouldOverride = 1;
288 }
289 mHandler.obtainMessage(MSG_SCHEDULE_TRUST_TIMEOUT, userId, shouldOverride).sendToTarget();
290 }
291
292 private void handleScheduleTrustTimeout(int userId, int shouldOverride) {
293 long when = SystemClock.elapsedRealtime() + TRUST_TIMEOUT_IN_MILLIS;
294 userId = mCurrentUser;
295 TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
296
297 // Cancel existing trust timeouts for this user if needed.
298 if (alarm != null) {
299 if (shouldOverride == 0 && alarm.isQueued()) {
300 if (DEBUG) Slog.d(TAG, "Found existing trust timeout alarm. Skipping.");
301 return;
302 }
303 mAlarmManager.cancel(alarm);
304 } else {
305 alarm = new TrustTimeoutAlarmListener(userId);
306 mTrustTimeoutAlarmListenerForUser.put(userId, alarm);
307 }
308
309 if (DEBUG) Slog.d(TAG, "\tSetting up trust timeout alarm");
310 alarm.setQueued(true /* isQueued */);
311 mAlarmManager.setExact(
312 AlarmManager.ELAPSED_REALTIME_WAKEUP, when, TRUST_TIMEOUT_ALARM_TAG, alarm,
313 mHandler);
314 }
315
316 // Agent management
Adrian Roos82142c22014-03-27 14:56:59 +0100317
318 private static final class AgentInfo {
319 CharSequence label;
320 Drawable icon;
321 ComponentName component; // service that implements ITrustAgent
Lingjun Li20914d72016-11-14 15:39:13 -0800322 SettingsAttrs settings; // setting to launch to modify agent.
Adrian Roos82142c22014-03-27 14:56:59 +0100323 TrustAgentWrapper agent;
324 int userId;
325
326 @Override
327 public boolean equals(Object other) {
328 if (!(other instanceof AgentInfo)) {
329 return false;
330 }
331 AgentInfo o = (AgentInfo) other;
332 return component.equals(o.component) && userId == o.userId;
333 }
334
335 @Override
336 public int hashCode() {
337 return component.hashCode() * 31 + userId;
338 }
339 }
340
341 private void updateTrustAll() {
342 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
343 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700344 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100345 }
346 }
347
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800348
Adrian Roos94e15a52015-04-16 12:23:18 -0700349 public void updateTrust(int userId, int flags) {
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800350 updateTrust(userId, flags, false /* isFromUnlock */);
351 }
352
353 private void updateTrust(int userId, int flags, boolean isFromUnlock) {
Adrian Roosc13723f2016-01-12 20:29:03 +0100354 boolean managed = aggregateIsTrustManaged(userId);
355 dispatchOnTrustManagedChanged(managed, userId);
356 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
357 && isTrustUsuallyManagedInternal(userId) != managed) {
358 updateTrustUsuallyManaged(userId, managed);
359 }
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800360
Adrian Roosbcd07652014-10-22 16:57:16 +0200361 boolean trusted = aggregateIsTrusted(userId);
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800362 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
363 boolean showingKeyguard = true;
364 try {
365 showingKeyguard = wm.isKeyguardLocked();
366 } catch (RemoteException e) {
367 }
368
369 if (mSettingsObserver.getTrustAgentsExtendUnlock()) {
370 trusted = trusted && (!showingKeyguard || isFromUnlock) && userId == mCurrentUser;
371 if (DEBUG) {
372 Slog.d(TAG, "Extend unlock setting trusted as " + Boolean.toString(trusted)
373 + " && " + Boolean.toString(!showingKeyguard)
374 + " && " + Boolean.toString(userId == mCurrentUser));
375 }
376 }
377
Adrian Roos481a6df2014-11-20 19:48:56 +0100378 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200379 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100380 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200381 mUserIsTrusted.put(userId, trusted);
382 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700383 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100384 if (changed) {
385 refreshDeviceLockedForUser(userId);
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800386 if (!trusted) {
387 maybeLockScreen(userId);
388 } else {
389 scheduleTrustTimeout(userId, false /* override */);
390 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100391 }
Adrian Roos82142c22014-03-27 14:56:59 +0100392 }
393
Adrian Roosc13723f2016-01-12 20:29:03 +0100394 private void updateTrustUsuallyManaged(int userId, boolean managed) {
395 synchronized (mTrustUsuallyManagedForUser) {
396 mTrustUsuallyManagedForUser.put(userId, managed);
397 }
398 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
399 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
400 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
401 mHandler.sendMessageDelayed(
402 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
403 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
404 }
405
Lingjun Li93a145f2017-01-23 17:13:35 -0800406 public long addEscrowToken(byte[] token, int userId) {
407 return mLockPatternUtils.addEscrowToken(token, userId);
408 }
409
410 public boolean removeEscrowToken(long handle, int userId) {
411 return mLockPatternUtils.removeEscrowToken(handle, userId);
412 }
413
414 public boolean isEscrowTokenActive(long handle, int userId) {
415 return mLockPatternUtils.isEscrowTokenActive(handle, userId);
416 }
417
418 public void unlockUserWithToken(long handle, byte[] token, int userId) {
419 mLockPatternUtils.unlockUserWithToken(handle, token, userId);
420 }
421
Lucas Dupinef886542018-01-03 16:03:07 -0800422 void showKeyguardErrorMessage(CharSequence message) {
423 dispatchOnTrustError(message);
424 }
425
Adrian Roos517b3a42016-03-03 14:58:33 -0800426 void refreshAgentList(int userIdOrAll) {
427 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100428 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200429 return;
430 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800431 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
432 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
Adrian Roose681c272014-09-08 14:03:47 +0200433 + " must be USER_ALL or a specific user.", new Throwable("here"));
Adrian Roos517b3a42016-03-03 14:58:33 -0800434 userIdOrAll = UserHandle.USER_ALL;
Adrian Roose681c272014-09-08 14:03:47 +0200435 }
Adrian Roos82142c22014-03-27 14:56:59 +0100436 PackageManager pm = mContext.getPackageManager();
437
Marco Fucci4e68f112014-08-29 12:31:48 -0700438 List<UserInfo> userInfos;
Adrian Roos517b3a42016-03-03 14:58:33 -0800439 if (userIdOrAll == UserHandle.USER_ALL) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700440 userInfos = mUserManager.getUsers(true /* excludeDying */);
441 } else {
442 userInfos = new ArrayList<>();
Adrian Roos517b3a42016-03-03 14:58:33 -0800443 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
Marco Fucci4e68f112014-08-29 12:31:48 -0700444 }
Adrian Roos3870d452014-09-05 18:22:28 +0200445 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100446
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200447 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
448 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100449
450 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100451 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
452 || userInfo.guestToRemove) continue;
Adrian Roos5d639782016-07-21 11:43:02 -0700453 if (!userInfo.supportsSwitchToByUser()) {
454 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
455 + ": switchToByUser=false");
456 continue;
457 }
Adrian Roos5d639782016-07-21 11:43:02 -0700458 if (!mActivityManager.isUserRunning(userInfo.id)) {
459 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
460 + ": user not started");
461 continue;
462 }
463 if (!lockPatternUtils.isSecure(userInfo.id)) {
464 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
465 + ": no secure credential");
466 continue;
467 }
Lingjun Li20914d72016-11-14 15:39:13 -0800468
Adrian Roos8f211582014-07-29 15:09:57 +0200469 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
470 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700471 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200472 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
473
Adrian Roos82142c22014-03-27 14:56:59 +0100474 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200475 if (enabledAgents == null) {
Adrian Roos5d639782016-07-21 11:43:02 -0700476 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
477 + ": no agents enabled by user");
Adrian Roos82142c22014-03-27 14:56:59 +0100478 continue;
479 }
Adrian Roos3870d452014-09-05 18:22:28 +0200480 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100481 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100482 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100483
Adrian Roos5d639782016-07-21 11:43:02 -0700484 if (!enabledAgents.contains(name)) {
485 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
486 + name.flattenToShortString() + " u"+ userInfo.id
487 + ": not enabled by user");
488 continue;
489 }
Adrian Roos8f211582014-07-29 15:09:57 +0200490 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700491 List<PersistableBundle> config =
492 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200493 // Disable agent if no features are enabled.
Adrian Roos5d639782016-07-21 11:43:02 -0700494 if (config == null || config.isEmpty()) {
495 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
496 + name.flattenToShortString() + " u"+ userInfo.id
497 + ": not allowed by DPM");
498 continue;
499 }
Adrian Roos8f211582014-07-29 15:09:57 +0200500 }
Adrian Roos82142c22014-03-27 14:56:59 +0100501 AgentInfo agentInfo = new AgentInfo();
502 agentInfo.component = name;
503 agentInfo.userId = userInfo.id;
504 if (!mActiveAgents.contains(agentInfo)) {
505 agentInfo.label = resolveInfo.loadLabel(pm);
506 agentInfo.icon = resolveInfo.loadIcon(pm);
Lingjun Li20914d72016-11-14 15:39:13 -0800507 agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
Lingjun Li20914d72016-11-14 15:39:13 -0800508 } else {
509 int index = mActiveAgents.indexOf(agentInfo);
510 agentInfo = mActiveAgents.valueAt(index);
511 }
512
513 boolean directUnlock = resolveInfo.serviceInfo.directBootAware
514 && agentInfo.settings.canUnlockProfile;
515
516 if (directUnlock) {
517 if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
518 + "of user " + userInfo.id + "can unlock user profile.");
519 }
520
Jeff Sharkeya65e6492017-06-21 13:45:11 -0600521 if (!mUserManager.isUserUnlockingOrUnlocked(userInfo.id)
Lingjun Li20914d72016-11-14 15:39:13 -0800522 && !directUnlock) {
523 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
Lingjun Li93a145f2017-01-23 17:13:35 -0800524 + "'s trust agent " + name + ": FBE still locked and "
Lingjun Li20914d72016-11-14 15:39:13 -0800525 + " the agent cannot unlock user profile.");
526 continue;
527 }
528
529 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
530 int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
Zachary Iqbal327323d2017-01-12 14:41:13 -0800531 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
532 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
533 || !directUnlock) {
534 if (DEBUG)
535 Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
536 + ": prevented by StrongAuthTracker = 0x"
537 + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
538 userInfo.id)));
539 continue;
540 }
Lingjun Li20914d72016-11-14 15:39:13 -0800541 }
542 }
543
Adrian Roosb884bb22017-05-03 11:33:51 -0700544 if (agentInfo.agent == null) {
545 agentInfo.agent = new TrustAgentWrapper(mContext, this,
546 new Intent().setComponent(name), userInfo.getUserHandle());
547 }
548
Lingjun Li20914d72016-11-14 15:39:13 -0800549 if (!mActiveAgents.contains(agentInfo)) {
Adrian Roos82142c22014-03-27 14:56:59 +0100550 mActiveAgents.add(agentInfo);
551 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200552 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100553 }
554 }
555 }
556
557 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200558 for (int i = 0; i < obsoleteAgents.size(); i++) {
559 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roos517b3a42016-03-03 14:58:33 -0800560 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
Adrian Roose681c272014-09-08 14:03:47 +0200561 if (info.agent.isManagingTrust()) {
562 trustMayHaveChanged = true;
563 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100564 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200565 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100566 }
Adrian Roos82142c22014-03-27 14:56:59 +0100567 }
568
569 if (trustMayHaveChanged) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800570 if (userIdOrAll == UserHandle.USER_ALL) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100571 updateTrustAll();
572 } else {
Adrian Roos517b3a42016-03-03 14:58:33 -0800573 updateTrust(userIdOrAll, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100574 }
Adrian Roos82142c22014-03-27 14:56:59 +0100575 }
576 }
577
Adrian Roos481a6df2014-11-20 19:48:56 +0100578 boolean isDeviceLockedInner(int userId) {
579 synchronized (mDeviceLockedForUser) {
580 return mDeviceLockedForUser.get(userId, true);
581 }
582 }
583
584 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700585 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100586 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100587 + " must be USER_ALL or a specific user.", new Throwable("here"));
588 userId = UserHandle.USER_ALL;
589 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100590 List<UserInfo> userInfos;
591 if (userId == UserHandle.USER_ALL) {
592 userInfos = mUserManager.getUsers(true /* excludeDying */);
593 } else {
594 userInfos = new ArrayList<>();
595 userInfos.add(mUserManager.getUserInfo(userId));
596 }
597
598 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
599
600 for (int i = 0; i < userInfos.size(); i++) {
601 UserInfo info = userInfos.get(i);
602
Pavel Grafov259ca362018-07-27 14:04:57 +0100603 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100604 continue;
605 }
606
607 int id = info.id;
608 boolean secure = mLockPatternUtils.isSecure(id);
Pavel Grafov259ca362018-07-27 14:04:57 +0100609
610 if (!info.supportsSwitchToByUser()) {
611 if (info.isManagedProfile() && !secure) {
612 setDeviceLockedForUser(id, false);
613 }
614 continue;
615 }
616
Adrian Roos481a6df2014-11-20 19:48:56 +0100617 boolean trusted = aggregateIsTrusted(id);
618 boolean showingKeyguard = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200619 boolean biometricAuthenticated = false;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700620
Adrian Roos481a6df2014-11-20 19:48:56 +0100621 if (mCurrentUser == id) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200622 synchronized(mUsersUnlockedByBiometric) {
623 biometricAuthenticated = mUsersUnlockedByBiometric.get(id, false);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700624 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100625 try {
626 showingKeyguard = wm.isKeyguardLocked();
627 } catch (RemoteException e) {
628 }
629 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700630 boolean deviceLocked = secure && showingKeyguard && !trusted &&
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200631 !biometricAuthenticated;
Andrew Scull85a63bc2016-10-24 13:47:47 +0100632 setDeviceLockedForUser(id, deviceLocked);
633 }
634 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100635
Andrew Scull85a63bc2016-10-24 13:47:47 +0100636 private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
637 final boolean changed;
638 synchronized (mDeviceLockedForUser) {
639 changed = isDeviceLockedInner(userId) != locked;
640 mDeviceLockedForUser.put(userId, locked);
641 }
642 if (changed) {
643 dispatchDeviceLocked(userId, locked);
Adrian Roos481a6df2014-11-20 19:48:56 +0100644 }
645 }
646
647 private void dispatchDeviceLocked(int userId, boolean isLocked) {
648 for (int i = 0; i < mActiveAgents.size(); i++) {
649 AgentInfo agent = mActiveAgents.valueAt(i);
650 if (agent.userId == userId) {
651 if (isLocked) {
652 agent.agent.onDeviceLocked();
653 } else{
654 agent.agent.onDeviceUnlocked();
655 }
656 }
657 }
658 }
659
Marco Fucci4e68f112014-08-29 12:31:48 -0700660 void updateDevicePolicyFeatures() {
Adrian Roos9d6fc922016-08-10 17:09:55 -0700661 boolean changed = false;
Adrian Roos8f211582014-07-29 15:09:57 +0200662 for (int i = 0; i < mActiveAgents.size(); i++) {
663 AgentInfo info = mActiveAgents.valueAt(i);
664 if (info.agent.isConnected()) {
665 info.agent.updateDevicePolicyFeatures();
Adrian Roos9d6fc922016-08-10 17:09:55 -0700666 changed = true;
Adrian Roos8f211582014-07-29 15:09:57 +0200667 }
668 }
Adrian Roos9d6fc922016-08-10 17:09:55 -0700669 if (changed) {
670 mArchive.logDevicePolicyChanged();
671 }
Adrian Roos8f211582014-07-29 15:09:57 +0200672 }
673
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200674 private void removeAgentsOfPackage(String packageName) {
675 boolean trustMayHaveChanged = false;
676 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
677 AgentInfo info = mActiveAgents.valueAt(i);
678 if (packageName.equals(info.component.getPackageName())) {
679 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200680 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200681 trustMayHaveChanged = true;
682 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100683 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200684 mActiveAgents.removeAt(i);
685 }
686 }
687 if (trustMayHaveChanged) {
688 updateTrustAll();
689 }
690 }
691
692 public void resetAgent(ComponentName name, int userId) {
693 boolean trustMayHaveChanged = false;
694 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
695 AgentInfo info = mActiveAgents.valueAt(i);
696 if (name.equals(info.component) && userId == info.userId) {
697 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200698 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200699 trustMayHaveChanged = true;
700 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100701 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200702 mActiveAgents.removeAt(i);
703 }
704 }
705 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700706 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200707 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700708 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200709 }
710
Lingjun Li20914d72016-11-14 15:39:13 -0800711 private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) {
Adrian Roos82142c22014-03-27 14:56:59 +0100712 if (resolveInfo == null || resolveInfo.serviceInfo == null
713 || resolveInfo.serviceInfo.metaData == null) return null;
714 String cn = null;
Lingjun Li20914d72016-11-14 15:39:13 -0800715 boolean canUnlockProfile = false;
716
Adrian Roos82142c22014-03-27 14:56:59 +0100717 XmlResourceParser parser = null;
718 Exception caughtException = null;
719 try {
720 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
721 TrustAgentService.TRUST_AGENT_META_DATA);
722 if (parser == null) {
723 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
724 return null;
725 }
726 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
727 AttributeSet attrs = Xml.asAttributeSet(parser);
728 int type;
729 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
730 && type != XmlPullParser.START_TAG) {
731 // Drain preamble.
732 }
733 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200734 if (!"trust-agent".equals(nodeName)) {
735 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100736 return null;
737 }
738 TypedArray sa = res
739 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
740 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
Lingjun Li20914d72016-11-14 15:39:13 -0800741 canUnlockProfile = sa.getBoolean(
742 com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
Adrian Roos82142c22014-03-27 14:56:59 +0100743 sa.recycle();
744 } catch (PackageManager.NameNotFoundException e) {
745 caughtException = e;
746 } catch (IOException e) {
747 caughtException = e;
748 } catch (XmlPullParserException e) {
749 caughtException = e;
750 } finally {
751 if (parser != null) parser.close();
752 }
753 if (caughtException != null) {
754 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
755 return null;
756 }
757 if (cn == null) {
758 return null;
759 }
760 if (cn.indexOf('/') < 0) {
761 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
762 }
Lingjun Li20914d72016-11-14 15:39:13 -0800763 return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
Adrian Roos82142c22014-03-27 14:56:59 +0100764 }
765
766 private ComponentName getComponentName(ResolveInfo resolveInfo) {
767 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
768 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
769 }
770
Adrian Roos3870d452014-09-05 18:22:28 +0200771 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200772 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
773 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
774 return;
775 }
776 PackageManager pm = mContext.getPackageManager();
777 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700778 ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
779 boolean shouldUseDefaultAgent = defaultAgent != null;
Adrian Roos2f19ad42017-07-05 16:09:22 +0200780 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
Zachary Iqbal666484d2017-03-31 19:10:09 -0700781
782 if (shouldUseDefaultAgent) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200783 discoveredAgents.add(defaultAgent);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700784 Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
785 } else { // A default agent is not set; perform regular trust agent discovery
786 for (ResolveInfo resolveInfo : resolveInfos) {
787 ComponentName componentName = getComponentName(resolveInfo);
788 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
789 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
790 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
791 + "is not a system package.");
792 continue;
793 }
794 discoveredAgents.add(componentName);
Adrian Roos3870d452014-09-05 18:22:28 +0200795 }
Adrian Roos3870d452014-09-05 18:22:28 +0200796 }
Adrian Roos2f19ad42017-07-05 16:09:22 +0200797
798 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
799 if (previouslyEnabledAgents != null) {
800 discoveredAgents.addAll(previouslyEnabledAgents);
801 }
802 utils.setEnabledTrustAgents(discoveredAgents, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200803 Settings.Secure.putIntForUser(mContext.getContentResolver(),
804 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
805 }
806
Zachary Iqbal666484d2017-03-31 19:10:09 -0700807 /**
808 * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
809 * is no trust agent set.
810 */
811 private static ComponentName getDefaultFactoryTrustAgent(Context context) {
812 String defaultTrustAgent = context.getResources()
813 .getString(com.android.internal.R.string.config_defaultTrustAgent);
814 if (TextUtils.isEmpty(defaultTrustAgent)) {
815 return null;
816 }
817 return ComponentName.unflattenFromString(defaultTrustAgent);
818 }
819
Adrian Roos3870d452014-09-05 18:22:28 +0200820 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
821 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
Lingjun Li20914d72016-11-14 15:39:13 -0800822 PackageManager.GET_META_DATA |
Adrian Roos68771eb2016-05-03 14:02:36 -0700823 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
824 userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200825 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
826 for (ResolveInfo resolveInfo : resolveInfos) {
827 if (resolveInfo.serviceInfo == null) continue;
828 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
829 String packageName = resolveInfo.serviceInfo.packageName;
830 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
831 != PackageManager.PERMISSION_GRANTED) {
832 ComponentName name = getComponentName(resolveInfo);
833 Log.w(TAG, "Skipping agent " + name + " because package does not have"
834 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
835 continue;
836 }
837 allowedAgents.add(resolveInfo);
838 }
839 return allowedAgents;
840 }
841
Adrian Roos82142c22014-03-27 14:56:59 +0100842 // Agent dispatch and aggregation
843
844 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700845 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200846 return false;
847 }
Adrian Roos82142c22014-03-27 14:56:59 +0100848 for (int i = 0; i < mActiveAgents.size(); i++) {
849 AgentInfo info = mActiveAgents.valueAt(i);
850 if (info.userId == userId) {
851 if (info.agent.isTrusted()) {
852 return true;
853 }
854 }
855 }
856 return false;
857 }
858
Adrian Roos7861c662014-07-25 15:37:28 +0200859 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700860 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200861 return false;
862 }
863 for (int i = 0; i < mActiveAgents.size(); i++) {
864 AgentInfo info = mActiveAgents.valueAt(i);
865 if (info.userId == userId) {
866 if (info.agent.isManagingTrust()) {
867 return true;
868 }
869 }
870 }
871 return false;
872 }
873
Adrian Roos82142c22014-03-27 14:56:59 +0100874 private void dispatchUnlockAttempt(boolean successful, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800875 if (successful) {
876 mStrongAuthTracker.allowTrustFromUnlock(userId);
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800877 // Allow the presence of trust on a successful unlock attempt to extend unlock.
878 updateTrust(userId, 0 /* flags */, true);
Adrian Roos517b3a42016-03-03 14:58:33 -0800879 }
880
Adrian Roos82142c22014-03-27 14:56:59 +0100881 for (int i = 0; i < mActiveAgents.size(); i++) {
882 AgentInfo info = mActiveAgents.valueAt(i);
883 if (info.userId == userId) {
884 info.agent.onUnlockAttempt(successful);
885 }
886 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200887 }
888
Zachary Iqbal327323d2017-01-12 14:41:13 -0800889 private void dispatchUnlockLockout(int timeoutMs, int userId) {
890 for (int i = 0; i < mActiveAgents.size(); i++) {
891 AgentInfo info = mActiveAgents.valueAt(i);
892 if (info.userId == userId) {
893 info.agent.onUnlockLockout(timeoutMs);
894 }
895 }
896 }
897
Adrian Roos82142c22014-03-27 14:56:59 +0100898 // Listeners
899
900 private void addListener(ITrustListener listener) {
901 for (int i = 0; i < mTrustListeners.size(); i++) {
902 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
903 return;
904 }
905 }
906 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200907 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100908 }
909
910 private void removeListener(ITrustListener listener) {
911 for (int i = 0; i < mTrustListeners.size(); i++) {
912 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700913 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100914 return;
915 }
916 }
917 }
918
Adrian Roos94e15a52015-04-16 12:23:18 -0700919 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800920 if (DEBUG) {
921 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
922 + Integer.toHexString(flags) + ")");
923 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700924 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100925 for (int i = 0; i < mTrustListeners.size(); i++) {
926 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700927 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200928 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200929 Slog.d(TAG, "Removing dead TrustListener.");
930 mTrustListeners.remove(i);
931 i--;
932 } catch (RemoteException e) {
933 Slog.e(TAG, "Exception while notifying TrustListener.", e);
934 }
935 }
936 }
937
938 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800939 if (DEBUG) {
940 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
941 }
Adrian Roos7861c662014-07-25 15:37:28 +0200942 for (int i = 0; i < mTrustListeners.size(); i++) {
943 try {
944 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
945 } catch (DeadObjectException e) {
946 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200947 mTrustListeners.remove(i);
948 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100949 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200950 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100951 }
952 }
953 }
954
Lucas Dupinef886542018-01-03 16:03:07 -0800955 private void dispatchOnTrustError(CharSequence message) {
956 if (DEBUG) {
957 Log.i(TAG, "onTrustError(" + message + ")");
958 }
959 for (int i = 0; i < mTrustListeners.size(); i++) {
960 try {
961 mTrustListeners.get(i).onTrustError(message);
962 } catch (DeadObjectException e) {
963 Slog.d(TAG, "Removing dead TrustListener.");
964 mTrustListeners.remove(i);
965 i--;
966 } catch (RemoteException e) {
967 Slog.e(TAG, "Exception while notifying TrustListener.", e);
968 }
969 }
970 }
971
Adrian Rooscbe614f2014-10-28 20:16:12 +0100972 // User lifecycle
973
974 @Override
975 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100976 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100977 }
978
979 @Override
980 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100981 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
982 }
983
984 @Override
985 public void onSwitchUser(int userId) {
986 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100987 }
988
Adrian Roos68771eb2016-05-03 14:02:36 -0700989 @Override
990 public void onUnlockUser(int userId) {
991 mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
992 }
993
Andrew Scull85a63bc2016-10-24 13:47:47 +0100994 @Override
995 public void onStopUser(@UserIdInt int userId) {
996 mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
997 }
998
Adrian Roos82142c22014-03-27 14:56:59 +0100999 // Plumbing
1000
1001 private final IBinder mService = new ITrustManager.Stub() {
1002 @Override
1003 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
1004 enforceReportPermission();
1005 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
1006 .sendToTarget();
1007 }
1008
1009 @Override
Zachary Iqbal327323d2017-01-12 14:41:13 -08001010 public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
1011 enforceReportPermission();
1012 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
1013 .sendToTarget();
1014 }
1015
1016 @Override
Adrian Roos82142c22014-03-27 14:56:59 +01001017 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
1018 enforceReportPermission();
1019 // coalesce refresh messages.
1020 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
1021 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
1022 }
1023
1024 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +01001025 public void reportKeyguardShowingChanged() throws RemoteException {
1026 enforceReportPermission();
1027 // coalesce refresh messages.
1028 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
1029 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
Jorim Jaggi5277dea2017-05-18 02:05:29 +02001030
1031 // Make sure handler processes the message before returning, such that isDeviceLocked
1032 // after this call will retrieve the correct value.
1033 mHandler.runWithScissors(() -> {}, 0);
Adrian Roos481a6df2014-11-20 19:48:56 +01001034 }
1035
1036 @Override
Adrian Roos82142c22014-03-27 14:56:59 +01001037 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
1038 enforceListenerPermission();
1039 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
1040 }
1041
1042 @Override
1043 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
1044 enforceListenerPermission();
1045 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
1046 }
1047
Adrian Roosbcd07652014-10-22 16:57:16 +02001048 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +01001049 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +02001050 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +01001051 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +01001052
Clara Bayarri078e91b2016-01-15 16:57:35 +00001053 long token = Binder.clearCallingIdentity();
1054 try {
1055 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
1056 userId = resolveProfileParent(userId);
1057 }
1058 return isDeviceLockedInner(userId);
1059 } finally {
1060 Binder.restoreCallingIdentity(token);
1061 }
Adrian Roosbcd07652014-10-22 16:57:16 +02001062 }
1063
Adrian Roos82893682015-04-02 16:17:46 +02001064 @Override
1065 public boolean isDeviceSecure(int userId) throws RemoteException {
1066 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
1067 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +02001068
1069 long token = Binder.clearCallingIdentity();
1070 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +00001071 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
1072 userId = resolveProfileParent(userId);
1073 }
Clara Bayarria1771112015-12-18 16:29:18 +00001074 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +02001075 } finally {
1076 Binder.restoreCallingIdentity(token);
1077 }
1078 }
1079
Adrian Roos82142c22014-03-27 14:56:59 +01001080 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +02001081 mContext.enforceCallingOrSelfPermission(
1082 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +01001083 }
1084
1085 private void enforceListenerPermission() {
1086 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1087 "register trust listener");
1088 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001089
1090 @Override
1091 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001092 if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
Adrian Roos49d53452014-10-24 15:48:39 +02001093 if (isSafeMode()) {
1094 fout.println("disabled because the system is in safe mode.");
1095 return;
1096 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001097 if (!mTrustAgentsCanRun) {
1098 fout.println("disabled because the third-party apps can't run yet.");
1099 return;
1100 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001101 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001102 mHandler.runWithScissors(new Runnable() {
1103 @Override
1104 public void run() {
1105 fout.println("Trust manager state:");
1106 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001107 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001108 }
1109 }
1110 }, 1500);
1111 }
1112
1113 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
1114 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
1115 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -07001116 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001117 fout.println("(managed profile)");
1118 fout.println(" disabled because switching to this user is not possible.");
1119 return;
1120 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001121 if (isCurrent) {
1122 fout.print(" (current)");
1123 }
1124 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +02001125 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +01001126 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -07001127 fout.print(", strongAuthRequired=" + dumpHex(
1128 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001129 fout.println();
1130 fout.println(" Enabled agents:");
1131 boolean duplicateSimpleNames = false;
1132 ArraySet<String> simpleNames = new ArraySet<String>();
1133 for (AgentInfo info : mActiveAgents) {
1134 if (info.userId != user.id) { continue; }
1135 boolean trusted = info.agent.isTrusted();
1136 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001137 fout.print(" bound=" + dumpBool(info.agent.isBound()));
1138 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +02001139 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
1140 fout.print(", trusted=" + dumpBool(trusted));
1141 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001142 if (trusted) {
1143 fout.println(" message=\"" + info.agent.getMessage() + "\"");
1144 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001145 if (!info.agent.isConnected()) {
1146 String restartTime = TrustArchive.formatDuration(
1147 info.agent.getScheduledRestartUptimeMillis()
1148 - SystemClock.uptimeMillis());
1149 fout.println(" restartScheduledAt=" + restartTime);
1150 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001151 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
1152 duplicateSimpleNames = true;
1153 }
1154 }
1155 fout.println(" Events:");
1156 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
1157 fout.println();
1158 }
1159
1160 private String dumpBool(boolean b) {
1161 return b ? "1" : "0";
1162 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001163
1164 private String dumpHex(int i) {
1165 return "0x" + Integer.toHexString(i);
1166 }
Clara Bayarri56878a92015-10-29 15:43:55 +00001167
1168 @Override
Rubin Xu83a15bc2016-08-10 10:53:24 +01001169 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarri00a9b892016-01-13 16:17:09 +00001170 enforceReportPermission();
Rubin Xue0781332016-08-19 11:20:34 +01001171 final long identity = Binder.clearCallingIdentity();
1172 try {
Pavel Grafov259ca362018-07-27 14:04:57 +01001173 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
1174 && mLockPatternUtils.isSecure(userId)) {
Rubin Xue0781332016-08-19 11:20:34 +01001175 synchronized (mDeviceLockedForUser) {
1176 mDeviceLockedForUser.put(userId, locked);
1177 }
1178 if (locked) {
1179 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001180 ActivityManager.getService().notifyLockedProfile(userId);
Rubin Xue0781332016-08-19 11:20:34 +01001181 } catch (RemoteException e) {
1182 }
Rubin Xu83a15bc2016-08-10 10:53:24 +01001183 }
Robin Lee92b83c62016-08-31 13:27:51 +01001184 final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
1185 lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1186 lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1187 mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
1188 Manifest.permission.TRUST_LISTENER, /* options */ null);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001189 }
Rubin Xue0781332016-08-19 11:20:34 +01001190 } finally {
1191 Binder.restoreCallingIdentity(identity);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001192 }
Clara Bayarri56878a92015-10-29 15:43:55 +00001193 }
Adrian Roosc13723f2016-01-12 20:29:03 +01001194
1195 @Override
1196 public boolean isTrustUsuallyManaged(int userId) {
1197 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1198 "query trust state");
1199 return isTrustUsuallyManagedInternal(userId);
1200 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001201
1202 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001203 public void unlockedByBiometricForUser(int userId, BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001204 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001205 synchronized(mUsersUnlockedByBiometric) {
1206 mUsersUnlockedByBiometric.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001207 }
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001208 // In extend unlock mode we need to refresh trust state here, which will call
1209 // refreshDeviceLockedForUser()
1210 int updateTrustOnUnlock = mSettingsObserver.getTrustAgentsExtendUnlock() ? 1 : 0;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001211 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001212 updateTrustOnUnlock).sendToTarget();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001213 }
1214
1215 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001216 public void clearAllBiometricRecognized(BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001217 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001218 synchronized(mUsersUnlockedByBiometric) {
1219 mUsersUnlockedByBiometric.clear();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001220 }
1221 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
1222 0 /* arg2 */).sendToTarget();
1223 }
Adrian Roos82142c22014-03-27 14:56:59 +01001224 };
1225
Adrian Roosc13723f2016-01-12 20:29:03 +01001226 private boolean isTrustUsuallyManagedInternal(int userId) {
1227 synchronized (mTrustUsuallyManagedForUser) {
1228 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1229 if (i >= 0) {
1230 return mTrustUsuallyManagedForUser.valueAt(i);
1231 }
1232 }
1233 // It's not in memory yet, get the value from persisted storage instead
1234 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
1235 synchronized (mTrustUsuallyManagedForUser) {
1236 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1237 if (i >= 0) {
1238 // Someone set the trust usually managed in the mean time. Better use that.
1239 return mTrustUsuallyManagedForUser.valueAt(i);
1240 } else {
1241 // .. otherwise it's safe to cache the fetched value now.
1242 mTrustUsuallyManagedForUser.put(userId, persistedValue);
1243 return persistedValue;
1244 }
1245 }
1246 }
1247
Adrian Roosbcd07652014-10-22 16:57:16 +02001248 private int resolveProfileParent(int userId) {
1249 long identity = Binder.clearCallingIdentity();
1250 try {
1251 UserInfo parent = mUserManager.getProfileParent(userId);
1252 if (parent != null) {
1253 return parent.getUserHandle().getIdentifier();
1254 }
1255 return userId;
1256 } finally {
1257 Binder.restoreCallingIdentity(identity);
1258 }
1259 }
1260
Adrian Roos82142c22014-03-27 14:56:59 +01001261 private final Handler mHandler = new Handler() {
1262 @Override
1263 public void handleMessage(Message msg) {
1264 switch (msg.what) {
1265 case MSG_REGISTER_LISTENER:
1266 addListener((ITrustListener) msg.obj);
1267 break;
1268 case MSG_UNREGISTER_LISTENER:
1269 removeListener((ITrustListener) msg.obj);
1270 break;
1271 case MSG_DISPATCH_UNLOCK_ATTEMPT:
1272 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
1273 break;
Zachary Iqbal327323d2017-01-12 14:41:13 -08001274 case MSG_DISPATCH_UNLOCK_LOCKOUT:
1275 dispatchUnlockLockout(msg.arg1, msg.arg2);
1276 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001277 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -07001278 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +01001279 // This is also called when the security mode of a user changes.
1280 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001281 break;
Adrian Roos481a6df2014-11-20 19:48:56 +01001282 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +01001283 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +01001284 break;
1285 case MSG_START_USER:
1286 case MSG_CLEANUP_USER:
Adrian Roos68771eb2016-05-03 14:02:36 -07001287 case MSG_UNLOCK_USER:
Adrian Roos481a6df2014-11-20 19:48:56 +01001288 refreshAgentList(msg.arg1);
1289 break;
1290 case MSG_SWITCH_USER:
1291 mCurrentUser = msg.arg1;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001292 mSettingsObserver.updateContentObserver();
Adrian Roos481a6df2014-11-20 19:48:56 +01001293 refreshDeviceLockedForUser(UserHandle.USER_ALL);
1294 break;
Andrew Scull85a63bc2016-10-24 13:47:47 +01001295 case MSG_STOP_USER:
1296 setDeviceLockedForUser(msg.arg1, true);
1297 break;
Adrian Roosc13723f2016-01-12 20:29:03 +01001298 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
1299 SparseBooleanArray usuallyManaged;
1300 synchronized (mTrustUsuallyManagedForUser) {
1301 usuallyManaged = mTrustUsuallyManagedForUser.clone();
1302 }
1303
1304 for (int i = 0; i < usuallyManaged.size(); i++) {
1305 int userId = usuallyManaged.keyAt(i);
1306 boolean value = usuallyManaged.valueAt(i);
1307 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
1308 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
1309 }
1310 }
Adrian Roos68771eb2016-05-03 14:02:36 -07001311 break;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001312 case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001313 if (msg.arg2 == 1) {
1314 updateTrust(msg.arg1, 0 /* flags */, true);
1315 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001316 refreshDeviceLockedForUser(msg.arg1);
1317 break;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001318 case MSG_SCHEDULE_TRUST_TIMEOUT:
1319 handleScheduleTrustTimeout(msg.arg1, msg.arg2);
1320 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001321 }
1322 }
1323 };
1324
1325 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1326 @Override
1327 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -07001328 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001329 }
1330
1331 @Override
1332 public boolean onPackageChanged(String packageName, int uid, String[] components) {
1333 // We're interested in all changes, even if just some components get enabled / disabled.
1334 return true;
1335 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001336
1337 @Override
1338 public void onPackageDisappeared(String packageName, int reason) {
1339 removeAgentsOfPackage(packageName);
1340 }
Adrian Roos82142c22014-03-27 14:56:59 +01001341 };
Adrian Roosca36b952014-05-16 18:52:29 +02001342
Lingjun Li20914d72016-11-14 15:39:13 -08001343 private static class SettingsAttrs {
1344 public ComponentName componentName;
1345 public boolean canUnlockProfile;
1346
1347 public SettingsAttrs(
1348 ComponentName componentName,
1349 boolean canUnlockProfile) {
1350 this.componentName = componentName;
1351 this.canUnlockProfile = canUnlockProfile;
1352 }
1353 };
1354
Adrian Roos9dbe1902014-08-13 18:25:52 +02001355 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +02001356
1357 @Override
1358 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +02001359 String action = intent.getAction();
1360 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -07001361 refreshAgentList(getSendingUserId());
1362 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +02001363 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +01001364 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +02001365 if (userId > 0) {
1366 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +02001367 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001368 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
1369 int userId = getUserId(intent);
1370 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001371 synchronized (mUserIsTrusted) {
1372 mUserIsTrusted.delete(userId);
1373 }
1374 synchronized (mDeviceLockedForUser) {
1375 mDeviceLockedForUser.delete(userId);
1376 }
Adrian Roosae025822016-11-03 14:46:13 -07001377 synchronized (mTrustUsuallyManagedForUser) {
1378 mTrustUsuallyManagedForUser.delete(userId);
1379 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001380 synchronized (mUsersUnlockedByBiometric) {
1381 mUsersUnlockedByBiometric.delete(userId);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001382 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001383 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +01001384 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001385 }
1386 }
1387 }
1388
1389 private int getUserId(Intent intent) {
1390 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
1391 if (userId > 0) {
1392 return userId;
1393 } else {
1394 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
1395 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +02001396 }
1397 }
1398
1399 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +02001400 IntentFilter filter = new IntentFilter();
1401 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Adrian Roos3870d452014-09-05 18:22:28 +02001402 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001403 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +02001404 context.registerReceiverAsUser(this,
1405 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +02001406 filter,
Adrian Roosca36b952014-05-16 18:52:29 +02001407 null /* permission */,
1408 null /* scheduler */);
1409 }
1410 }
Adrian Roos517b3a42016-03-03 14:58:33 -08001411
1412 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1413
1414 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1415
1416 public StrongAuthTracker(Context context) {
1417 super(context);
1418 }
1419
1420 @Override
1421 public void onStrongAuthRequiredChanged(int userId) {
1422 mStartFromSuccessfulUnlock.delete(userId);
1423
1424 if (DEBUG) {
1425 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1426 + " trustAllowed=" + isTrustAllowedForUser(userId)
1427 + " agentsCanRun=" + canAgentsRunForUser(userId));
1428 }
1429
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001430 // Cancel pending alarms if we require some auth anyway.
1431 if (!isTrustAllowedForUser(userId)) {
1432 TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
1433 if (alarm != null && alarm.isQueued()) {
1434 alarm.setQueued(false /* isQueued */);
1435 mAlarmManager.cancel(alarm);
1436 }
1437 }
1438
Adrian Roos517b3a42016-03-03 14:58:33 -08001439 refreshAgentList(userId);
1440
1441 // The list of active trust agents may not have changed, if there was a previous call
1442 // to allowTrustFromUnlock, so we update the trust here too.
1443 updateTrust(userId, 0 /* flags */);
1444 }
1445
1446 boolean canAgentsRunForUser(int userId) {
1447 return mStartFromSuccessfulUnlock.get(userId)
1448 || super.isTrustAllowedForUser(userId);
1449 }
1450
1451 /**
1452 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1453 * changes again. Must only be called when we know about a successful unlock already
1454 * before the underlying StrongAuthTracker.
1455 *
1456 * Note that this only changes whether trust agents can be started, not the actual trusted
1457 * value.
1458 */
1459 void allowTrustFromUnlock(int userId) {
1460 if (userId < UserHandle.USER_SYSTEM) {
1461 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1462 }
1463 boolean previous = canAgentsRunForUser(userId);
1464 mStartFromSuccessfulUnlock.put(userId, true);
1465
1466 if (DEBUG) {
1467 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1468 + " trustAllowed=" + isTrustAllowedForUser(userId)
1469 + " agentsCanRun=" + canAgentsRunForUser(userId));
1470 }
1471
1472 if (canAgentsRunForUser(userId) != previous) {
1473 refreshAgentList(userId);
1474 }
1475 }
1476 }
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001477
1478 private class TrustTimeoutAlarmListener implements OnAlarmListener {
1479 private final int mUserId;
1480 private boolean mIsQueued = false;
1481
1482 TrustTimeoutAlarmListener(int userId) {
1483 mUserId = userId;
1484 }
1485
1486 @Override
1487 public void onAlarm() {
1488 mIsQueued = false;
1489 int strongAuthState = mStrongAuthTracker.getStrongAuthForUser(mUserId);
1490
1491 // Only fire if trust can unlock.
1492 if (mStrongAuthTracker.isTrustAllowedForUser(mUserId)) {
1493 if (DEBUG) Slog.d(TAG, "Revoking all trust because of trust timeout");
1494 mLockPatternUtils.requireStrongAuth(
1495 mStrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, mUserId);
1496 }
1497 maybeLockScreen(mUserId);
1498 }
1499
1500 public void setQueued(boolean isQueued) {
1501 mIsQueued = isQueued;
1502 }
1503
1504 public boolean isQueued() {
1505 return mIsQueued;
1506 }
1507 }
Adrian Roos82142c22014-03-27 14:56:59 +01001508}