blob: 3a390536b43880ff4c672fe57a7253d205b6ee21 [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
Adrian Roos481a6df2014-11-20 19:48:56 +0100369 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200370 synchronized (mUserIsTrusted) {
Chad Brubakerc4c52572019-02-17 13:34:02 -0800371 if (mSettingsObserver.getTrustAgentsExtendUnlock()) {
372 // In extend unlock trust agents can only set the device to trusted if it already
373 // trusted or the device is unlocked. Attempting to set the device as trusted
374 // when the device is locked will be ignored.
375 changed = mUserIsTrusted.get(userId) != trusted;
376 trusted = trusted
377 && (!showingKeyguard || isFromUnlock || !changed)
378 && userId == mCurrentUser;
379 if (DEBUG) {
380 Slog.d(TAG, "Extend unlock setting trusted as " + Boolean.toString(trusted)
381 + " && " + Boolean.toString(!showingKeyguard)
382 + " && " + Boolean.toString(userId == mCurrentUser));
383 }
384 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100385 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200386 mUserIsTrusted.put(userId, trusted);
387 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700388 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100389 if (changed) {
390 refreshDeviceLockedForUser(userId);
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800391 if (!trusted) {
392 maybeLockScreen(userId);
393 } else {
394 scheduleTrustTimeout(userId, false /* override */);
395 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100396 }
Adrian Roos82142c22014-03-27 14:56:59 +0100397 }
398
Adrian Roosc13723f2016-01-12 20:29:03 +0100399 private void updateTrustUsuallyManaged(int userId, boolean managed) {
400 synchronized (mTrustUsuallyManagedForUser) {
401 mTrustUsuallyManagedForUser.put(userId, managed);
402 }
403 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
404 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
405 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
406 mHandler.sendMessageDelayed(
407 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
408 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
409 }
410
Lingjun Li93a145f2017-01-23 17:13:35 -0800411 public long addEscrowToken(byte[] token, int userId) {
Ram Periathiruvadi32d53552019-02-19 13:25:46 -0800412 return mLockPatternUtils.addEscrowToken(token, userId,
413 (long handle, int userid) -> {
414 dispatchEscrowTokenActivatedLocked(handle, userid);
415 });
Lingjun Li93a145f2017-01-23 17:13:35 -0800416 }
417
418 public boolean removeEscrowToken(long handle, int userId) {
419 return mLockPatternUtils.removeEscrowToken(handle, userId);
420 }
421
422 public boolean isEscrowTokenActive(long handle, int userId) {
423 return mLockPatternUtils.isEscrowTokenActive(handle, userId);
424 }
425
426 public void unlockUserWithToken(long handle, byte[] token, int userId) {
427 mLockPatternUtils.unlockUserWithToken(handle, token, userId);
428 }
429
Lucas Dupinef886542018-01-03 16:03:07 -0800430 void showKeyguardErrorMessage(CharSequence message) {
431 dispatchOnTrustError(message);
432 }
433
Adrian Roos517b3a42016-03-03 14:58:33 -0800434 void refreshAgentList(int userIdOrAll) {
435 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100436 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200437 return;
438 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800439 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
440 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
Adrian Roose681c272014-09-08 14:03:47 +0200441 + " must be USER_ALL or a specific user.", new Throwable("here"));
Adrian Roos517b3a42016-03-03 14:58:33 -0800442 userIdOrAll = UserHandle.USER_ALL;
Adrian Roose681c272014-09-08 14:03:47 +0200443 }
Adrian Roos82142c22014-03-27 14:56:59 +0100444 PackageManager pm = mContext.getPackageManager();
445
Marco Fucci4e68f112014-08-29 12:31:48 -0700446 List<UserInfo> userInfos;
Adrian Roos517b3a42016-03-03 14:58:33 -0800447 if (userIdOrAll == UserHandle.USER_ALL) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700448 userInfos = mUserManager.getUsers(true /* excludeDying */);
449 } else {
450 userInfos = new ArrayList<>();
Adrian Roos517b3a42016-03-03 14:58:33 -0800451 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
Marco Fucci4e68f112014-08-29 12:31:48 -0700452 }
Adrian Roos3870d452014-09-05 18:22:28 +0200453 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100454
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200455 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
456 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100457
458 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100459 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
460 || userInfo.guestToRemove) continue;
Adrian Roos5d639782016-07-21 11:43:02 -0700461 if (!userInfo.supportsSwitchToByUser()) {
462 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
463 + ": switchToByUser=false");
464 continue;
465 }
Adrian Roos5d639782016-07-21 11:43:02 -0700466 if (!mActivityManager.isUserRunning(userInfo.id)) {
467 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
468 + ": user not started");
469 continue;
470 }
471 if (!lockPatternUtils.isSecure(userInfo.id)) {
472 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
473 + ": no secure credential");
474 continue;
475 }
Lingjun Li20914d72016-11-14 15:39:13 -0800476
Adrian Roos8f211582014-07-29 15:09:57 +0200477 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
478 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700479 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200480 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
481
Adrian Roos82142c22014-03-27 14:56:59 +0100482 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200483 if (enabledAgents == null) {
Adrian Roos5d639782016-07-21 11:43:02 -0700484 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
485 + ": no agents enabled by user");
Adrian Roos82142c22014-03-27 14:56:59 +0100486 continue;
487 }
Adrian Roos3870d452014-09-05 18:22:28 +0200488 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100489 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100490 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100491
Adrian Roos5d639782016-07-21 11:43:02 -0700492 if (!enabledAgents.contains(name)) {
493 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
494 + name.flattenToShortString() + " u"+ userInfo.id
495 + ": not enabled by user");
496 continue;
497 }
Adrian Roos8f211582014-07-29 15:09:57 +0200498 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700499 List<PersistableBundle> config =
500 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200501 // Disable agent if no features are enabled.
Adrian Roos5d639782016-07-21 11:43:02 -0700502 if (config == null || config.isEmpty()) {
503 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
504 + name.flattenToShortString() + " u"+ userInfo.id
505 + ": not allowed by DPM");
506 continue;
507 }
Adrian Roos8f211582014-07-29 15:09:57 +0200508 }
Adrian Roos82142c22014-03-27 14:56:59 +0100509 AgentInfo agentInfo = new AgentInfo();
510 agentInfo.component = name;
511 agentInfo.userId = userInfo.id;
512 if (!mActiveAgents.contains(agentInfo)) {
513 agentInfo.label = resolveInfo.loadLabel(pm);
514 agentInfo.icon = resolveInfo.loadIcon(pm);
Lingjun Li20914d72016-11-14 15:39:13 -0800515 agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
Lingjun Li20914d72016-11-14 15:39:13 -0800516 } else {
517 int index = mActiveAgents.indexOf(agentInfo);
518 agentInfo = mActiveAgents.valueAt(index);
519 }
520
521 boolean directUnlock = resolveInfo.serviceInfo.directBootAware
522 && agentInfo.settings.canUnlockProfile;
523
524 if (directUnlock) {
525 if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
526 + "of user " + userInfo.id + "can unlock user profile.");
527 }
528
Jeff Sharkeya65e6492017-06-21 13:45:11 -0600529 if (!mUserManager.isUserUnlockingOrUnlocked(userInfo.id)
Lingjun Li20914d72016-11-14 15:39:13 -0800530 && !directUnlock) {
531 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
Lingjun Li93a145f2017-01-23 17:13:35 -0800532 + "'s trust agent " + name + ": FBE still locked and "
Lingjun Li20914d72016-11-14 15:39:13 -0800533 + " the agent cannot unlock user profile.");
534 continue;
535 }
536
537 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
538 int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
Zachary Iqbal327323d2017-01-12 14:41:13 -0800539 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
540 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
541 || !directUnlock) {
542 if (DEBUG)
543 Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
544 + ": prevented by StrongAuthTracker = 0x"
545 + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
546 userInfo.id)));
547 continue;
548 }
Lingjun Li20914d72016-11-14 15:39:13 -0800549 }
550 }
551
Adrian Roosb884bb22017-05-03 11:33:51 -0700552 if (agentInfo.agent == null) {
553 agentInfo.agent = new TrustAgentWrapper(mContext, this,
554 new Intent().setComponent(name), userInfo.getUserHandle());
555 }
556
Lingjun Li20914d72016-11-14 15:39:13 -0800557 if (!mActiveAgents.contains(agentInfo)) {
Adrian Roos82142c22014-03-27 14:56:59 +0100558 mActiveAgents.add(agentInfo);
559 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200560 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100561 }
562 }
563 }
564
565 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200566 for (int i = 0; i < obsoleteAgents.size(); i++) {
567 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roos517b3a42016-03-03 14:58:33 -0800568 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
Adrian Roose681c272014-09-08 14:03:47 +0200569 if (info.agent.isManagingTrust()) {
570 trustMayHaveChanged = true;
571 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100572 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200573 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100574 }
Adrian Roos82142c22014-03-27 14:56:59 +0100575 }
576
577 if (trustMayHaveChanged) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800578 if (userIdOrAll == UserHandle.USER_ALL) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100579 updateTrustAll();
580 } else {
Adrian Roos517b3a42016-03-03 14:58:33 -0800581 updateTrust(userIdOrAll, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100582 }
Adrian Roos82142c22014-03-27 14:56:59 +0100583 }
584 }
585
Adrian Roos481a6df2014-11-20 19:48:56 +0100586 boolean isDeviceLockedInner(int userId) {
587 synchronized (mDeviceLockedForUser) {
588 return mDeviceLockedForUser.get(userId, true);
589 }
590 }
591
592 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700593 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100594 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100595 + " must be USER_ALL or a specific user.", new Throwable("here"));
596 userId = UserHandle.USER_ALL;
597 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100598 List<UserInfo> userInfos;
599 if (userId == UserHandle.USER_ALL) {
600 userInfos = mUserManager.getUsers(true /* excludeDying */);
601 } else {
602 userInfos = new ArrayList<>();
603 userInfos.add(mUserManager.getUserInfo(userId));
604 }
605
606 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
607
608 for (int i = 0; i < userInfos.size(); i++) {
609 UserInfo info = userInfos.get(i);
610
Pavel Grafov259ca362018-07-27 14:04:57 +0100611 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100612 continue;
613 }
614
615 int id = info.id;
616 boolean secure = mLockPatternUtils.isSecure(id);
Pavel Grafov259ca362018-07-27 14:04:57 +0100617
618 if (!info.supportsSwitchToByUser()) {
619 if (info.isManagedProfile() && !secure) {
620 setDeviceLockedForUser(id, false);
621 }
622 continue;
623 }
624
Adrian Roos481a6df2014-11-20 19:48:56 +0100625 boolean trusted = aggregateIsTrusted(id);
626 boolean showingKeyguard = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200627 boolean biometricAuthenticated = false;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700628
Adrian Roos481a6df2014-11-20 19:48:56 +0100629 if (mCurrentUser == id) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200630 synchronized(mUsersUnlockedByBiometric) {
631 biometricAuthenticated = mUsersUnlockedByBiometric.get(id, false);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700632 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100633 try {
634 showingKeyguard = wm.isKeyguardLocked();
635 } catch (RemoteException e) {
636 }
637 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700638 boolean deviceLocked = secure && showingKeyguard && !trusted &&
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200639 !biometricAuthenticated;
Andrew Scull85a63bc2016-10-24 13:47:47 +0100640 setDeviceLockedForUser(id, deviceLocked);
641 }
642 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100643
Andrew Scull85a63bc2016-10-24 13:47:47 +0100644 private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
645 final boolean changed;
646 synchronized (mDeviceLockedForUser) {
647 changed = isDeviceLockedInner(userId) != locked;
648 mDeviceLockedForUser.put(userId, locked);
649 }
650 if (changed) {
651 dispatchDeviceLocked(userId, locked);
Adrian Roos481a6df2014-11-20 19:48:56 +0100652 }
653 }
654
655 private void dispatchDeviceLocked(int userId, boolean isLocked) {
656 for (int i = 0; i < mActiveAgents.size(); i++) {
657 AgentInfo agent = mActiveAgents.valueAt(i);
658 if (agent.userId == userId) {
659 if (isLocked) {
660 agent.agent.onDeviceLocked();
661 } else{
662 agent.agent.onDeviceUnlocked();
663 }
664 }
665 }
666 }
667
Ram Periathiruvadi32d53552019-02-19 13:25:46 -0800668 private void dispatchEscrowTokenActivatedLocked(long handle, int userId) {
669 for (int i = 0; i < mActiveAgents.size(); i++) {
670 AgentInfo agent = mActiveAgents.valueAt(i);
671 if (agent.userId == userId) {
672 agent.agent.onEscrowTokenActivated(handle, userId);
673 }
674 }
675 }
676
Marco Fucci4e68f112014-08-29 12:31:48 -0700677 void updateDevicePolicyFeatures() {
Adrian Roos9d6fc922016-08-10 17:09:55 -0700678 boolean changed = false;
Adrian Roos8f211582014-07-29 15:09:57 +0200679 for (int i = 0; i < mActiveAgents.size(); i++) {
680 AgentInfo info = mActiveAgents.valueAt(i);
681 if (info.agent.isConnected()) {
682 info.agent.updateDevicePolicyFeatures();
Adrian Roos9d6fc922016-08-10 17:09:55 -0700683 changed = true;
Adrian Roos8f211582014-07-29 15:09:57 +0200684 }
685 }
Adrian Roos9d6fc922016-08-10 17:09:55 -0700686 if (changed) {
687 mArchive.logDevicePolicyChanged();
688 }
Adrian Roos8f211582014-07-29 15:09:57 +0200689 }
690
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200691 private void removeAgentsOfPackage(String packageName) {
692 boolean trustMayHaveChanged = false;
693 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
694 AgentInfo info = mActiveAgents.valueAt(i);
695 if (packageName.equals(info.component.getPackageName())) {
696 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200697 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200698 trustMayHaveChanged = true;
699 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100700 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200701 mActiveAgents.removeAt(i);
702 }
703 }
704 if (trustMayHaveChanged) {
705 updateTrustAll();
706 }
707 }
708
709 public void resetAgent(ComponentName name, int userId) {
710 boolean trustMayHaveChanged = false;
711 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
712 AgentInfo info = mActiveAgents.valueAt(i);
713 if (name.equals(info.component) && userId == info.userId) {
714 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200715 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200716 trustMayHaveChanged = true;
717 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100718 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200719 mActiveAgents.removeAt(i);
720 }
721 }
722 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700723 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200724 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700725 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200726 }
727
Lingjun Li20914d72016-11-14 15:39:13 -0800728 private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) {
Adrian Roos82142c22014-03-27 14:56:59 +0100729 if (resolveInfo == null || resolveInfo.serviceInfo == null
730 || resolveInfo.serviceInfo.metaData == null) return null;
731 String cn = null;
Lingjun Li20914d72016-11-14 15:39:13 -0800732 boolean canUnlockProfile = false;
733
Adrian Roos82142c22014-03-27 14:56:59 +0100734 XmlResourceParser parser = null;
735 Exception caughtException = null;
736 try {
737 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
738 TrustAgentService.TRUST_AGENT_META_DATA);
739 if (parser == null) {
740 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
741 return null;
742 }
743 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
744 AttributeSet attrs = Xml.asAttributeSet(parser);
745 int type;
746 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
747 && type != XmlPullParser.START_TAG) {
748 // Drain preamble.
749 }
750 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200751 if (!"trust-agent".equals(nodeName)) {
752 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100753 return null;
754 }
755 TypedArray sa = res
756 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
757 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
Lingjun Li20914d72016-11-14 15:39:13 -0800758 canUnlockProfile = sa.getBoolean(
759 com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
Adrian Roos82142c22014-03-27 14:56:59 +0100760 sa.recycle();
761 } catch (PackageManager.NameNotFoundException e) {
762 caughtException = e;
763 } catch (IOException e) {
764 caughtException = e;
765 } catch (XmlPullParserException e) {
766 caughtException = e;
767 } finally {
768 if (parser != null) parser.close();
769 }
770 if (caughtException != null) {
771 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
772 return null;
773 }
774 if (cn == null) {
775 return null;
776 }
777 if (cn.indexOf('/') < 0) {
778 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
779 }
Lingjun Li20914d72016-11-14 15:39:13 -0800780 return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
Adrian Roos82142c22014-03-27 14:56:59 +0100781 }
782
783 private ComponentName getComponentName(ResolveInfo resolveInfo) {
784 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
785 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
786 }
787
Adrian Roos3870d452014-09-05 18:22:28 +0200788 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200789 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
790 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
791 return;
792 }
793 PackageManager pm = mContext.getPackageManager();
794 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700795 ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
796 boolean shouldUseDefaultAgent = defaultAgent != null;
Adrian Roos2f19ad42017-07-05 16:09:22 +0200797 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
Zachary Iqbal666484d2017-03-31 19:10:09 -0700798
799 if (shouldUseDefaultAgent) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200800 discoveredAgents.add(defaultAgent);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700801 Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
802 } else { // A default agent is not set; perform regular trust agent discovery
803 for (ResolveInfo resolveInfo : resolveInfos) {
804 ComponentName componentName = getComponentName(resolveInfo);
805 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
806 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
807 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
808 + "is not a system package.");
809 continue;
810 }
811 discoveredAgents.add(componentName);
Adrian Roos3870d452014-09-05 18:22:28 +0200812 }
Adrian Roos3870d452014-09-05 18:22:28 +0200813 }
Adrian Roos2f19ad42017-07-05 16:09:22 +0200814
815 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
816 if (previouslyEnabledAgents != null) {
817 discoveredAgents.addAll(previouslyEnabledAgents);
818 }
819 utils.setEnabledTrustAgents(discoveredAgents, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200820 Settings.Secure.putIntForUser(mContext.getContentResolver(),
821 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
822 }
823
Zachary Iqbal666484d2017-03-31 19:10:09 -0700824 /**
825 * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
826 * is no trust agent set.
827 */
828 private static ComponentName getDefaultFactoryTrustAgent(Context context) {
829 String defaultTrustAgent = context.getResources()
830 .getString(com.android.internal.R.string.config_defaultTrustAgent);
831 if (TextUtils.isEmpty(defaultTrustAgent)) {
832 return null;
833 }
834 return ComponentName.unflattenFromString(defaultTrustAgent);
835 }
836
Adrian Roos3870d452014-09-05 18:22:28 +0200837 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
838 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
Lingjun Li20914d72016-11-14 15:39:13 -0800839 PackageManager.GET_META_DATA |
Adrian Roos68771eb2016-05-03 14:02:36 -0700840 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
841 userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200842 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
843 for (ResolveInfo resolveInfo : resolveInfos) {
844 if (resolveInfo.serviceInfo == null) continue;
845 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
846 String packageName = resolveInfo.serviceInfo.packageName;
847 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
848 != PackageManager.PERMISSION_GRANTED) {
849 ComponentName name = getComponentName(resolveInfo);
850 Log.w(TAG, "Skipping agent " + name + " because package does not have"
851 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
852 continue;
853 }
854 allowedAgents.add(resolveInfo);
855 }
856 return allowedAgents;
857 }
858
Adrian Roos82142c22014-03-27 14:56:59 +0100859 // Agent dispatch and aggregation
860
861 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700862 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200863 return false;
864 }
Adrian Roos82142c22014-03-27 14:56:59 +0100865 for (int i = 0; i < mActiveAgents.size(); i++) {
866 AgentInfo info = mActiveAgents.valueAt(i);
867 if (info.userId == userId) {
868 if (info.agent.isTrusted()) {
869 return true;
870 }
871 }
872 }
873 return false;
874 }
875
Adrian Roos7861c662014-07-25 15:37:28 +0200876 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700877 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200878 return false;
879 }
880 for (int i = 0; i < mActiveAgents.size(); i++) {
881 AgentInfo info = mActiveAgents.valueAt(i);
882 if (info.userId == userId) {
883 if (info.agent.isManagingTrust()) {
884 return true;
885 }
886 }
887 }
888 return false;
889 }
890
Adrian Roos82142c22014-03-27 14:56:59 +0100891 private void dispatchUnlockAttempt(boolean successful, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800892 if (successful) {
893 mStrongAuthTracker.allowTrustFromUnlock(userId);
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800894 // Allow the presence of trust on a successful unlock attempt to extend unlock.
895 updateTrust(userId, 0 /* flags */, true);
Adrian Roos517b3a42016-03-03 14:58:33 -0800896 }
897
Adrian Roos82142c22014-03-27 14:56:59 +0100898 for (int i = 0; i < mActiveAgents.size(); i++) {
899 AgentInfo info = mActiveAgents.valueAt(i);
900 if (info.userId == userId) {
901 info.agent.onUnlockAttempt(successful);
902 }
903 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200904 }
905
Zachary Iqbal327323d2017-01-12 14:41:13 -0800906 private void dispatchUnlockLockout(int timeoutMs, int userId) {
907 for (int i = 0; i < mActiveAgents.size(); i++) {
908 AgentInfo info = mActiveAgents.valueAt(i);
909 if (info.userId == userId) {
910 info.agent.onUnlockLockout(timeoutMs);
911 }
912 }
913 }
914
Adrian Roos82142c22014-03-27 14:56:59 +0100915 // Listeners
916
917 private void addListener(ITrustListener listener) {
918 for (int i = 0; i < mTrustListeners.size(); i++) {
919 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
920 return;
921 }
922 }
923 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200924 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100925 }
926
927 private void removeListener(ITrustListener listener) {
928 for (int i = 0; i < mTrustListeners.size(); i++) {
929 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700930 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100931 return;
932 }
933 }
934 }
935
Adrian Roos94e15a52015-04-16 12:23:18 -0700936 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800937 if (DEBUG) {
938 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
939 + Integer.toHexString(flags) + ")");
940 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700941 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100942 for (int i = 0; i < mTrustListeners.size(); i++) {
943 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700944 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200945 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200946 Slog.d(TAG, "Removing dead TrustListener.");
947 mTrustListeners.remove(i);
948 i--;
949 } catch (RemoteException e) {
950 Slog.e(TAG, "Exception while notifying TrustListener.", e);
951 }
952 }
953 }
954
955 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800956 if (DEBUG) {
957 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
958 }
Adrian Roos7861c662014-07-25 15:37:28 +0200959 for (int i = 0; i < mTrustListeners.size(); i++) {
960 try {
961 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
962 } catch (DeadObjectException e) {
963 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200964 mTrustListeners.remove(i);
965 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100966 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200967 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100968 }
969 }
970 }
971
Lucas Dupinef886542018-01-03 16:03:07 -0800972 private void dispatchOnTrustError(CharSequence message) {
973 if (DEBUG) {
974 Log.i(TAG, "onTrustError(" + message + ")");
975 }
976 for (int i = 0; i < mTrustListeners.size(); i++) {
977 try {
978 mTrustListeners.get(i).onTrustError(message);
979 } catch (DeadObjectException e) {
980 Slog.d(TAG, "Removing dead TrustListener.");
981 mTrustListeners.remove(i);
982 i--;
983 } catch (RemoteException e) {
984 Slog.e(TAG, "Exception while notifying TrustListener.", e);
985 }
986 }
987 }
988
Adrian Rooscbe614f2014-10-28 20:16:12 +0100989 // User lifecycle
990
991 @Override
992 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100993 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100994 }
995
996 @Override
997 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100998 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
999 }
1000
1001 @Override
1002 public void onSwitchUser(int userId) {
1003 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +01001004 }
1005
Adrian Roos68771eb2016-05-03 14:02:36 -07001006 @Override
1007 public void onUnlockUser(int userId) {
1008 mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
1009 }
1010
Andrew Scull85a63bc2016-10-24 13:47:47 +01001011 @Override
1012 public void onStopUser(@UserIdInt int userId) {
1013 mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
1014 }
1015
Adrian Roos82142c22014-03-27 14:56:59 +01001016 // Plumbing
1017
1018 private final IBinder mService = new ITrustManager.Stub() {
1019 @Override
1020 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
1021 enforceReportPermission();
1022 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
1023 .sendToTarget();
1024 }
1025
1026 @Override
Zachary Iqbal327323d2017-01-12 14:41:13 -08001027 public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
1028 enforceReportPermission();
1029 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
1030 .sendToTarget();
1031 }
1032
1033 @Override
Adrian Roos82142c22014-03-27 14:56:59 +01001034 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
1035 enforceReportPermission();
1036 // coalesce refresh messages.
1037 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
1038 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
1039 }
1040
1041 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +01001042 public void reportKeyguardShowingChanged() throws RemoteException {
1043 enforceReportPermission();
1044 // coalesce refresh messages.
1045 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
1046 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
Jorim Jaggi5277dea2017-05-18 02:05:29 +02001047
1048 // Make sure handler processes the message before returning, such that isDeviceLocked
1049 // after this call will retrieve the correct value.
1050 mHandler.runWithScissors(() -> {}, 0);
Adrian Roos481a6df2014-11-20 19:48:56 +01001051 }
1052
1053 @Override
Adrian Roos82142c22014-03-27 14:56:59 +01001054 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
1055 enforceListenerPermission();
1056 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
1057 }
1058
1059 @Override
1060 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
1061 enforceListenerPermission();
1062 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
1063 }
1064
Adrian Roosbcd07652014-10-22 16:57:16 +02001065 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +01001066 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +02001067 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +01001068 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +01001069
Clara Bayarri078e91b2016-01-15 16:57:35 +00001070 long token = Binder.clearCallingIdentity();
1071 try {
1072 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
1073 userId = resolveProfileParent(userId);
1074 }
1075 return isDeviceLockedInner(userId);
1076 } finally {
1077 Binder.restoreCallingIdentity(token);
1078 }
Adrian Roosbcd07652014-10-22 16:57:16 +02001079 }
1080
Adrian Roos82893682015-04-02 16:17:46 +02001081 @Override
1082 public boolean isDeviceSecure(int userId) throws RemoteException {
1083 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
1084 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +02001085
1086 long token = Binder.clearCallingIdentity();
1087 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +00001088 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
1089 userId = resolveProfileParent(userId);
1090 }
Clara Bayarria1771112015-12-18 16:29:18 +00001091 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +02001092 } finally {
1093 Binder.restoreCallingIdentity(token);
1094 }
1095 }
1096
Adrian Roos82142c22014-03-27 14:56:59 +01001097 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +02001098 mContext.enforceCallingOrSelfPermission(
1099 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +01001100 }
1101
1102 private void enforceListenerPermission() {
1103 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1104 "register trust listener");
1105 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001106
1107 @Override
1108 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001109 if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
Adrian Roos49d53452014-10-24 15:48:39 +02001110 if (isSafeMode()) {
1111 fout.println("disabled because the system is in safe mode.");
1112 return;
1113 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001114 if (!mTrustAgentsCanRun) {
1115 fout.println("disabled because the third-party apps can't run yet.");
1116 return;
1117 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001118 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001119 mHandler.runWithScissors(new Runnable() {
1120 @Override
1121 public void run() {
1122 fout.println("Trust manager state:");
1123 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001124 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001125 }
1126 }
1127 }, 1500);
1128 }
1129
1130 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
1131 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
1132 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -07001133 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001134 fout.println("(managed profile)");
1135 fout.println(" disabled because switching to this user is not possible.");
1136 return;
1137 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001138 if (isCurrent) {
1139 fout.print(" (current)");
1140 }
1141 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +02001142 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +01001143 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -07001144 fout.print(", strongAuthRequired=" + dumpHex(
1145 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001146 fout.println();
1147 fout.println(" Enabled agents:");
1148 boolean duplicateSimpleNames = false;
1149 ArraySet<String> simpleNames = new ArraySet<String>();
1150 for (AgentInfo info : mActiveAgents) {
1151 if (info.userId != user.id) { continue; }
1152 boolean trusted = info.agent.isTrusted();
1153 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001154 fout.print(" bound=" + dumpBool(info.agent.isBound()));
1155 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +02001156 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
1157 fout.print(", trusted=" + dumpBool(trusted));
1158 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001159 if (trusted) {
1160 fout.println(" message=\"" + info.agent.getMessage() + "\"");
1161 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001162 if (!info.agent.isConnected()) {
1163 String restartTime = TrustArchive.formatDuration(
1164 info.agent.getScheduledRestartUptimeMillis()
1165 - SystemClock.uptimeMillis());
1166 fout.println(" restartScheduledAt=" + restartTime);
1167 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001168 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
1169 duplicateSimpleNames = true;
1170 }
1171 }
1172 fout.println(" Events:");
1173 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
1174 fout.println();
1175 }
1176
1177 private String dumpBool(boolean b) {
1178 return b ? "1" : "0";
1179 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001180
1181 private String dumpHex(int i) {
1182 return "0x" + Integer.toHexString(i);
1183 }
Clara Bayarri56878a92015-10-29 15:43:55 +00001184
1185 @Override
Rubin Xu83a15bc2016-08-10 10:53:24 +01001186 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarri00a9b892016-01-13 16:17:09 +00001187 enforceReportPermission();
Rubin Xue0781332016-08-19 11:20:34 +01001188 final long identity = Binder.clearCallingIdentity();
1189 try {
Pavel Grafov259ca362018-07-27 14:04:57 +01001190 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
1191 && mLockPatternUtils.isSecure(userId)) {
Rubin Xue0781332016-08-19 11:20:34 +01001192 synchronized (mDeviceLockedForUser) {
1193 mDeviceLockedForUser.put(userId, locked);
1194 }
1195 if (locked) {
1196 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001197 ActivityManager.getService().notifyLockedProfile(userId);
Rubin Xue0781332016-08-19 11:20:34 +01001198 } catch (RemoteException e) {
1199 }
Rubin Xu83a15bc2016-08-10 10:53:24 +01001200 }
Robin Lee92b83c62016-08-31 13:27:51 +01001201 final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
1202 lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1203 lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1204 mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
1205 Manifest.permission.TRUST_LISTENER, /* options */ null);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001206 }
Rubin Xue0781332016-08-19 11:20:34 +01001207 } finally {
1208 Binder.restoreCallingIdentity(identity);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001209 }
Clara Bayarri56878a92015-10-29 15:43:55 +00001210 }
Adrian Roosc13723f2016-01-12 20:29:03 +01001211
1212 @Override
1213 public boolean isTrustUsuallyManaged(int userId) {
1214 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1215 "query trust state");
1216 return isTrustUsuallyManagedInternal(userId);
1217 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001218
1219 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001220 public void unlockedByBiometricForUser(int userId, BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001221 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001222 synchronized(mUsersUnlockedByBiometric) {
1223 mUsersUnlockedByBiometric.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001224 }
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001225 // In extend unlock mode we need to refresh trust state here, which will call
1226 // refreshDeviceLockedForUser()
1227 int updateTrustOnUnlock = mSettingsObserver.getTrustAgentsExtendUnlock() ? 1 : 0;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001228 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001229 updateTrustOnUnlock).sendToTarget();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001230 }
1231
1232 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001233 public void clearAllBiometricRecognized(BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001234 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001235 synchronized(mUsersUnlockedByBiometric) {
1236 mUsersUnlockedByBiometric.clear();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001237 }
1238 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
1239 0 /* arg2 */).sendToTarget();
1240 }
Adrian Roos82142c22014-03-27 14:56:59 +01001241 };
1242
Adrian Roosc13723f2016-01-12 20:29:03 +01001243 private boolean isTrustUsuallyManagedInternal(int userId) {
1244 synchronized (mTrustUsuallyManagedForUser) {
1245 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1246 if (i >= 0) {
1247 return mTrustUsuallyManagedForUser.valueAt(i);
1248 }
1249 }
1250 // It's not in memory yet, get the value from persisted storage instead
1251 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
1252 synchronized (mTrustUsuallyManagedForUser) {
1253 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1254 if (i >= 0) {
1255 // Someone set the trust usually managed in the mean time. Better use that.
1256 return mTrustUsuallyManagedForUser.valueAt(i);
1257 } else {
1258 // .. otherwise it's safe to cache the fetched value now.
1259 mTrustUsuallyManagedForUser.put(userId, persistedValue);
1260 return persistedValue;
1261 }
1262 }
1263 }
1264
Adrian Roosbcd07652014-10-22 16:57:16 +02001265 private int resolveProfileParent(int userId) {
1266 long identity = Binder.clearCallingIdentity();
1267 try {
1268 UserInfo parent = mUserManager.getProfileParent(userId);
1269 if (parent != null) {
1270 return parent.getUserHandle().getIdentifier();
1271 }
1272 return userId;
1273 } finally {
1274 Binder.restoreCallingIdentity(identity);
1275 }
1276 }
1277
Adrian Roos82142c22014-03-27 14:56:59 +01001278 private final Handler mHandler = new Handler() {
1279 @Override
1280 public void handleMessage(Message msg) {
1281 switch (msg.what) {
1282 case MSG_REGISTER_LISTENER:
1283 addListener((ITrustListener) msg.obj);
1284 break;
1285 case MSG_UNREGISTER_LISTENER:
1286 removeListener((ITrustListener) msg.obj);
1287 break;
1288 case MSG_DISPATCH_UNLOCK_ATTEMPT:
1289 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
1290 break;
Zachary Iqbal327323d2017-01-12 14:41:13 -08001291 case MSG_DISPATCH_UNLOCK_LOCKOUT:
1292 dispatchUnlockLockout(msg.arg1, msg.arg2);
1293 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001294 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -07001295 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +01001296 // This is also called when the security mode of a user changes.
1297 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001298 break;
Adrian Roos481a6df2014-11-20 19:48:56 +01001299 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +01001300 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +01001301 break;
1302 case MSG_START_USER:
1303 case MSG_CLEANUP_USER:
Adrian Roos68771eb2016-05-03 14:02:36 -07001304 case MSG_UNLOCK_USER:
Adrian Roos481a6df2014-11-20 19:48:56 +01001305 refreshAgentList(msg.arg1);
1306 break;
1307 case MSG_SWITCH_USER:
1308 mCurrentUser = msg.arg1;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001309 mSettingsObserver.updateContentObserver();
Adrian Roos481a6df2014-11-20 19:48:56 +01001310 refreshDeviceLockedForUser(UserHandle.USER_ALL);
1311 break;
Andrew Scull85a63bc2016-10-24 13:47:47 +01001312 case MSG_STOP_USER:
1313 setDeviceLockedForUser(msg.arg1, true);
1314 break;
Adrian Roosc13723f2016-01-12 20:29:03 +01001315 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
1316 SparseBooleanArray usuallyManaged;
1317 synchronized (mTrustUsuallyManagedForUser) {
1318 usuallyManaged = mTrustUsuallyManagedForUser.clone();
1319 }
1320
1321 for (int i = 0; i < usuallyManaged.size(); i++) {
1322 int userId = usuallyManaged.keyAt(i);
1323 boolean value = usuallyManaged.valueAt(i);
1324 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
1325 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
1326 }
1327 }
Adrian Roos68771eb2016-05-03 14:02:36 -07001328 break;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001329 case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001330 if (msg.arg2 == 1) {
1331 updateTrust(msg.arg1, 0 /* flags */, true);
1332 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001333 refreshDeviceLockedForUser(msg.arg1);
1334 break;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001335 case MSG_SCHEDULE_TRUST_TIMEOUT:
1336 handleScheduleTrustTimeout(msg.arg1, msg.arg2);
1337 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001338 }
1339 }
1340 };
1341
1342 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1343 @Override
1344 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -07001345 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001346 }
1347
1348 @Override
1349 public boolean onPackageChanged(String packageName, int uid, String[] components) {
1350 // We're interested in all changes, even if just some components get enabled / disabled.
1351 return true;
1352 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001353
1354 @Override
1355 public void onPackageDisappeared(String packageName, int reason) {
1356 removeAgentsOfPackage(packageName);
1357 }
Adrian Roos82142c22014-03-27 14:56:59 +01001358 };
Adrian Roosca36b952014-05-16 18:52:29 +02001359
Lingjun Li20914d72016-11-14 15:39:13 -08001360 private static class SettingsAttrs {
1361 public ComponentName componentName;
1362 public boolean canUnlockProfile;
1363
1364 public SettingsAttrs(
1365 ComponentName componentName,
1366 boolean canUnlockProfile) {
1367 this.componentName = componentName;
1368 this.canUnlockProfile = canUnlockProfile;
1369 }
1370 };
1371
Adrian Roos9dbe1902014-08-13 18:25:52 +02001372 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +02001373
1374 @Override
1375 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +02001376 String action = intent.getAction();
1377 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -07001378 refreshAgentList(getSendingUserId());
1379 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +02001380 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +01001381 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +02001382 if (userId > 0) {
1383 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +02001384 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001385 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
1386 int userId = getUserId(intent);
1387 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001388 synchronized (mUserIsTrusted) {
1389 mUserIsTrusted.delete(userId);
1390 }
1391 synchronized (mDeviceLockedForUser) {
1392 mDeviceLockedForUser.delete(userId);
1393 }
Adrian Roosae025822016-11-03 14:46:13 -07001394 synchronized (mTrustUsuallyManagedForUser) {
1395 mTrustUsuallyManagedForUser.delete(userId);
1396 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001397 synchronized (mUsersUnlockedByBiometric) {
1398 mUsersUnlockedByBiometric.delete(userId);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001399 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001400 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +01001401 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001402 }
1403 }
1404 }
1405
1406 private int getUserId(Intent intent) {
1407 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
1408 if (userId > 0) {
1409 return userId;
1410 } else {
1411 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
1412 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +02001413 }
1414 }
1415
1416 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +02001417 IntentFilter filter = new IntentFilter();
1418 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Adrian Roos3870d452014-09-05 18:22:28 +02001419 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001420 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +02001421 context.registerReceiverAsUser(this,
1422 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +02001423 filter,
Adrian Roosca36b952014-05-16 18:52:29 +02001424 null /* permission */,
1425 null /* scheduler */);
1426 }
1427 }
Adrian Roos517b3a42016-03-03 14:58:33 -08001428
1429 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1430
1431 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1432
1433 public StrongAuthTracker(Context context) {
1434 super(context);
1435 }
1436
1437 @Override
1438 public void onStrongAuthRequiredChanged(int userId) {
1439 mStartFromSuccessfulUnlock.delete(userId);
1440
1441 if (DEBUG) {
1442 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1443 + " trustAllowed=" + isTrustAllowedForUser(userId)
1444 + " agentsCanRun=" + canAgentsRunForUser(userId));
1445 }
1446
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001447 // Cancel pending alarms if we require some auth anyway.
1448 if (!isTrustAllowedForUser(userId)) {
1449 TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
1450 if (alarm != null && alarm.isQueued()) {
1451 alarm.setQueued(false /* isQueued */);
1452 mAlarmManager.cancel(alarm);
1453 }
1454 }
1455
Adrian Roos517b3a42016-03-03 14:58:33 -08001456 refreshAgentList(userId);
1457
1458 // The list of active trust agents may not have changed, if there was a previous call
1459 // to allowTrustFromUnlock, so we update the trust here too.
1460 updateTrust(userId, 0 /* flags */);
1461 }
1462
1463 boolean canAgentsRunForUser(int userId) {
1464 return mStartFromSuccessfulUnlock.get(userId)
1465 || super.isTrustAllowedForUser(userId);
1466 }
1467
1468 /**
1469 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1470 * changes again. Must only be called when we know about a successful unlock already
1471 * before the underlying StrongAuthTracker.
1472 *
1473 * Note that this only changes whether trust agents can be started, not the actual trusted
1474 * value.
1475 */
1476 void allowTrustFromUnlock(int userId) {
1477 if (userId < UserHandle.USER_SYSTEM) {
1478 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1479 }
1480 boolean previous = canAgentsRunForUser(userId);
1481 mStartFromSuccessfulUnlock.put(userId, true);
1482
1483 if (DEBUG) {
1484 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1485 + " trustAllowed=" + isTrustAllowedForUser(userId)
1486 + " agentsCanRun=" + canAgentsRunForUser(userId));
1487 }
1488
1489 if (canAgentsRunForUser(userId) != previous) {
1490 refreshAgentList(userId);
1491 }
1492 }
1493 }
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001494
1495 private class TrustTimeoutAlarmListener implements OnAlarmListener {
1496 private final int mUserId;
1497 private boolean mIsQueued = false;
1498
1499 TrustTimeoutAlarmListener(int userId) {
1500 mUserId = userId;
1501 }
1502
1503 @Override
1504 public void onAlarm() {
1505 mIsQueued = false;
1506 int strongAuthState = mStrongAuthTracker.getStrongAuthForUser(mUserId);
1507
1508 // Only fire if trust can unlock.
1509 if (mStrongAuthTracker.isTrustAllowedForUser(mUserId)) {
1510 if (DEBUG) Slog.d(TAG, "Revoking all trust because of trust timeout");
1511 mLockPatternUtils.requireStrongAuth(
1512 mStrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, mUserId);
1513 }
1514 maybeLockScreen(mUserId);
1515 }
1516
1517 public void setQueued(boolean isQueued) {
1518 mIsQueued = isQueued;
1519 }
1520
1521 public boolean isQueued() {
1522 return mIsQueued;
1523 }
1524 }
Adrian Roos82142c22014-03-27 14:56:59 +01001525}