blob: c7044a15dd5d640d773c9f5e7bcbe0beb1d946b9 [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) {
412 return mLockPatternUtils.addEscrowToken(token, userId);
413 }
414
415 public boolean removeEscrowToken(long handle, int userId) {
416 return mLockPatternUtils.removeEscrowToken(handle, userId);
417 }
418
419 public boolean isEscrowTokenActive(long handle, int userId) {
420 return mLockPatternUtils.isEscrowTokenActive(handle, userId);
421 }
422
423 public void unlockUserWithToken(long handle, byte[] token, int userId) {
424 mLockPatternUtils.unlockUserWithToken(handle, token, userId);
425 }
426
Lucas Dupinef886542018-01-03 16:03:07 -0800427 void showKeyguardErrorMessage(CharSequence message) {
428 dispatchOnTrustError(message);
429 }
430
Adrian Roos517b3a42016-03-03 14:58:33 -0800431 void refreshAgentList(int userIdOrAll) {
432 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100433 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200434 return;
435 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800436 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
437 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
Adrian Roose681c272014-09-08 14:03:47 +0200438 + " must be USER_ALL or a specific user.", new Throwable("here"));
Adrian Roos517b3a42016-03-03 14:58:33 -0800439 userIdOrAll = UserHandle.USER_ALL;
Adrian Roose681c272014-09-08 14:03:47 +0200440 }
Adrian Roos82142c22014-03-27 14:56:59 +0100441 PackageManager pm = mContext.getPackageManager();
442
Marco Fucci4e68f112014-08-29 12:31:48 -0700443 List<UserInfo> userInfos;
Adrian Roos517b3a42016-03-03 14:58:33 -0800444 if (userIdOrAll == UserHandle.USER_ALL) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700445 userInfos = mUserManager.getUsers(true /* excludeDying */);
446 } else {
447 userInfos = new ArrayList<>();
Adrian Roos517b3a42016-03-03 14:58:33 -0800448 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
Marco Fucci4e68f112014-08-29 12:31:48 -0700449 }
Adrian Roos3870d452014-09-05 18:22:28 +0200450 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100451
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200452 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
453 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100454
455 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100456 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
457 || userInfo.guestToRemove) continue;
Adrian Roos5d639782016-07-21 11:43:02 -0700458 if (!userInfo.supportsSwitchToByUser()) {
459 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
460 + ": switchToByUser=false");
461 continue;
462 }
Adrian Roos5d639782016-07-21 11:43:02 -0700463 if (!mActivityManager.isUserRunning(userInfo.id)) {
464 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
465 + ": user not started");
466 continue;
467 }
468 if (!lockPatternUtils.isSecure(userInfo.id)) {
469 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
470 + ": no secure credential");
471 continue;
472 }
Lingjun Li20914d72016-11-14 15:39:13 -0800473
Adrian Roos8f211582014-07-29 15:09:57 +0200474 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
475 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700476 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200477 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
478
Adrian Roos82142c22014-03-27 14:56:59 +0100479 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200480 if (enabledAgents == null) {
Adrian Roos5d639782016-07-21 11:43:02 -0700481 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
482 + ": no agents enabled by user");
Adrian Roos82142c22014-03-27 14:56:59 +0100483 continue;
484 }
Adrian Roos3870d452014-09-05 18:22:28 +0200485 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100486 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100487 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100488
Adrian Roos5d639782016-07-21 11:43:02 -0700489 if (!enabledAgents.contains(name)) {
490 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
491 + name.flattenToShortString() + " u"+ userInfo.id
492 + ": not enabled by user");
493 continue;
494 }
Adrian Roos8f211582014-07-29 15:09:57 +0200495 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700496 List<PersistableBundle> config =
497 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200498 // Disable agent if no features are enabled.
Adrian Roos5d639782016-07-21 11:43:02 -0700499 if (config == null || config.isEmpty()) {
500 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
501 + name.flattenToShortString() + " u"+ userInfo.id
502 + ": not allowed by DPM");
503 continue;
504 }
Adrian Roos8f211582014-07-29 15:09:57 +0200505 }
Adrian Roos82142c22014-03-27 14:56:59 +0100506 AgentInfo agentInfo = new AgentInfo();
507 agentInfo.component = name;
508 agentInfo.userId = userInfo.id;
509 if (!mActiveAgents.contains(agentInfo)) {
510 agentInfo.label = resolveInfo.loadLabel(pm);
511 agentInfo.icon = resolveInfo.loadIcon(pm);
Lingjun Li20914d72016-11-14 15:39:13 -0800512 agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
Lingjun Li20914d72016-11-14 15:39:13 -0800513 } else {
514 int index = mActiveAgents.indexOf(agentInfo);
515 agentInfo = mActiveAgents.valueAt(index);
516 }
517
518 boolean directUnlock = resolveInfo.serviceInfo.directBootAware
519 && agentInfo.settings.canUnlockProfile;
520
521 if (directUnlock) {
522 if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
523 + "of user " + userInfo.id + "can unlock user profile.");
524 }
525
Jeff Sharkeya65e6492017-06-21 13:45:11 -0600526 if (!mUserManager.isUserUnlockingOrUnlocked(userInfo.id)
Lingjun Li20914d72016-11-14 15:39:13 -0800527 && !directUnlock) {
528 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
Lingjun Li93a145f2017-01-23 17:13:35 -0800529 + "'s trust agent " + name + ": FBE still locked and "
Lingjun Li20914d72016-11-14 15:39:13 -0800530 + " the agent cannot unlock user profile.");
531 continue;
532 }
533
534 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
535 int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
Zachary Iqbal327323d2017-01-12 14:41:13 -0800536 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
537 if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
538 || !directUnlock) {
539 if (DEBUG)
540 Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
541 + ": prevented by StrongAuthTracker = 0x"
542 + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
543 userInfo.id)));
544 continue;
545 }
Lingjun Li20914d72016-11-14 15:39:13 -0800546 }
547 }
548
Adrian Roosb884bb22017-05-03 11:33:51 -0700549 if (agentInfo.agent == null) {
550 agentInfo.agent = new TrustAgentWrapper(mContext, this,
551 new Intent().setComponent(name), userInfo.getUserHandle());
552 }
553
Lingjun Li20914d72016-11-14 15:39:13 -0800554 if (!mActiveAgents.contains(agentInfo)) {
Adrian Roos82142c22014-03-27 14:56:59 +0100555 mActiveAgents.add(agentInfo);
556 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200557 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100558 }
559 }
560 }
561
562 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200563 for (int i = 0; i < obsoleteAgents.size(); i++) {
564 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roos517b3a42016-03-03 14:58:33 -0800565 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
Adrian Roose681c272014-09-08 14:03:47 +0200566 if (info.agent.isManagingTrust()) {
567 trustMayHaveChanged = true;
568 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100569 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200570 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100571 }
Adrian Roos82142c22014-03-27 14:56:59 +0100572 }
573
574 if (trustMayHaveChanged) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800575 if (userIdOrAll == UserHandle.USER_ALL) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100576 updateTrustAll();
577 } else {
Adrian Roos517b3a42016-03-03 14:58:33 -0800578 updateTrust(userIdOrAll, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100579 }
Adrian Roos82142c22014-03-27 14:56:59 +0100580 }
581 }
582
Adrian Roos481a6df2014-11-20 19:48:56 +0100583 boolean isDeviceLockedInner(int userId) {
584 synchronized (mDeviceLockedForUser) {
585 return mDeviceLockedForUser.get(userId, true);
586 }
587 }
588
589 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700590 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100591 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100592 + " must be USER_ALL or a specific user.", new Throwable("here"));
593 userId = UserHandle.USER_ALL;
594 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100595 List<UserInfo> userInfos;
596 if (userId == UserHandle.USER_ALL) {
597 userInfos = mUserManager.getUsers(true /* excludeDying */);
598 } else {
599 userInfos = new ArrayList<>();
600 userInfos.add(mUserManager.getUserInfo(userId));
601 }
602
603 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
604
605 for (int i = 0; i < userInfos.size(); i++) {
606 UserInfo info = userInfos.get(i);
607
Pavel Grafov259ca362018-07-27 14:04:57 +0100608 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100609 continue;
610 }
611
612 int id = info.id;
613 boolean secure = mLockPatternUtils.isSecure(id);
Pavel Grafov259ca362018-07-27 14:04:57 +0100614
615 if (!info.supportsSwitchToByUser()) {
616 if (info.isManagedProfile() && !secure) {
617 setDeviceLockedForUser(id, false);
618 }
619 continue;
620 }
621
Adrian Roos481a6df2014-11-20 19:48:56 +0100622 boolean trusted = aggregateIsTrusted(id);
623 boolean showingKeyguard = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200624 boolean biometricAuthenticated = false;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700625
Adrian Roos481a6df2014-11-20 19:48:56 +0100626 if (mCurrentUser == id) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200627 synchronized(mUsersUnlockedByBiometric) {
628 biometricAuthenticated = mUsersUnlockedByBiometric.get(id, false);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700629 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100630 try {
631 showingKeyguard = wm.isKeyguardLocked();
632 } catch (RemoteException e) {
633 }
634 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700635 boolean deviceLocked = secure && showingKeyguard && !trusted &&
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200636 !biometricAuthenticated;
Andrew Scull85a63bc2016-10-24 13:47:47 +0100637 setDeviceLockedForUser(id, deviceLocked);
638 }
639 }
Adrian Roos481a6df2014-11-20 19:48:56 +0100640
Andrew Scull85a63bc2016-10-24 13:47:47 +0100641 private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
642 final boolean changed;
643 synchronized (mDeviceLockedForUser) {
644 changed = isDeviceLockedInner(userId) != locked;
645 mDeviceLockedForUser.put(userId, locked);
646 }
647 if (changed) {
648 dispatchDeviceLocked(userId, locked);
Adrian Roos481a6df2014-11-20 19:48:56 +0100649 }
650 }
651
652 private void dispatchDeviceLocked(int userId, boolean isLocked) {
653 for (int i = 0; i < mActiveAgents.size(); i++) {
654 AgentInfo agent = mActiveAgents.valueAt(i);
655 if (agent.userId == userId) {
656 if (isLocked) {
657 agent.agent.onDeviceLocked();
658 } else{
659 agent.agent.onDeviceUnlocked();
660 }
661 }
662 }
663 }
664
Marco Fucci4e68f112014-08-29 12:31:48 -0700665 void updateDevicePolicyFeatures() {
Adrian Roos9d6fc922016-08-10 17:09:55 -0700666 boolean changed = false;
Adrian Roos8f211582014-07-29 15:09:57 +0200667 for (int i = 0; i < mActiveAgents.size(); i++) {
668 AgentInfo info = mActiveAgents.valueAt(i);
669 if (info.agent.isConnected()) {
670 info.agent.updateDevicePolicyFeatures();
Adrian Roos9d6fc922016-08-10 17:09:55 -0700671 changed = true;
Adrian Roos8f211582014-07-29 15:09:57 +0200672 }
673 }
Adrian Roos9d6fc922016-08-10 17:09:55 -0700674 if (changed) {
675 mArchive.logDevicePolicyChanged();
676 }
Adrian Roos8f211582014-07-29 15:09:57 +0200677 }
678
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200679 private void removeAgentsOfPackage(String packageName) {
680 boolean trustMayHaveChanged = false;
681 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
682 AgentInfo info = mActiveAgents.valueAt(i);
683 if (packageName.equals(info.component.getPackageName())) {
684 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200685 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200686 trustMayHaveChanged = true;
687 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100688 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200689 mActiveAgents.removeAt(i);
690 }
691 }
692 if (trustMayHaveChanged) {
693 updateTrustAll();
694 }
695 }
696
697 public void resetAgent(ComponentName name, int userId) {
698 boolean trustMayHaveChanged = false;
699 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
700 AgentInfo info = mActiveAgents.valueAt(i);
701 if (name.equals(info.component) && userId == info.userId) {
702 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200703 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200704 trustMayHaveChanged = true;
705 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100706 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200707 mActiveAgents.removeAt(i);
708 }
709 }
710 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700711 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200712 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700713 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200714 }
715
Lingjun Li20914d72016-11-14 15:39:13 -0800716 private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) {
Adrian Roos82142c22014-03-27 14:56:59 +0100717 if (resolveInfo == null || resolveInfo.serviceInfo == null
718 || resolveInfo.serviceInfo.metaData == null) return null;
719 String cn = null;
Lingjun Li20914d72016-11-14 15:39:13 -0800720 boolean canUnlockProfile = false;
721
Adrian Roos82142c22014-03-27 14:56:59 +0100722 XmlResourceParser parser = null;
723 Exception caughtException = null;
724 try {
725 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
726 TrustAgentService.TRUST_AGENT_META_DATA);
727 if (parser == null) {
728 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
729 return null;
730 }
731 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
732 AttributeSet attrs = Xml.asAttributeSet(parser);
733 int type;
734 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
735 && type != XmlPullParser.START_TAG) {
736 // Drain preamble.
737 }
738 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200739 if (!"trust-agent".equals(nodeName)) {
740 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100741 return null;
742 }
743 TypedArray sa = res
744 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
745 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
Lingjun Li20914d72016-11-14 15:39:13 -0800746 canUnlockProfile = sa.getBoolean(
747 com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
Adrian Roos82142c22014-03-27 14:56:59 +0100748 sa.recycle();
749 } catch (PackageManager.NameNotFoundException e) {
750 caughtException = e;
751 } catch (IOException e) {
752 caughtException = e;
753 } catch (XmlPullParserException e) {
754 caughtException = e;
755 } finally {
756 if (parser != null) parser.close();
757 }
758 if (caughtException != null) {
759 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
760 return null;
761 }
762 if (cn == null) {
763 return null;
764 }
765 if (cn.indexOf('/') < 0) {
766 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
767 }
Lingjun Li20914d72016-11-14 15:39:13 -0800768 return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
Adrian Roos82142c22014-03-27 14:56:59 +0100769 }
770
771 private ComponentName getComponentName(ResolveInfo resolveInfo) {
772 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
773 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
774 }
775
Adrian Roos3870d452014-09-05 18:22:28 +0200776 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200777 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
778 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
779 return;
780 }
781 PackageManager pm = mContext.getPackageManager();
782 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700783 ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
784 boolean shouldUseDefaultAgent = defaultAgent != null;
Adrian Roos2f19ad42017-07-05 16:09:22 +0200785 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
Zachary Iqbal666484d2017-03-31 19:10:09 -0700786
787 if (shouldUseDefaultAgent) {
Adrian Roos2f19ad42017-07-05 16:09:22 +0200788 discoveredAgents.add(defaultAgent);
Zachary Iqbal666484d2017-03-31 19:10:09 -0700789 Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
790 } else { // A default agent is not set; perform regular trust agent discovery
791 for (ResolveInfo resolveInfo : resolveInfos) {
792 ComponentName componentName = getComponentName(resolveInfo);
793 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
794 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
795 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
796 + "is not a system package.");
797 continue;
798 }
799 discoveredAgents.add(componentName);
Adrian Roos3870d452014-09-05 18:22:28 +0200800 }
Adrian Roos3870d452014-09-05 18:22:28 +0200801 }
Adrian Roos2f19ad42017-07-05 16:09:22 +0200802
803 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
804 if (previouslyEnabledAgents != null) {
805 discoveredAgents.addAll(previouslyEnabledAgents);
806 }
807 utils.setEnabledTrustAgents(discoveredAgents, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200808 Settings.Secure.putIntForUser(mContext.getContentResolver(),
809 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
810 }
811
Zachary Iqbal666484d2017-03-31 19:10:09 -0700812 /**
813 * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
814 * is no trust agent set.
815 */
816 private static ComponentName getDefaultFactoryTrustAgent(Context context) {
817 String defaultTrustAgent = context.getResources()
818 .getString(com.android.internal.R.string.config_defaultTrustAgent);
819 if (TextUtils.isEmpty(defaultTrustAgent)) {
820 return null;
821 }
822 return ComponentName.unflattenFromString(defaultTrustAgent);
823 }
824
Adrian Roos3870d452014-09-05 18:22:28 +0200825 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
826 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
Lingjun Li20914d72016-11-14 15:39:13 -0800827 PackageManager.GET_META_DATA |
Adrian Roos68771eb2016-05-03 14:02:36 -0700828 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
829 userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200830 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
831 for (ResolveInfo resolveInfo : resolveInfos) {
832 if (resolveInfo.serviceInfo == null) continue;
833 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
834 String packageName = resolveInfo.serviceInfo.packageName;
835 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
836 != PackageManager.PERMISSION_GRANTED) {
837 ComponentName name = getComponentName(resolveInfo);
838 Log.w(TAG, "Skipping agent " + name + " because package does not have"
839 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
840 continue;
841 }
842 allowedAgents.add(resolveInfo);
843 }
844 return allowedAgents;
845 }
846
Adrian Roos82142c22014-03-27 14:56:59 +0100847 // Agent dispatch and aggregation
848
849 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700850 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200851 return false;
852 }
Adrian Roos82142c22014-03-27 14:56:59 +0100853 for (int i = 0; i < mActiveAgents.size(); i++) {
854 AgentInfo info = mActiveAgents.valueAt(i);
855 if (info.userId == userId) {
856 if (info.agent.isTrusted()) {
857 return true;
858 }
859 }
860 }
861 return false;
862 }
863
Adrian Roos7861c662014-07-25 15:37:28 +0200864 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700865 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200866 return false;
867 }
868 for (int i = 0; i < mActiveAgents.size(); i++) {
869 AgentInfo info = mActiveAgents.valueAt(i);
870 if (info.userId == userId) {
871 if (info.agent.isManagingTrust()) {
872 return true;
873 }
874 }
875 }
876 return false;
877 }
878
Adrian Roos82142c22014-03-27 14:56:59 +0100879 private void dispatchUnlockAttempt(boolean successful, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800880 if (successful) {
881 mStrongAuthTracker.allowTrustFromUnlock(userId);
Vishwath Mohan15f7dd02018-12-12 11:15:08 -0800882 // Allow the presence of trust on a successful unlock attempt to extend unlock.
883 updateTrust(userId, 0 /* flags */, true);
Adrian Roos517b3a42016-03-03 14:58:33 -0800884 }
885
Adrian Roos82142c22014-03-27 14:56:59 +0100886 for (int i = 0; i < mActiveAgents.size(); i++) {
887 AgentInfo info = mActiveAgents.valueAt(i);
888 if (info.userId == userId) {
889 info.agent.onUnlockAttempt(successful);
890 }
891 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200892 }
893
Zachary Iqbal327323d2017-01-12 14:41:13 -0800894 private void dispatchUnlockLockout(int timeoutMs, int userId) {
895 for (int i = 0; i < mActiveAgents.size(); i++) {
896 AgentInfo info = mActiveAgents.valueAt(i);
897 if (info.userId == userId) {
898 info.agent.onUnlockLockout(timeoutMs);
899 }
900 }
901 }
902
Adrian Roos82142c22014-03-27 14:56:59 +0100903 // Listeners
904
905 private void addListener(ITrustListener listener) {
906 for (int i = 0; i < mTrustListeners.size(); i++) {
907 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
908 return;
909 }
910 }
911 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200912 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100913 }
914
915 private void removeListener(ITrustListener listener) {
916 for (int i = 0; i < mTrustListeners.size(); i++) {
917 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700918 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100919 return;
920 }
921 }
922 }
923
Adrian Roos94e15a52015-04-16 12:23:18 -0700924 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800925 if (DEBUG) {
926 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
927 + Integer.toHexString(flags) + ")");
928 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700929 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100930 for (int i = 0; i < mTrustListeners.size(); i++) {
931 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700932 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200933 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200934 Slog.d(TAG, "Removing dead TrustListener.");
935 mTrustListeners.remove(i);
936 i--;
937 } catch (RemoteException e) {
938 Slog.e(TAG, "Exception while notifying TrustListener.", e);
939 }
940 }
941 }
942
943 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800944 if (DEBUG) {
945 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
946 }
Adrian Roos7861c662014-07-25 15:37:28 +0200947 for (int i = 0; i < mTrustListeners.size(); i++) {
948 try {
949 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
950 } catch (DeadObjectException e) {
951 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200952 mTrustListeners.remove(i);
953 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100954 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200955 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100956 }
957 }
958 }
959
Lucas Dupinef886542018-01-03 16:03:07 -0800960 private void dispatchOnTrustError(CharSequence message) {
961 if (DEBUG) {
962 Log.i(TAG, "onTrustError(" + message + ")");
963 }
964 for (int i = 0; i < mTrustListeners.size(); i++) {
965 try {
966 mTrustListeners.get(i).onTrustError(message);
967 } catch (DeadObjectException e) {
968 Slog.d(TAG, "Removing dead TrustListener.");
969 mTrustListeners.remove(i);
970 i--;
971 } catch (RemoteException e) {
972 Slog.e(TAG, "Exception while notifying TrustListener.", e);
973 }
974 }
975 }
976
Adrian Rooscbe614f2014-10-28 20:16:12 +0100977 // User lifecycle
978
979 @Override
980 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100981 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100982 }
983
984 @Override
985 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100986 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
987 }
988
989 @Override
990 public void onSwitchUser(int userId) {
991 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100992 }
993
Adrian Roos68771eb2016-05-03 14:02:36 -0700994 @Override
995 public void onUnlockUser(int userId) {
996 mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
997 }
998
Andrew Scull85a63bc2016-10-24 13:47:47 +0100999 @Override
1000 public void onStopUser(@UserIdInt int userId) {
1001 mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
1002 }
1003
Adrian Roos82142c22014-03-27 14:56:59 +01001004 // Plumbing
1005
1006 private final IBinder mService = new ITrustManager.Stub() {
1007 @Override
1008 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
1009 enforceReportPermission();
1010 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
1011 .sendToTarget();
1012 }
1013
1014 @Override
Zachary Iqbal327323d2017-01-12 14:41:13 -08001015 public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
1016 enforceReportPermission();
1017 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
1018 .sendToTarget();
1019 }
1020
1021 @Override
Adrian Roos82142c22014-03-27 14:56:59 +01001022 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
1023 enforceReportPermission();
1024 // coalesce refresh messages.
1025 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
1026 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
1027 }
1028
1029 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +01001030 public void reportKeyguardShowingChanged() throws RemoteException {
1031 enforceReportPermission();
1032 // coalesce refresh messages.
1033 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
1034 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
Jorim Jaggi5277dea2017-05-18 02:05:29 +02001035
1036 // Make sure handler processes the message before returning, such that isDeviceLocked
1037 // after this call will retrieve the correct value.
1038 mHandler.runWithScissors(() -> {}, 0);
Adrian Roos481a6df2014-11-20 19:48:56 +01001039 }
1040
1041 @Override
Adrian Roos82142c22014-03-27 14:56:59 +01001042 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
1043 enforceListenerPermission();
1044 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
1045 }
1046
1047 @Override
1048 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
1049 enforceListenerPermission();
1050 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
1051 }
1052
Adrian Roosbcd07652014-10-22 16:57:16 +02001053 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +01001054 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +02001055 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +01001056 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +01001057
Clara Bayarri078e91b2016-01-15 16:57:35 +00001058 long token = Binder.clearCallingIdentity();
1059 try {
1060 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
1061 userId = resolveProfileParent(userId);
1062 }
1063 return isDeviceLockedInner(userId);
1064 } finally {
1065 Binder.restoreCallingIdentity(token);
1066 }
Adrian Roosbcd07652014-10-22 16:57:16 +02001067 }
1068
Adrian Roos82893682015-04-02 16:17:46 +02001069 @Override
1070 public boolean isDeviceSecure(int userId) throws RemoteException {
1071 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
1072 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +02001073
1074 long token = Binder.clearCallingIdentity();
1075 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +00001076 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
1077 userId = resolveProfileParent(userId);
1078 }
Clara Bayarria1771112015-12-18 16:29:18 +00001079 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +02001080 } finally {
1081 Binder.restoreCallingIdentity(token);
1082 }
1083 }
1084
Adrian Roos82142c22014-03-27 14:56:59 +01001085 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +02001086 mContext.enforceCallingOrSelfPermission(
1087 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +01001088 }
1089
1090 private void enforceListenerPermission() {
1091 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1092 "register trust listener");
1093 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001094
1095 @Override
1096 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001097 if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
Adrian Roos49d53452014-10-24 15:48:39 +02001098 if (isSafeMode()) {
1099 fout.println("disabled because the system is in safe mode.");
1100 return;
1101 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001102 if (!mTrustAgentsCanRun) {
1103 fout.println("disabled because the third-party apps can't run yet.");
1104 return;
1105 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001106 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001107 mHandler.runWithScissors(new Runnable() {
1108 @Override
1109 public void run() {
1110 fout.println("Trust manager state:");
1111 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001112 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001113 }
1114 }
1115 }, 1500);
1116 }
1117
1118 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
1119 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
1120 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -07001121 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001122 fout.println("(managed profile)");
1123 fout.println(" disabled because switching to this user is not possible.");
1124 return;
1125 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001126 if (isCurrent) {
1127 fout.print(" (current)");
1128 }
1129 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +02001130 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +01001131 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -07001132 fout.print(", strongAuthRequired=" + dumpHex(
1133 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001134 fout.println();
1135 fout.println(" Enabled agents:");
1136 boolean duplicateSimpleNames = false;
1137 ArraySet<String> simpleNames = new ArraySet<String>();
1138 for (AgentInfo info : mActiveAgents) {
1139 if (info.userId != user.id) { continue; }
1140 boolean trusted = info.agent.isTrusted();
1141 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001142 fout.print(" bound=" + dumpBool(info.agent.isBound()));
1143 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +02001144 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
1145 fout.print(", trusted=" + dumpBool(trusted));
1146 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001147 if (trusted) {
1148 fout.println(" message=\"" + info.agent.getMessage() + "\"");
1149 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001150 if (!info.agent.isConnected()) {
1151 String restartTime = TrustArchive.formatDuration(
1152 info.agent.getScheduledRestartUptimeMillis()
1153 - SystemClock.uptimeMillis());
1154 fout.println(" restartScheduledAt=" + restartTime);
1155 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +02001156 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
1157 duplicateSimpleNames = true;
1158 }
1159 }
1160 fout.println(" Events:");
1161 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
1162 fout.println();
1163 }
1164
1165 private String dumpBool(boolean b) {
1166 return b ? "1" : "0";
1167 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001168
1169 private String dumpHex(int i) {
1170 return "0x" + Integer.toHexString(i);
1171 }
Clara Bayarri56878a92015-10-29 15:43:55 +00001172
1173 @Override
Rubin Xu83a15bc2016-08-10 10:53:24 +01001174 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarri00a9b892016-01-13 16:17:09 +00001175 enforceReportPermission();
Rubin Xue0781332016-08-19 11:20:34 +01001176 final long identity = Binder.clearCallingIdentity();
1177 try {
Pavel Grafov259ca362018-07-27 14:04:57 +01001178 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
1179 && mLockPatternUtils.isSecure(userId)) {
Rubin Xue0781332016-08-19 11:20:34 +01001180 synchronized (mDeviceLockedForUser) {
1181 mDeviceLockedForUser.put(userId, locked);
1182 }
1183 if (locked) {
1184 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001185 ActivityManager.getService().notifyLockedProfile(userId);
Rubin Xue0781332016-08-19 11:20:34 +01001186 } catch (RemoteException e) {
1187 }
Rubin Xu83a15bc2016-08-10 10:53:24 +01001188 }
Robin Lee92b83c62016-08-31 13:27:51 +01001189 final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
1190 lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1191 lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1192 mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
1193 Manifest.permission.TRUST_LISTENER, /* options */ null);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001194 }
Rubin Xue0781332016-08-19 11:20:34 +01001195 } finally {
1196 Binder.restoreCallingIdentity(identity);
Rubin Xu83a15bc2016-08-10 10:53:24 +01001197 }
Clara Bayarri56878a92015-10-29 15:43:55 +00001198 }
Adrian Roosc13723f2016-01-12 20:29:03 +01001199
1200 @Override
1201 public boolean isTrustUsuallyManaged(int userId) {
1202 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1203 "query trust state");
1204 return isTrustUsuallyManagedInternal(userId);
1205 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001206
1207 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001208 public void unlockedByBiometricForUser(int userId, BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001209 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001210 synchronized(mUsersUnlockedByBiometric) {
1211 mUsersUnlockedByBiometric.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001212 }
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001213 // In extend unlock mode we need to refresh trust state here, which will call
1214 // refreshDeviceLockedForUser()
1215 int updateTrustOnUnlock = mSettingsObserver.getTrustAgentsExtendUnlock() ? 1 : 0;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001216 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001217 updateTrustOnUnlock).sendToTarget();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001218 }
1219
1220 @Override
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001221 public void clearAllBiometricRecognized(BiometricSourceType biometricSource) {
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001222 enforceReportPermission();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001223 synchronized(mUsersUnlockedByBiometric) {
1224 mUsersUnlockedByBiometric.clear();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001225 }
1226 mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
1227 0 /* arg2 */).sendToTarget();
1228 }
Adrian Roos82142c22014-03-27 14:56:59 +01001229 };
1230
Adrian Roosc13723f2016-01-12 20:29:03 +01001231 private boolean isTrustUsuallyManagedInternal(int userId) {
1232 synchronized (mTrustUsuallyManagedForUser) {
1233 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1234 if (i >= 0) {
1235 return mTrustUsuallyManagedForUser.valueAt(i);
1236 }
1237 }
1238 // It's not in memory yet, get the value from persisted storage instead
1239 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
1240 synchronized (mTrustUsuallyManagedForUser) {
1241 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1242 if (i >= 0) {
1243 // Someone set the trust usually managed in the mean time. Better use that.
1244 return mTrustUsuallyManagedForUser.valueAt(i);
1245 } else {
1246 // .. otherwise it's safe to cache the fetched value now.
1247 mTrustUsuallyManagedForUser.put(userId, persistedValue);
1248 return persistedValue;
1249 }
1250 }
1251 }
1252
Adrian Roosbcd07652014-10-22 16:57:16 +02001253 private int resolveProfileParent(int userId) {
1254 long identity = Binder.clearCallingIdentity();
1255 try {
1256 UserInfo parent = mUserManager.getProfileParent(userId);
1257 if (parent != null) {
1258 return parent.getUserHandle().getIdentifier();
1259 }
1260 return userId;
1261 } finally {
1262 Binder.restoreCallingIdentity(identity);
1263 }
1264 }
1265
Adrian Roos82142c22014-03-27 14:56:59 +01001266 private final Handler mHandler = new Handler() {
1267 @Override
1268 public void handleMessage(Message msg) {
1269 switch (msg.what) {
1270 case MSG_REGISTER_LISTENER:
1271 addListener((ITrustListener) msg.obj);
1272 break;
1273 case MSG_UNREGISTER_LISTENER:
1274 removeListener((ITrustListener) msg.obj);
1275 break;
1276 case MSG_DISPATCH_UNLOCK_ATTEMPT:
1277 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
1278 break;
Zachary Iqbal327323d2017-01-12 14:41:13 -08001279 case MSG_DISPATCH_UNLOCK_LOCKOUT:
1280 dispatchUnlockLockout(msg.arg1, msg.arg2);
1281 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001282 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -07001283 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +01001284 // This is also called when the security mode of a user changes.
1285 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001286 break;
Adrian Roos481a6df2014-11-20 19:48:56 +01001287 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +01001288 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +01001289 break;
1290 case MSG_START_USER:
1291 case MSG_CLEANUP_USER:
Adrian Roos68771eb2016-05-03 14:02:36 -07001292 case MSG_UNLOCK_USER:
Adrian Roos481a6df2014-11-20 19:48:56 +01001293 refreshAgentList(msg.arg1);
1294 break;
1295 case MSG_SWITCH_USER:
1296 mCurrentUser = msg.arg1;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001297 mSettingsObserver.updateContentObserver();
Adrian Roos481a6df2014-11-20 19:48:56 +01001298 refreshDeviceLockedForUser(UserHandle.USER_ALL);
1299 break;
Andrew Scull85a63bc2016-10-24 13:47:47 +01001300 case MSG_STOP_USER:
1301 setDeviceLockedForUser(msg.arg1, true);
1302 break;
Adrian Roosc13723f2016-01-12 20:29:03 +01001303 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
1304 SparseBooleanArray usuallyManaged;
1305 synchronized (mTrustUsuallyManagedForUser) {
1306 usuallyManaged = mTrustUsuallyManagedForUser.clone();
1307 }
1308
1309 for (int i = 0; i < usuallyManaged.size(); i++) {
1310 int userId = usuallyManaged.keyAt(i);
1311 boolean value = usuallyManaged.valueAt(i);
1312 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
1313 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
1314 }
1315 }
Adrian Roos68771eb2016-05-03 14:02:36 -07001316 break;
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001317 case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001318 if (msg.arg2 == 1) {
1319 updateTrust(msg.arg1, 0 /* flags */, true);
1320 }
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001321 refreshDeviceLockedForUser(msg.arg1);
1322 break;
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001323 case MSG_SCHEDULE_TRUST_TIMEOUT:
1324 handleScheduleTrustTimeout(msg.arg1, msg.arg2);
1325 break;
Adrian Roos82142c22014-03-27 14:56:59 +01001326 }
1327 }
1328 };
1329
1330 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1331 @Override
1332 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -07001333 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +01001334 }
1335
1336 @Override
1337 public boolean onPackageChanged(String packageName, int uid, String[] components) {
1338 // We're interested in all changes, even if just some components get enabled / disabled.
1339 return true;
1340 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +02001341
1342 @Override
1343 public void onPackageDisappeared(String packageName, int reason) {
1344 removeAgentsOfPackage(packageName);
1345 }
Adrian Roos82142c22014-03-27 14:56:59 +01001346 };
Adrian Roosca36b952014-05-16 18:52:29 +02001347
Lingjun Li20914d72016-11-14 15:39:13 -08001348 private static class SettingsAttrs {
1349 public ComponentName componentName;
1350 public boolean canUnlockProfile;
1351
1352 public SettingsAttrs(
1353 ComponentName componentName,
1354 boolean canUnlockProfile) {
1355 this.componentName = componentName;
1356 this.canUnlockProfile = canUnlockProfile;
1357 }
1358 };
1359
Adrian Roos9dbe1902014-08-13 18:25:52 +02001360 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +02001361
1362 @Override
1363 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +02001364 String action = intent.getAction();
1365 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -07001366 refreshAgentList(getSendingUserId());
1367 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +02001368 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +01001369 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +02001370 if (userId > 0) {
1371 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +02001372 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001373 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
1374 int userId = getUserId(intent);
1375 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +01001376 synchronized (mUserIsTrusted) {
1377 mUserIsTrusted.delete(userId);
1378 }
1379 synchronized (mDeviceLockedForUser) {
1380 mDeviceLockedForUser.delete(userId);
1381 }
Adrian Roosae025822016-11-03 14:46:13 -07001382 synchronized (mTrustUsuallyManagedForUser) {
1383 mTrustUsuallyManagedForUser.delete(userId);
1384 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001385 synchronized (mUsersUnlockedByBiometric) {
1386 mUsersUnlockedByBiometric.delete(userId);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001387 }
Adrian Rooscbe614f2014-10-28 20:16:12 +01001388 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +01001389 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001390 }
1391 }
1392 }
1393
1394 private int getUserId(Intent intent) {
1395 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
1396 if (userId > 0) {
1397 return userId;
1398 } else {
1399 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
1400 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +02001401 }
1402 }
1403
1404 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +02001405 IntentFilter filter = new IntentFilter();
1406 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Adrian Roos3870d452014-09-05 18:22:28 +02001407 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +01001408 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +02001409 context.registerReceiverAsUser(this,
1410 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +02001411 filter,
Adrian Roosca36b952014-05-16 18:52:29 +02001412 null /* permission */,
1413 null /* scheduler */);
1414 }
1415 }
Adrian Roos517b3a42016-03-03 14:58:33 -08001416
1417 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1418
1419 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1420
1421 public StrongAuthTracker(Context context) {
1422 super(context);
1423 }
1424
1425 @Override
1426 public void onStrongAuthRequiredChanged(int userId) {
1427 mStartFromSuccessfulUnlock.delete(userId);
1428
1429 if (DEBUG) {
1430 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1431 + " trustAllowed=" + isTrustAllowedForUser(userId)
1432 + " agentsCanRun=" + canAgentsRunForUser(userId));
1433 }
1434
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001435 // Cancel pending alarms if we require some auth anyway.
1436 if (!isTrustAllowedForUser(userId)) {
1437 TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
1438 if (alarm != null && alarm.isQueued()) {
1439 alarm.setQueued(false /* isQueued */);
1440 mAlarmManager.cancel(alarm);
1441 }
1442 }
1443
Adrian Roos517b3a42016-03-03 14:58:33 -08001444 refreshAgentList(userId);
1445
1446 // The list of active trust agents may not have changed, if there was a previous call
1447 // to allowTrustFromUnlock, so we update the trust here too.
1448 updateTrust(userId, 0 /* flags */);
1449 }
1450
1451 boolean canAgentsRunForUser(int userId) {
1452 return mStartFromSuccessfulUnlock.get(userId)
1453 || super.isTrustAllowedForUser(userId);
1454 }
1455
1456 /**
1457 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1458 * changes again. Must only be called when we know about a successful unlock already
1459 * before the underlying StrongAuthTracker.
1460 *
1461 * Note that this only changes whether trust agents can be started, not the actual trusted
1462 * value.
1463 */
1464 void allowTrustFromUnlock(int userId) {
1465 if (userId < UserHandle.USER_SYSTEM) {
1466 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1467 }
1468 boolean previous = canAgentsRunForUser(userId);
1469 mStartFromSuccessfulUnlock.put(userId, true);
1470
1471 if (DEBUG) {
1472 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1473 + " trustAllowed=" + isTrustAllowedForUser(userId)
1474 + " agentsCanRun=" + canAgentsRunForUser(userId));
1475 }
1476
1477 if (canAgentsRunForUser(userId) != previous) {
1478 refreshAgentList(userId);
1479 }
1480 }
1481 }
Vishwath Mohan15f7dd02018-12-12 11:15:08 -08001482
1483 private class TrustTimeoutAlarmListener implements OnAlarmListener {
1484 private final int mUserId;
1485 private boolean mIsQueued = false;
1486
1487 TrustTimeoutAlarmListener(int userId) {
1488 mUserId = userId;
1489 }
1490
1491 @Override
1492 public void onAlarm() {
1493 mIsQueued = false;
1494 int strongAuthState = mStrongAuthTracker.getStrongAuthForUser(mUserId);
1495
1496 // Only fire if trust can unlock.
1497 if (mStrongAuthTracker.isTrustAllowedForUser(mUserId)) {
1498 if (DEBUG) Slog.d(TAG, "Revoking all trust because of trust timeout");
1499 mLockPatternUtils.requireStrongAuth(
1500 mStrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, mUserId);
1501 }
1502 maybeLockScreen(mUserId);
1503 }
1504
1505 public void setQueued(boolean isQueued) {
1506 mIsQueued = isQueued;
1507 }
1508
1509 public boolean isQueued() {
1510 return mIsQueued;
1511 }
1512 }
Adrian Roos82142c22014-03-27 14:56:59 +01001513}