blob: b38d33d14b8be39cb890f7d0d6646dc316cf5839 [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 Roosbcd07652014-10-22 16:57:16 +020019import com.android.internal.annotations.GuardedBy;
Adrian Roos82142c22014-03-27 14:56:59 +010020import com.android.internal.content.PackageMonitor;
21import com.android.internal.widget.LockPatternUtils;
22import com.android.server.SystemService;
23
24import org.xmlpull.v1.XmlPullParser;
25import org.xmlpull.v1.XmlPullParserException;
26
27import android.Manifest;
Adrian Roosbcd07652014-10-22 16:57:16 +020028import android.app.ActivityManager;
Adrian Roosca36b952014-05-16 18:52:29 +020029import android.app.admin.DevicePolicyManager;
Adrian Roos82142c22014-03-27 14:56:59 +010030import android.app.trust.ITrustListener;
31import android.app.trust.ITrustManager;
Adrian Roosca36b952014-05-16 18:52:29 +020032import android.content.BroadcastReceiver;
Adrian Roos82142c22014-03-27 14:56:59 +010033import android.content.ComponentName;
34import android.content.Context;
35import android.content.Intent;
Adrian Roosca36b952014-05-16 18:52:29 +020036import android.content.IntentFilter;
Adrian Roos3870d452014-09-05 18:22:28 +020037import android.content.pm.ApplicationInfo;
Adrian Roos82142c22014-03-27 14:56:59 +010038import android.content.pm.PackageManager;
39import android.content.pm.ResolveInfo;
40import android.content.pm.UserInfo;
41import android.content.res.Resources;
42import android.content.res.TypedArray;
43import android.content.res.XmlResourceParser;
44import android.graphics.drawable.Drawable;
Adrian Roosbcd07652014-10-22 16:57:16 +020045import android.os.Binder;
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;
57import android.util.ArraySet;
58import android.util.AttributeSet;
Adrian Roos18ea8932014-05-28 14:53:06 +020059import android.util.Log;
Adrian Roos82142c22014-03-27 14:56:59 +010060import android.util.Slog;
Adrian Roos7046bfd2014-05-16 21:20:54 +020061import android.util.SparseBooleanArray;
Adrian Roos82142c22014-03-27 14:56:59 +010062import android.util.Xml;
Adrian Roos481a6df2014-11-20 19:48:56 +010063import android.view.IWindowManager;
Adrian Roos50bfeec2014-11-20 16:21:11 +010064import android.view.WindowManagerGlobal;
Adrian Roos82142c22014-03-27 14:56:59 +010065
Adrian Roos7a4f3d42014-05-02 12:12:20 +020066import java.io.FileDescriptor;
Adrian Roos82142c22014-03-27 14:56:59 +010067import java.io.IOException;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020068import java.io.PrintWriter;
Adrian Roos82142c22014-03-27 14:56:59 +010069import java.util.ArrayList;
70import java.util.List;
71
72/**
73 * Manages trust agents and trust listeners.
74 *
75 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
76 * of each user and notifies them about events that are relevant to them.
77 * It start and stops them based on the value of
78 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
79 *
80 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
81 * trust state changes for any user.
82 *
83 * Trust state and the setting of enabled agents is kept per user and each user has its own
84 * instance of a {@link android.service.trust.TrustAgentService}.
85 */
86public class TrustManagerService extends SystemService {
87
88 private static final boolean DEBUG = false;
89 private static final String TAG = "TrustManagerService";
90
91 private static final Intent TRUST_AGENT_INTENT =
92 new Intent(TrustAgentService.SERVICE_INTERFACE);
Adrian Roos18ea8932014-05-28 14:53:06 +020093 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
Adrian Roos82142c22014-03-27 14:56:59 +010094
95 private static final int MSG_REGISTER_LISTENER = 1;
96 private static final int MSG_UNREGISTER_LISTENER = 2;
97 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
98 private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
Adrian Roos2c12cfa2014-06-25 23:28:53 +020099 private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
Adrian Roos481a6df2014-11-20 19:48:56 +0100100 private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
101 private static final int MSG_START_USER = 7;
102 private static final int MSG_CLEANUP_USER = 8;
103 private static final int MSG_SWITCH_USER = 9;
Adrian Roos82142c22014-03-27 14:56:59 +0100104
105 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
106 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
Adrian Roos9dbe1902014-08-13 18:25:52 +0200107 private final Receiver mReceiver = new Receiver();
Adrian Roos7046bfd2014-05-16 21:20:54 +0200108 private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200109 /* package */ final TrustArchive mArchive = new TrustArchive();
Adrian Roos82142c22014-03-27 14:56:59 +0100110 private final Context mContext;
Adrian Roos3870d452014-09-05 18:22:28 +0200111 private final LockPatternUtils mLockPatternUtils;
Adrian Roosbcd07652014-10-22 16:57:16 +0200112 private final UserManager mUserManager;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100113 private final ActivityManager mActivityManager;
Adrian Roos82142c22014-03-27 14:56:59 +0100114
Adrian Roosbcd07652014-10-22 16:57:16 +0200115 @GuardedBy("mUserIsTrusted")
116 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
Adrian Roos82142c22014-03-27 14:56:59 +0100117
Adrian Roos481a6df2014-11-20 19:48:56 +0100118 @GuardedBy("mDeviceLockedForUser")
119 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
120
Adrian Rooscbe614f2014-10-28 20:16:12 +0100121 private boolean mTrustAgentsCanRun = false;
Adrian Roos481a6df2014-11-20 19:48:56 +0100122 private int mCurrentUser = UserHandle.USER_OWNER;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100123
Adrian Roos82142c22014-03-27 14:56:59 +0100124 public TrustManagerService(Context context) {
125 super(context);
126 mContext = context;
127 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100128 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200129 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100130 }
131
132 @Override
133 public void onStart() {
134 publishBinderService(Context.TRUST_SERVICE, mService);
135 }
136
137 @Override
138 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200139 if (isSafeMode()) {
140 // No trust agents in safe mode.
141 return;
142 }
143 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100144 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200145 mReceiver.register(mContext);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100146 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
147 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700148 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200149 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Adrian Roos7b4a38b2014-10-21 17:07:39 +0200150 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER);
Adrian Roos82142c22014-03-27 14:56:59 +0100151 }
152 }
153
154 // Agent management
155
156 private static final class AgentInfo {
157 CharSequence label;
158 Drawable icon;
159 ComponentName component; // service that implements ITrustAgent
160 ComponentName settings; // setting to launch to modify agent.
161 TrustAgentWrapper agent;
162 int userId;
163
164 @Override
165 public boolean equals(Object other) {
166 if (!(other instanceof AgentInfo)) {
167 return false;
168 }
169 AgentInfo o = (AgentInfo) other;
170 return component.equals(o.component) && userId == o.userId;
171 }
172
173 @Override
174 public int hashCode() {
175 return component.hashCode() * 31 + userId;
176 }
177 }
178
179 private void updateTrustAll() {
180 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
181 for (UserInfo userInfo : userInfos) {
Adrian Roos3c9a3502014-08-06 19:09:45 +0200182 updateTrust(userInfo.id, false);
Adrian Roos82142c22014-03-27 14:56:59 +0100183 }
184 }
185
Adrian Roos3c9a3502014-08-06 19:09:45 +0200186 public void updateTrust(int userId, boolean initiatedByUser) {
Adrian Roos7861c662014-07-25 15:37:28 +0200187 dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200188 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100189 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200190 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100191 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200192 mUserIsTrusted.put(userId, trusted);
193 }
194 dispatchOnTrustChanged(trusted, userId, initiatedByUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100195 if (changed) {
196 refreshDeviceLockedForUser(userId);
197 }
Adrian Roos82142c22014-03-27 14:56:59 +0100198 }
199
Marco Fucci4e68f112014-08-29 12:31:48 -0700200 void refreshAgentList(int userId) {
Adrian Roos82142c22014-03-27 14:56:59 +0100201 if (DEBUG) Slog.d(TAG, "refreshAgentList()");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100202 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200203 return;
204 }
Adrian Roose681c272014-09-08 14:03:47 +0200205 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
206 Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
207 + " must be USER_ALL or a specific user.", new Throwable("here"));
208 userId = UserHandle.USER_ALL;
209 }
Adrian Roos82142c22014-03-27 14:56:59 +0100210 PackageManager pm = mContext.getPackageManager();
211
Marco Fucci4e68f112014-08-29 12:31:48 -0700212 List<UserInfo> userInfos;
213 if (userId == UserHandle.USER_ALL) {
214 userInfos = mUserManager.getUsers(true /* excludeDying */);
215 } else {
216 userInfos = new ArrayList<>();
217 userInfos.add(mUserManager.getUserInfo(userId));
218 }
Adrian Roos3870d452014-09-05 18:22:28 +0200219 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100220
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200221 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
222 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100223
224 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100225 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
226 || userInfo.guestToRemove) continue;
Adrian Roos3870d452014-09-05 18:22:28 +0200227 if (!userInfo.supportsSwitchTo()) continue;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100228 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
Adrian Roos481a6df2014-11-20 19:48:56 +0100229 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
Marco Fucci4e68f112014-08-29 12:31:48 -0700230 if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200231 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
232 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700233 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200234 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
235
Adrian Roos82142c22014-03-27 14:56:59 +0100236 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200237 if (enabledAgents == null) {
Adrian Roos82142c22014-03-27 14:56:59 +0100238 continue;
239 }
Adrian Roos3870d452014-09-05 18:22:28 +0200240 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100241 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100242 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100243
Adrian Roos3870d452014-09-05 18:22:28 +0200244 if (!enabledAgents.contains(name)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200245 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700246 List<PersistableBundle> config =
247 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200248 // Disable agent if no features are enabled.
Jim Millere303bf42014-08-26 17:12:29 -0700249 if (config == null || config.isEmpty()) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200250 }
251
Adrian Roos82142c22014-03-27 14:56:59 +0100252 AgentInfo agentInfo = new AgentInfo();
253 agentInfo.component = name;
254 agentInfo.userId = userInfo.id;
255 if (!mActiveAgents.contains(agentInfo)) {
256 agentInfo.label = resolveInfo.loadLabel(pm);
257 agentInfo.icon = resolveInfo.loadIcon(pm);
258 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
259 agentInfo.agent = new TrustAgentWrapper(mContext, this,
260 new Intent().setComponent(name), userInfo.getUserHandle());
261 mActiveAgents.add(agentInfo);
262 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200263 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100264 }
265 }
266 }
267
268 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200269 for (int i = 0; i < obsoleteAgents.size(); i++) {
270 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roose681c272014-09-08 14:03:47 +0200271 if (userId == UserHandle.USER_ALL || userId == info.userId) {
272 if (info.agent.isManagingTrust()) {
273 trustMayHaveChanged = true;
274 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100275 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200276 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100277 }
Adrian Roos82142c22014-03-27 14:56:59 +0100278 }
279
280 if (trustMayHaveChanged) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100281 if (userId == UserHandle.USER_ALL) {
282 updateTrustAll();
283 } else {
284 updateTrust(userId, false /* initiatedByUser */);
285 }
Adrian Roos82142c22014-03-27 14:56:59 +0100286 }
287 }
288
Adrian Roos481a6df2014-11-20 19:48:56 +0100289 boolean isDeviceLockedInner(int userId) {
290 synchronized (mDeviceLockedForUser) {
291 return mDeviceLockedForUser.get(userId, true);
292 }
293 }
294
295 private void refreshDeviceLockedForUser(int userId) {
296 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100297 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100298 + " must be USER_ALL or a specific user.", new Throwable("here"));
299 userId = UserHandle.USER_ALL;
300 }
301
302 List<UserInfo> userInfos;
303 if (userId == UserHandle.USER_ALL) {
304 userInfos = mUserManager.getUsers(true /* excludeDying */);
305 } else {
306 userInfos = new ArrayList<>();
307 userInfos.add(mUserManager.getUserInfo(userId));
308 }
309
310 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
311
312 for (int i = 0; i < userInfos.size(); i++) {
313 UserInfo info = userInfos.get(i);
314
315 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
316 || !info.supportsSwitchTo()) {
317 continue;
318 }
319
320 int id = info.id;
321 boolean secure = mLockPatternUtils.isSecure(id);
322 boolean trusted = aggregateIsTrusted(id);
323 boolean showingKeyguard = true;
324 if (mCurrentUser == id) {
325 try {
326 showingKeyguard = wm.isKeyguardLocked();
327 } catch (RemoteException e) {
328 }
329 }
330 boolean deviceLocked = secure && showingKeyguard && !trusted;
331
332 boolean changed;
333 synchronized (mDeviceLockedForUser) {
334 changed = isDeviceLockedInner(id) != deviceLocked;
335 mDeviceLockedForUser.put(id, deviceLocked);
336 }
337 if (changed) {
338 dispatchDeviceLocked(id, deviceLocked);
339 }
340 }
341 }
342
343 private void dispatchDeviceLocked(int userId, boolean isLocked) {
344 for (int i = 0; i < mActiveAgents.size(); i++) {
345 AgentInfo agent = mActiveAgents.valueAt(i);
346 if (agent.userId == userId) {
347 if (isLocked) {
348 agent.agent.onDeviceLocked();
349 } else{
350 agent.agent.onDeviceUnlocked();
351 }
352 }
353 }
354 }
355
Marco Fucci4e68f112014-08-29 12:31:48 -0700356 void updateDevicePolicyFeatures() {
Adrian Roos8f211582014-07-29 15:09:57 +0200357 for (int i = 0; i < mActiveAgents.size(); i++) {
358 AgentInfo info = mActiveAgents.valueAt(i);
359 if (info.agent.isConnected()) {
360 info.agent.updateDevicePolicyFeatures();
361 }
362 }
363 }
364
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200365 private void removeAgentsOfPackage(String packageName) {
366 boolean trustMayHaveChanged = false;
367 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
368 AgentInfo info = mActiveAgents.valueAt(i);
369 if (packageName.equals(info.component.getPackageName())) {
370 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200371 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200372 trustMayHaveChanged = true;
373 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100374 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200375 mActiveAgents.removeAt(i);
376 }
377 }
378 if (trustMayHaveChanged) {
379 updateTrustAll();
380 }
381 }
382
383 public void resetAgent(ComponentName name, int userId) {
384 boolean trustMayHaveChanged = false;
385 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
386 AgentInfo info = mActiveAgents.valueAt(i);
387 if (name.equals(info.component) && userId == info.userId) {
388 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200389 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200390 trustMayHaveChanged = true;
391 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100392 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200393 mActiveAgents.removeAt(i);
394 }
395 }
396 if (trustMayHaveChanged) {
Adrian Roos3c9a3502014-08-06 19:09:45 +0200397 updateTrust(userId, false);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200398 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700399 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200400 }
401
Adrian Roos82142c22014-03-27 14:56:59 +0100402 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
403 if (resolveInfo == null || resolveInfo.serviceInfo == null
404 || resolveInfo.serviceInfo.metaData == null) return null;
405 String cn = null;
406 XmlResourceParser parser = null;
407 Exception caughtException = null;
408 try {
409 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
410 TrustAgentService.TRUST_AGENT_META_DATA);
411 if (parser == null) {
412 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
413 return null;
414 }
415 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
416 AttributeSet attrs = Xml.asAttributeSet(parser);
417 int type;
418 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
419 && type != XmlPullParser.START_TAG) {
420 // Drain preamble.
421 }
422 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200423 if (!"trust-agent".equals(nodeName)) {
424 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100425 return null;
426 }
427 TypedArray sa = res
428 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
429 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
430 sa.recycle();
431 } catch (PackageManager.NameNotFoundException e) {
432 caughtException = e;
433 } catch (IOException e) {
434 caughtException = e;
435 } catch (XmlPullParserException e) {
436 caughtException = e;
437 } finally {
438 if (parser != null) parser.close();
439 }
440 if (caughtException != null) {
441 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
442 return null;
443 }
444 if (cn == null) {
445 return null;
446 }
447 if (cn.indexOf('/') < 0) {
448 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
449 }
450 return ComponentName.unflattenFromString(cn);
451 }
452
453 private ComponentName getComponentName(ResolveInfo resolveInfo) {
454 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
455 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
456 }
457
Adrian Roos3870d452014-09-05 18:22:28 +0200458 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
459 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
460 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
461 return;
462 }
463 PackageManager pm = mContext.getPackageManager();
464 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
465 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
466 for (ResolveInfo resolveInfo : resolveInfos) {
467 ComponentName componentName = getComponentName(resolveInfo);
468 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
469 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
470 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
471 + "is not a system package.");
472 continue;
473 }
474 discoveredAgents.add(componentName);
475 }
476
477 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
478 if (previouslyEnabledAgents != null) {
479 discoveredAgents.addAll(previouslyEnabledAgents);
480 }
481 utils.setEnabledTrustAgents(discoveredAgents, userId);
482 Settings.Secure.putIntForUser(mContext.getContentResolver(),
483 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
484 }
485
486 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
487 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
488 0 /* flags */, userId);
489 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
490 for (ResolveInfo resolveInfo : resolveInfos) {
491 if (resolveInfo.serviceInfo == null) continue;
492 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
493 String packageName = resolveInfo.serviceInfo.packageName;
494 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
495 != PackageManager.PERMISSION_GRANTED) {
496 ComponentName name = getComponentName(resolveInfo);
497 Log.w(TAG, "Skipping agent " + name + " because package does not have"
498 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
499 continue;
500 }
501 allowedAgents.add(resolveInfo);
502 }
503 return allowedAgents;
504 }
505
Adrian Roos82142c22014-03-27 14:56:59 +0100506 // Agent dispatch and aggregation
507
508 private boolean aggregateIsTrusted(int userId) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200509 if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
510 return false;
511 }
Adrian Roos82142c22014-03-27 14:56:59 +0100512 for (int i = 0; i < mActiveAgents.size(); i++) {
513 AgentInfo info = mActiveAgents.valueAt(i);
514 if (info.userId == userId) {
515 if (info.agent.isTrusted()) {
516 return true;
517 }
518 }
519 }
520 return false;
521 }
522
Adrian Roos7861c662014-07-25 15:37:28 +0200523 private boolean aggregateIsTrustManaged(int userId) {
524 if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
525 return false;
526 }
527 for (int i = 0; i < mActiveAgents.size(); i++) {
528 AgentInfo info = mActiveAgents.valueAt(i);
529 if (info.userId == userId) {
530 if (info.agent.isManagingTrust()) {
531 return true;
532 }
533 }
534 }
535 return false;
536 }
537
Adrian Roos82142c22014-03-27 14:56:59 +0100538 private void dispatchUnlockAttempt(boolean successful, int userId) {
539 for (int i = 0; i < mActiveAgents.size(); i++) {
540 AgentInfo info = mActiveAgents.valueAt(i);
541 if (info.userId == userId) {
542 info.agent.onUnlockAttempt(successful);
543 }
544 }
Adrian Roos7046bfd2014-05-16 21:20:54 +0200545
Adrian Roos9dbe1902014-08-13 18:25:52 +0200546 if (successful) {
547 updateUserHasAuthenticated(userId);
548 }
549 }
550
551 private void updateUserHasAuthenticated(int userId) {
552 if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200553 mUserHasAuthenticatedSinceBoot.put(userId, true);
Marco Fucci4e68f112014-08-29 12:31:48 -0700554 refreshAgentList(userId);
Adrian Roos7046bfd2014-05-16 21:20:54 +0200555 }
Adrian Roos82142c22014-03-27 14:56:59 +0100556 }
557
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200558
559 private void requireCredentialEntry(int userId) {
560 if (userId == UserHandle.USER_ALL) {
561 mUserHasAuthenticatedSinceBoot.clear();
Marco Fucci4e68f112014-08-29 12:31:48 -0700562 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200563 } else {
564 mUserHasAuthenticatedSinceBoot.put(userId, false);
Marco Fucci4e68f112014-08-29 12:31:48 -0700565 refreshAgentList(userId);
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200566 }
567 }
568
Adrian Roos82142c22014-03-27 14:56:59 +0100569 // Listeners
570
571 private void addListener(ITrustListener listener) {
572 for (int i = 0; i < mTrustListeners.size(); i++) {
573 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
574 return;
575 }
576 }
577 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200578 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100579 }
580
581 private void removeListener(ITrustListener listener) {
582 for (int i = 0; i < mTrustListeners.size(); i++) {
583 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700584 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100585 return;
586 }
587 }
588 }
589
Adrian Roos3c9a3502014-08-06 19:09:45 +0200590 private void dispatchOnTrustChanged(boolean enabled, int userId, boolean initiatedByUser) {
591 if (!enabled) initiatedByUser = false;
Adrian Roos82142c22014-03-27 14:56:59 +0100592 for (int i = 0; i < mTrustListeners.size(); i++) {
593 try {
Adrian Roos3c9a3502014-08-06 19:09:45 +0200594 mTrustListeners.get(i).onTrustChanged(enabled, userId, initiatedByUser);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200595 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200596 Slog.d(TAG, "Removing dead TrustListener.");
597 mTrustListeners.remove(i);
598 i--;
599 } catch (RemoteException e) {
600 Slog.e(TAG, "Exception while notifying TrustListener.", e);
601 }
602 }
603 }
604
605 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
606 for (int i = 0; i < mTrustListeners.size(); i++) {
607 try {
608 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
609 } catch (DeadObjectException e) {
610 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200611 mTrustListeners.remove(i);
612 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100613 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200614 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100615 }
616 }
617 }
618
Adrian Rooscbe614f2014-10-28 20:16:12 +0100619 // User lifecycle
620
621 @Override
622 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100623 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100624 }
625
626 @Override
627 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100628 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
629 }
630
631 @Override
632 public void onSwitchUser(int userId) {
633 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100634 }
635
Adrian Roos82142c22014-03-27 14:56:59 +0100636 // Plumbing
637
638 private final IBinder mService = new ITrustManager.Stub() {
639 @Override
640 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
641 enforceReportPermission();
642 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
643 .sendToTarget();
644 }
645
646 @Override
647 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
648 enforceReportPermission();
649 // coalesce refresh messages.
650 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
651 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
652 }
653
654 @Override
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200655 public void reportRequireCredentialEntry(int userId) throws RemoteException {
656 enforceReportPermission();
657 if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
658 mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget();
659 } else {
660 throw new IllegalArgumentException(
661 "userId must be an explicit user id or USER_ALL");
662 }
663 }
664
665 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100666 public void reportKeyguardShowingChanged() throws RemoteException {
667 enforceReportPermission();
668 // coalesce refresh messages.
669 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
670 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
671 }
672
673 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100674 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
675 enforceListenerPermission();
676 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
677 }
678
679 @Override
680 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
681 enforceListenerPermission();
682 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
683 }
684
Adrian Roosbcd07652014-10-22 16:57:16 +0200685 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100686 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200687 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100688 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roosbcd07652014-10-22 16:57:16 +0200689 userId = resolveProfileParent(userId);
Adrian Roos50bfeec2014-11-20 16:21:11 +0100690
Adrian Roos481a6df2014-11-20 19:48:56 +0100691 return isDeviceLockedInner(userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200692 }
693
Adrian Roos82893682015-04-02 16:17:46 +0200694 @Override
695 public boolean isDeviceSecure(int userId) throws RemoteException {
696 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
697 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
698 userId = resolveProfileParent(userId);
699
700 long token = Binder.clearCallingIdentity();
701 try {
702 return new LockPatternUtils(mContext).isSecure(userId);
703 } finally {
704 Binder.restoreCallingIdentity(token);
705 }
706 }
707
Adrian Roos82142c22014-03-27 14:56:59 +0100708 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200709 mContext.enforceCallingOrSelfPermission(
710 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100711 }
712
713 private void enforceListenerPermission() {
714 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
715 "register trust listener");
716 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200717
718 @Override
719 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
720 mContext.enforceCallingPermission(Manifest.permission.DUMP,
721 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200722 if (isSafeMode()) {
723 fout.println("disabled because the system is in safe mode.");
724 return;
725 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100726 if (!mTrustAgentsCanRun) {
727 fout.println("disabled because the third-party apps can't run yet.");
728 return;
729 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200730 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200731 mHandler.runWithScissors(new Runnable() {
732 @Override
733 public void run() {
734 fout.println("Trust manager state:");
735 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100736 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200737 }
738 }
739 }, 1500);
740 }
741
742 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
743 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
744 user.name, user.id, user.flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100745 if (!user.supportsSwitchTo()) {
746 fout.println("(managed profile)");
747 fout.println(" disabled because switching to this user is not possible.");
748 return;
749 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200750 if (isCurrent) {
751 fout.print(" (current)");
752 }
753 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200754 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100755 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200756 fout.println();
757 fout.println(" Enabled agents:");
758 boolean duplicateSimpleNames = false;
759 ArraySet<String> simpleNames = new ArraySet<String>();
760 for (AgentInfo info : mActiveAgents) {
761 if (info.userId != user.id) { continue; }
762 boolean trusted = info.agent.isTrusted();
763 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200764 fout.print(" bound=" + dumpBool(info.agent.isBound()));
765 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200766 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
767 fout.print(", trusted=" + dumpBool(trusted));
768 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200769 if (trusted) {
770 fout.println(" message=\"" + info.agent.getMessage() + "\"");
771 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200772 if (!info.agent.isConnected()) {
773 String restartTime = TrustArchive.formatDuration(
774 info.agent.getScheduledRestartUptimeMillis()
775 - SystemClock.uptimeMillis());
776 fout.println(" restartScheduledAt=" + restartTime);
777 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200778 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
779 duplicateSimpleNames = true;
780 }
781 }
782 fout.println(" Events:");
783 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
784 fout.println();
785 }
786
787 private String dumpBool(boolean b) {
788 return b ? "1" : "0";
789 }
Adrian Roos82142c22014-03-27 14:56:59 +0100790 };
791
Adrian Roosbcd07652014-10-22 16:57:16 +0200792 private int resolveProfileParent(int userId) {
793 long identity = Binder.clearCallingIdentity();
794 try {
795 UserInfo parent = mUserManager.getProfileParent(userId);
796 if (parent != null) {
797 return parent.getUserHandle().getIdentifier();
798 }
799 return userId;
800 } finally {
801 Binder.restoreCallingIdentity(identity);
802 }
803 }
804
Adrian Roos82142c22014-03-27 14:56:59 +0100805 private final Handler mHandler = new Handler() {
806 @Override
807 public void handleMessage(Message msg) {
808 switch (msg.what) {
809 case MSG_REGISTER_LISTENER:
810 addListener((ITrustListener) msg.obj);
811 break;
812 case MSG_UNREGISTER_LISTENER:
813 removeListener((ITrustListener) msg.obj);
814 break;
815 case MSG_DISPATCH_UNLOCK_ATTEMPT:
816 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
817 break;
818 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700819 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100820 // This is also called when the security mode of a user changes.
821 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100822 break;
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200823 case MSG_REQUIRE_CREDENTIAL_ENTRY:
824 requireCredentialEntry(msg.arg1);
825 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100826 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100827 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100828 break;
829 case MSG_START_USER:
830 case MSG_CLEANUP_USER:
831 refreshAgentList(msg.arg1);
832 break;
833 case MSG_SWITCH_USER:
834 mCurrentUser = msg.arg1;
835 refreshDeviceLockedForUser(UserHandle.USER_ALL);
836 break;
Adrian Roos82142c22014-03-27 14:56:59 +0100837 }
838 }
839 };
840
841 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
842 @Override
843 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700844 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100845 }
846
847 @Override
848 public boolean onPackageChanged(String packageName, int uid, String[] components) {
849 // We're interested in all changes, even if just some components get enabled / disabled.
850 return true;
851 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200852
853 @Override
854 public void onPackageDisappeared(String packageName, int reason) {
855 removeAgentsOfPackage(packageName);
856 }
Adrian Roos82142c22014-03-27 14:56:59 +0100857 };
Adrian Roosca36b952014-05-16 18:52:29 +0200858
Adrian Roos9dbe1902014-08-13 18:25:52 +0200859 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200860
861 @Override
862 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200863 String action = intent.getAction();
864 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700865 refreshAgentList(getSendingUserId());
866 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200867 } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200868 updateUserHasAuthenticated(getSendingUserId());
Adrian Roos3870d452014-09-05 18:22:28 +0200869 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100870 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200871 if (userId > 0) {
872 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200873 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100874 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
875 int userId = getUserId(intent);
876 if (userId > 0) {
877 mUserHasAuthenticatedSinceBoot.delete(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100878 synchronized (mUserIsTrusted) {
879 mUserIsTrusted.delete(userId);
880 }
881 synchronized (mDeviceLockedForUser) {
882 mDeviceLockedForUser.delete(userId);
883 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100884 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100885 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100886 }
887 }
888 }
889
890 private int getUserId(Intent intent) {
891 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
892 if (userId > 0) {
893 return userId;
894 } else {
895 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
896 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200897 }
898 }
899
900 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200901 IntentFilter filter = new IntentFilter();
902 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
903 filter.addAction(Intent.ACTION_USER_PRESENT);
Adrian Roos3870d452014-09-05 18:22:28 +0200904 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100905 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200906 context.registerReceiverAsUser(this,
907 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200908 filter,
Adrian Roosca36b952014-05-16 18:52:29 +0200909 null /* permission */,
910 null /* scheduler */);
911 }
912 }
Adrian Roos82142c22014-03-27 14:56:59 +0100913}