blob: 78e3f7f087795182b327c19fa72d0907d5c9b5bc [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;
Adrian Roosb5e47222015-08-14 15:53:06 -070022import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
Adrian Roos82142c22014-03-27 14:56:59 +010023import com.android.server.SystemService;
24
25import org.xmlpull.v1.XmlPullParser;
26import org.xmlpull.v1.XmlPullParserException;
27
28import android.Manifest;
Adrian Roosbcd07652014-10-22 16:57:16 +020029import android.app.ActivityManager;
Adrian Roosca36b952014-05-16 18:52:29 +020030import android.app.admin.DevicePolicyManager;
Adrian Roos82142c22014-03-27 14:56:59 +010031import android.app.trust.ITrustListener;
32import android.app.trust.ITrustManager;
Adrian Roosca36b952014-05-16 18:52:29 +020033import android.content.BroadcastReceiver;
Adrian Roos82142c22014-03-27 14:56:59 +010034import android.content.ComponentName;
35import android.content.Context;
36import android.content.Intent;
Adrian Roosca36b952014-05-16 18:52:29 +020037import android.content.IntentFilter;
Adrian Roos3870d452014-09-05 18:22:28 +020038import android.content.pm.ApplicationInfo;
Adrian Roos82142c22014-03-27 14:56:59 +010039import android.content.pm.PackageManager;
40import android.content.pm.ResolveInfo;
41import android.content.pm.UserInfo;
42import android.content.res.Resources;
43import android.content.res.TypedArray;
44import android.content.res.XmlResourceParser;
45import android.graphics.drawable.Drawable;
Adrian Roosbcd07652014-10-22 16:57:16 +020046import android.os.Binder;
Adrian Roosa4ba56b2014-05-20 12:56:25 +020047import android.os.DeadObjectException;
Adrian Roos82142c22014-03-27 14:56:59 +010048import android.os.Handler;
49import android.os.IBinder;
50import android.os.Message;
Jim Millere303bf42014-08-26 17:12:29 -070051import android.os.PersistableBundle;
Adrian Roos82142c22014-03-27 14:56:59 +010052import android.os.RemoteException;
Adrian Roosc5f95ce2014-07-24 16:00:46 +020053import android.os.SystemClock;
Adrian Roos82142c22014-03-27 14:56:59 +010054import android.os.UserHandle;
55import android.os.UserManager;
Adrian Roos3870d452014-09-05 18:22:28 +020056import android.provider.Settings;
Adrian Roos82142c22014-03-27 14:56:59 +010057import android.service.trust.TrustAgentService;
58import android.util.ArraySet;
59import android.util.AttributeSet;
Adrian Roos18ea8932014-05-28 14:53:06 +020060import android.util.Log;
Adrian Roos82142c22014-03-27 14:56:59 +010061import android.util.Slog;
Adrian Roos7046bfd2014-05-16 21:20:54 +020062import android.util.SparseBooleanArray;
Adrian Roosb5e47222015-08-14 15:53:06 -070063import android.util.SparseIntArray;
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;
Adrian Roos82142c22014-03-27 14:56:59 +010067
Adrian Roos7a4f3d42014-05-02 12:12:20 +020068import java.io.FileDescriptor;
Adrian Roos82142c22014-03-27 14:56:59 +010069import java.io.IOException;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020070import java.io.PrintWriter;
Adrian Roos82142c22014-03-27 14:56:59 +010071import java.util.ArrayList;
72import java.util.List;
73
74/**
75 * Manages trust agents and trust listeners.
76 *
77 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
78 * of each user and notifies them about events that are relevant to them.
79 * It start and stops them based on the value of
80 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
81 *
82 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
83 * trust state changes for any user.
84 *
85 * Trust state and the setting of enabled agents is kept per user and each user has its own
86 * instance of a {@link android.service.trust.TrustAgentService}.
87 */
88public class TrustManagerService extends SystemService {
89
90 private static final boolean DEBUG = false;
91 private static final String TAG = "TrustManagerService";
92
93 private static final Intent TRUST_AGENT_INTENT =
94 new Intent(TrustAgentService.SERVICE_INTERFACE);
Adrian Roos18ea8932014-05-28 14:53:06 +020095 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
Adrian Roos82142c22014-03-27 14:56:59 +010096
97 private static final int MSG_REGISTER_LISTENER = 1;
98 private static final int MSG_UNREGISTER_LISTENER = 2;
99 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
100 private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
Adrian Roos481a6df2014-11-20 19:48:56 +0100101 private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
102 private static final int MSG_START_USER = 7;
103 private static final int MSG_CLEANUP_USER = 8;
104 private static final int MSG_SWITCH_USER = 9;
Clara Bayarri56878a92015-10-29 15:43:55 +0000105 private static final int MSG_SET_DEVICE_LOCKED = 10;
Adrian Roos82142c22014-03-27 14:56:59 +0100106
Adrian Roosb5e47222015-08-14 15:53:06 -0700107 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
108 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
Adrian Roos9dbe1902014-08-13 18:25:52 +0200109 private final Receiver mReceiver = new Receiver();
Adrian Roosb5e47222015-08-14 15:53:06 -0700110
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200111 /* package */ final TrustArchive mArchive = new TrustArchive();
Adrian Roos82142c22014-03-27 14:56:59 +0100112 private final Context mContext;
Adrian Roos3870d452014-09-05 18:22:28 +0200113 private final LockPatternUtils mLockPatternUtils;
Adrian Roosbcd07652014-10-22 16:57:16 +0200114 private final UserManager mUserManager;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100115 private final ActivityManager mActivityManager;
Adrian Roos82142c22014-03-27 14:56:59 +0100116
Adrian Roosbcd07652014-10-22 16:57:16 +0200117 @GuardedBy("mUserIsTrusted")
118 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
Adrian Roos82142c22014-03-27 14:56:59 +0100119
Adrian Roos481a6df2014-11-20 19:48:56 +0100120 @GuardedBy("mDeviceLockedForUser")
121 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
122
Adrian Rooscbe614f2014-10-28 20:16:12 +0100123 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700124 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100125
Adrian Roos82142c22014-03-27 14:56:59 +0100126 public TrustManagerService(Context context) {
127 super(context);
128 mContext = context;
129 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100130 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200131 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100132 }
133
134 @Override
135 public void onStart() {
136 publishBinderService(Context.TRUST_SERVICE, mService);
137 }
138
139 @Override
140 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200141 if (isSafeMode()) {
142 // No trust agents in safe mode.
143 return;
144 }
145 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100146 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200147 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700148 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100149 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
150 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700151 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200152 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700153 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100154 }
155 }
156
157 // Agent management
158
159 private static final class AgentInfo {
160 CharSequence label;
161 Drawable icon;
162 ComponentName component; // service that implements ITrustAgent
163 ComponentName settings; // setting to launch to modify agent.
164 TrustAgentWrapper agent;
165 int userId;
166
167 @Override
168 public boolean equals(Object other) {
169 if (!(other instanceof AgentInfo)) {
170 return false;
171 }
172 AgentInfo o = (AgentInfo) other;
173 return component.equals(o.component) && userId == o.userId;
174 }
175
176 @Override
177 public int hashCode() {
178 return component.hashCode() * 31 + userId;
179 }
180 }
181
182 private void updateTrustAll() {
183 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
184 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700185 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100186 }
187 }
188
Adrian Roos94e15a52015-04-16 12:23:18 -0700189 public void updateTrust(int userId, int flags) {
Adrian Roos7861c662014-07-25 15:37:28 +0200190 dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200191 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100192 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200193 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100194 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200195 mUserIsTrusted.put(userId, trusted);
196 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700197 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100198 if (changed) {
199 refreshDeviceLockedForUser(userId);
200 }
Adrian Roos82142c22014-03-27 14:56:59 +0100201 }
202
Marco Fucci4e68f112014-08-29 12:31:48 -0700203 void refreshAgentList(int userId) {
Adrian Roos82142c22014-03-27 14:56:59 +0100204 if (DEBUG) Slog.d(TAG, "refreshAgentList()");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100205 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200206 return;
207 }
Xiaohui Chen09e02912015-08-05 09:44:56 -0700208 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roose681c272014-09-08 14:03:47 +0200209 Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
210 + " must be USER_ALL or a specific user.", new Throwable("here"));
211 userId = UserHandle.USER_ALL;
212 }
Adrian Roos82142c22014-03-27 14:56:59 +0100213 PackageManager pm = mContext.getPackageManager();
214
Marco Fucci4e68f112014-08-29 12:31:48 -0700215 List<UserInfo> userInfos;
216 if (userId == UserHandle.USER_ALL) {
217 userInfos = mUserManager.getUsers(true /* excludeDying */);
218 } else {
219 userInfos = new ArrayList<>();
220 userInfos.add(mUserManager.getUserInfo(userId));
221 }
Adrian Roos3870d452014-09-05 18:22:28 +0200222 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100223
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200224 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
225 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100226
227 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100228 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
229 || userInfo.guestToRemove) continue;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700230 if (!userInfo.supportsSwitchToByUser()) continue;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100231 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
Adrian Roos481a6df2014-11-20 19:48:56 +0100232 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
Adrian Roosb5e47222015-08-14 15:53:06 -0700233 if (!mStrongAuthTracker.isTrustAllowedForUser(userInfo.id)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200234 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
235 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700236 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200237 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
238
Adrian Roos82142c22014-03-27 14:56:59 +0100239 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200240 if (enabledAgents == null) {
Adrian Roos82142c22014-03-27 14:56:59 +0100241 continue;
242 }
Adrian Roos3870d452014-09-05 18:22:28 +0200243 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100244 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100245 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100246
Adrian Roos3870d452014-09-05 18:22:28 +0200247 if (!enabledAgents.contains(name)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200248 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700249 List<PersistableBundle> config =
250 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200251 // Disable agent if no features are enabled.
Jim Millere303bf42014-08-26 17:12:29 -0700252 if (config == null || config.isEmpty()) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200253 }
254
Adrian Roos82142c22014-03-27 14:56:59 +0100255 AgentInfo agentInfo = new AgentInfo();
256 agentInfo.component = name;
257 agentInfo.userId = userInfo.id;
258 if (!mActiveAgents.contains(agentInfo)) {
259 agentInfo.label = resolveInfo.loadLabel(pm);
260 agentInfo.icon = resolveInfo.loadIcon(pm);
261 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
262 agentInfo.agent = new TrustAgentWrapper(mContext, this,
263 new Intent().setComponent(name), userInfo.getUserHandle());
264 mActiveAgents.add(agentInfo);
265 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200266 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100267 }
268 }
269 }
270
271 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200272 for (int i = 0; i < obsoleteAgents.size(); i++) {
273 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roose681c272014-09-08 14:03:47 +0200274 if (userId == UserHandle.USER_ALL || userId == info.userId) {
275 if (info.agent.isManagingTrust()) {
276 trustMayHaveChanged = true;
277 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100278 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200279 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100280 }
Adrian Roos82142c22014-03-27 14:56:59 +0100281 }
282
283 if (trustMayHaveChanged) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100284 if (userId == UserHandle.USER_ALL) {
285 updateTrustAll();
286 } else {
Adrian Roos94e15a52015-04-16 12:23:18 -0700287 updateTrust(userId, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100288 }
Adrian Roos82142c22014-03-27 14:56:59 +0100289 }
290 }
291
Clara Bayarri56878a92015-10-29 15:43:55 +0000292 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarria1771112015-12-18 16:29:18 +0000293 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
294 synchronized (mDeviceLockedForUser) {
295 mDeviceLockedForUser.put(userId, locked);
Clara Bayarri56878a92015-10-29 15:43:55 +0000296 }
297 }
298 }
299
Adrian Roos481a6df2014-11-20 19:48:56 +0100300 boolean isDeviceLockedInner(int userId) {
301 synchronized (mDeviceLockedForUser) {
302 return mDeviceLockedForUser.get(userId, true);
303 }
304 }
305
306 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700307 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100308 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100309 + " must be USER_ALL or a specific user.", new Throwable("here"));
310 userId = UserHandle.USER_ALL;
311 }
312
313 List<UserInfo> userInfos;
314 if (userId == UserHandle.USER_ALL) {
315 userInfos = mUserManager.getUsers(true /* excludeDying */);
316 } else {
317 userInfos = new ArrayList<>();
318 userInfos.add(mUserManager.getUserInfo(userId));
319 }
320
321 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
322
323 for (int i = 0; i < userInfos.size(); i++) {
324 UserInfo info = userInfos.get(i);
325
326 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700327 || !info.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100328 continue;
329 }
330
331 int id = info.id;
332 boolean secure = mLockPatternUtils.isSecure(id);
333 boolean trusted = aggregateIsTrusted(id);
334 boolean showingKeyguard = true;
335 if (mCurrentUser == id) {
336 try {
337 showingKeyguard = wm.isKeyguardLocked();
338 } catch (RemoteException e) {
339 }
340 }
341 boolean deviceLocked = secure && showingKeyguard && !trusted;
342
343 boolean changed;
344 synchronized (mDeviceLockedForUser) {
345 changed = isDeviceLockedInner(id) != deviceLocked;
346 mDeviceLockedForUser.put(id, deviceLocked);
347 }
348 if (changed) {
349 dispatchDeviceLocked(id, deviceLocked);
350 }
351 }
352 }
353
354 private void dispatchDeviceLocked(int userId, boolean isLocked) {
355 for (int i = 0; i < mActiveAgents.size(); i++) {
356 AgentInfo agent = mActiveAgents.valueAt(i);
357 if (agent.userId == userId) {
358 if (isLocked) {
359 agent.agent.onDeviceLocked();
360 } else{
361 agent.agent.onDeviceUnlocked();
362 }
363 }
364 }
365 }
366
Marco Fucci4e68f112014-08-29 12:31:48 -0700367 void updateDevicePolicyFeatures() {
Adrian Roos8f211582014-07-29 15:09:57 +0200368 for (int i = 0; i < mActiveAgents.size(); i++) {
369 AgentInfo info = mActiveAgents.valueAt(i);
370 if (info.agent.isConnected()) {
371 info.agent.updateDevicePolicyFeatures();
372 }
373 }
374 }
375
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200376 private void removeAgentsOfPackage(String packageName) {
377 boolean trustMayHaveChanged = false;
378 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
379 AgentInfo info = mActiveAgents.valueAt(i);
380 if (packageName.equals(info.component.getPackageName())) {
381 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200382 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200383 trustMayHaveChanged = true;
384 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100385 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200386 mActiveAgents.removeAt(i);
387 }
388 }
389 if (trustMayHaveChanged) {
390 updateTrustAll();
391 }
392 }
393
394 public void resetAgent(ComponentName name, int userId) {
395 boolean trustMayHaveChanged = false;
396 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
397 AgentInfo info = mActiveAgents.valueAt(i);
398 if (name.equals(info.component) && userId == info.userId) {
399 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200400 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200401 trustMayHaveChanged = true;
402 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100403 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200404 mActiveAgents.removeAt(i);
405 }
406 }
407 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700408 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200409 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700410 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200411 }
412
Adrian Roos82142c22014-03-27 14:56:59 +0100413 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
414 if (resolveInfo == null || resolveInfo.serviceInfo == null
415 || resolveInfo.serviceInfo.metaData == null) return null;
416 String cn = null;
417 XmlResourceParser parser = null;
418 Exception caughtException = null;
419 try {
420 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
421 TrustAgentService.TRUST_AGENT_META_DATA);
422 if (parser == null) {
423 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
424 return null;
425 }
426 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
427 AttributeSet attrs = Xml.asAttributeSet(parser);
428 int type;
429 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
430 && type != XmlPullParser.START_TAG) {
431 // Drain preamble.
432 }
433 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200434 if (!"trust-agent".equals(nodeName)) {
435 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100436 return null;
437 }
438 TypedArray sa = res
439 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
440 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
441 sa.recycle();
442 } catch (PackageManager.NameNotFoundException e) {
443 caughtException = e;
444 } catch (IOException e) {
445 caughtException = e;
446 } catch (XmlPullParserException e) {
447 caughtException = e;
448 } finally {
449 if (parser != null) parser.close();
450 }
451 if (caughtException != null) {
452 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
453 return null;
454 }
455 if (cn == null) {
456 return null;
457 }
458 if (cn.indexOf('/') < 0) {
459 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
460 }
461 return ComponentName.unflattenFromString(cn);
462 }
463
464 private ComponentName getComponentName(ResolveInfo resolveInfo) {
465 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
466 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
467 }
468
Adrian Roos3870d452014-09-05 18:22:28 +0200469 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
470 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
471 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
472 return;
473 }
474 PackageManager pm = mContext.getPackageManager();
475 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
476 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
477 for (ResolveInfo resolveInfo : resolveInfos) {
478 ComponentName componentName = getComponentName(resolveInfo);
479 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
480 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
481 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
482 + "is not a system package.");
483 continue;
484 }
485 discoveredAgents.add(componentName);
486 }
487
488 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
489 if (previouslyEnabledAgents != null) {
490 discoveredAgents.addAll(previouslyEnabledAgents);
491 }
492 utils.setEnabledTrustAgents(discoveredAgents, userId);
493 Settings.Secure.putIntForUser(mContext.getContentResolver(),
494 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
495 }
496
497 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
498 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
499 0 /* flags */, userId);
500 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
501 for (ResolveInfo resolveInfo : resolveInfos) {
502 if (resolveInfo.serviceInfo == null) continue;
503 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
504 String packageName = resolveInfo.serviceInfo.packageName;
505 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
506 != PackageManager.PERMISSION_GRANTED) {
507 ComponentName name = getComponentName(resolveInfo);
508 Log.w(TAG, "Skipping agent " + name + " because package does not have"
509 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
510 continue;
511 }
512 allowedAgents.add(resolveInfo);
513 }
514 return allowedAgents;
515 }
516
Adrian Roos82142c22014-03-27 14:56:59 +0100517 // Agent dispatch and aggregation
518
519 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700520 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200521 return false;
522 }
Adrian Roos82142c22014-03-27 14:56:59 +0100523 for (int i = 0; i < mActiveAgents.size(); i++) {
524 AgentInfo info = mActiveAgents.valueAt(i);
525 if (info.userId == userId) {
526 if (info.agent.isTrusted()) {
527 return true;
528 }
529 }
530 }
531 return false;
532 }
533
Adrian Roos7861c662014-07-25 15:37:28 +0200534 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700535 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200536 return false;
537 }
538 for (int i = 0; i < mActiveAgents.size(); i++) {
539 AgentInfo info = mActiveAgents.valueAt(i);
540 if (info.userId == userId) {
541 if (info.agent.isManagingTrust()) {
542 return true;
543 }
544 }
545 }
546 return false;
547 }
548
Adrian Roos82142c22014-03-27 14:56:59 +0100549 private void dispatchUnlockAttempt(boolean successful, int userId) {
550 for (int i = 0; i < mActiveAgents.size(); i++) {
551 AgentInfo info = mActiveAgents.valueAt(i);
552 if (info.userId == userId) {
553 info.agent.onUnlockAttempt(successful);
554 }
555 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200556 }
557
Adrian Roos82142c22014-03-27 14:56:59 +0100558 // Listeners
559
560 private void addListener(ITrustListener listener) {
561 for (int i = 0; i < mTrustListeners.size(); i++) {
562 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
563 return;
564 }
565 }
566 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200567 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100568 }
569
570 private void removeListener(ITrustListener listener) {
571 for (int i = 0; i < mTrustListeners.size(); i++) {
572 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700573 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100574 return;
575 }
576 }
577 }
578
Adrian Roos94e15a52015-04-16 12:23:18 -0700579 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
580 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100581 for (int i = 0; i < mTrustListeners.size(); i++) {
582 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700583 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200584 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200585 Slog.d(TAG, "Removing dead TrustListener.");
586 mTrustListeners.remove(i);
587 i--;
588 } catch (RemoteException e) {
589 Slog.e(TAG, "Exception while notifying TrustListener.", e);
590 }
591 }
592 }
593
594 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
595 for (int i = 0; i < mTrustListeners.size(); i++) {
596 try {
597 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
598 } catch (DeadObjectException e) {
599 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200600 mTrustListeners.remove(i);
601 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100602 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200603 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100604 }
605 }
606 }
607
Adrian Rooscbe614f2014-10-28 20:16:12 +0100608 // User lifecycle
609
610 @Override
611 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100612 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100613 }
614
615 @Override
616 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100617 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
618 }
619
620 @Override
621 public void onSwitchUser(int userId) {
622 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100623 }
624
Adrian Roos82142c22014-03-27 14:56:59 +0100625 // Plumbing
626
627 private final IBinder mService = new ITrustManager.Stub() {
628 @Override
629 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
630 enforceReportPermission();
631 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
632 .sendToTarget();
633 }
634
635 @Override
636 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
637 enforceReportPermission();
638 // coalesce refresh messages.
639 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
640 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
641 }
642
643 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100644 public void reportKeyguardShowingChanged() throws RemoteException {
645 enforceReportPermission();
646 // coalesce refresh messages.
647 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
648 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
649 }
650
651 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100652 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
653 enforceListenerPermission();
654 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
655 }
656
657 @Override
658 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
659 enforceListenerPermission();
660 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
661 }
662
Adrian Roosbcd07652014-10-22 16:57:16 +0200663 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100664 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200665 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100666 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Clara Bayarria1771112015-12-18 16:29:18 +0000667 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarri56878a92015-10-29 15:43:55 +0000668 userId = resolveProfileParent(userId);
669 }
Adrian Roos50bfeec2014-11-20 16:21:11 +0100670
Adrian Roos481a6df2014-11-20 19:48:56 +0100671 return isDeviceLockedInner(userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200672 }
673
Adrian Roos82893682015-04-02 16:17:46 +0200674 @Override
675 public boolean isDeviceSecure(int userId) throws RemoteException {
676 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
677 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Clara Bayarria1771112015-12-18 16:29:18 +0000678 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
Clara Bayarrib3987bd2015-11-18 16:39:34 -0800679 userId = resolveProfileParent(userId);
680 }
Adrian Roos82893682015-04-02 16:17:46 +0200681
682 long token = Binder.clearCallingIdentity();
683 try {
Clara Bayarria1771112015-12-18 16:29:18 +0000684 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200685 } finally {
686 Binder.restoreCallingIdentity(token);
687 }
688 }
689
Adrian Roos82142c22014-03-27 14:56:59 +0100690 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200691 mContext.enforceCallingOrSelfPermission(
692 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100693 }
694
695 private void enforceListenerPermission() {
696 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
697 "register trust listener");
698 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200699
700 @Override
701 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
702 mContext.enforceCallingPermission(Manifest.permission.DUMP,
703 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200704 if (isSafeMode()) {
705 fout.println("disabled because the system is in safe mode.");
706 return;
707 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100708 if (!mTrustAgentsCanRun) {
709 fout.println("disabled because the third-party apps can't run yet.");
710 return;
711 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200712 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200713 mHandler.runWithScissors(new Runnable() {
714 @Override
715 public void run() {
716 fout.println("Trust manager state:");
717 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100718 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200719 }
720 }
721 }, 1500);
722 }
723
724 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
725 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
726 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700727 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100728 fout.println("(managed profile)");
729 fout.println(" disabled because switching to this user is not possible.");
730 return;
731 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200732 if (isCurrent) {
733 fout.print(" (current)");
734 }
735 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200736 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100737 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -0700738 fout.print(", strongAuthRequired=" + dumpHex(
739 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200740 fout.println();
741 fout.println(" Enabled agents:");
742 boolean duplicateSimpleNames = false;
743 ArraySet<String> simpleNames = new ArraySet<String>();
744 for (AgentInfo info : mActiveAgents) {
745 if (info.userId != user.id) { continue; }
746 boolean trusted = info.agent.isTrusted();
747 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200748 fout.print(" bound=" + dumpBool(info.agent.isBound()));
749 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200750 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
751 fout.print(", trusted=" + dumpBool(trusted));
752 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200753 if (trusted) {
754 fout.println(" message=\"" + info.agent.getMessage() + "\"");
755 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200756 if (!info.agent.isConnected()) {
757 String restartTime = TrustArchive.formatDuration(
758 info.agent.getScheduledRestartUptimeMillis()
759 - SystemClock.uptimeMillis());
760 fout.println(" restartScheduledAt=" + restartTime);
761 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200762 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
763 duplicateSimpleNames = true;
764 }
765 }
766 fout.println(" Events:");
767 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
768 fout.println();
769 }
770
771 private String dumpBool(boolean b) {
772 return b ? "1" : "0";
773 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700774
775 private String dumpHex(int i) {
776 return "0x" + Integer.toHexString(i);
777 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000778
779 @Override
780 public void setDeviceLockedForUser(int userId, boolean value) {
781 mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
782 .sendToTarget();
783 }
Adrian Roos82142c22014-03-27 14:56:59 +0100784 };
785
Adrian Roosbcd07652014-10-22 16:57:16 +0200786 private int resolveProfileParent(int userId) {
787 long identity = Binder.clearCallingIdentity();
788 try {
789 UserInfo parent = mUserManager.getProfileParent(userId);
790 if (parent != null) {
791 return parent.getUserHandle().getIdentifier();
792 }
793 return userId;
794 } finally {
795 Binder.restoreCallingIdentity(identity);
796 }
797 }
798
Adrian Roos82142c22014-03-27 14:56:59 +0100799 private final Handler mHandler = new Handler() {
800 @Override
801 public void handleMessage(Message msg) {
802 switch (msg.what) {
803 case MSG_REGISTER_LISTENER:
804 addListener((ITrustListener) msg.obj);
805 break;
806 case MSG_UNREGISTER_LISTENER:
807 removeListener((ITrustListener) msg.obj);
808 break;
809 case MSG_DISPATCH_UNLOCK_ATTEMPT:
810 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
811 break;
812 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700813 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100814 // This is also called when the security mode of a user changes.
815 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100816 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100817 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100818 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100819 break;
820 case MSG_START_USER:
821 case MSG_CLEANUP_USER:
822 refreshAgentList(msg.arg1);
823 break;
824 case MSG_SWITCH_USER:
825 mCurrentUser = msg.arg1;
826 refreshDeviceLockedForUser(UserHandle.USER_ALL);
827 break;
Clara Bayarri56878a92015-10-29 15:43:55 +0000828 case MSG_SET_DEVICE_LOCKED:
829 setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
830 break;
Adrian Roos82142c22014-03-27 14:56:59 +0100831 }
832 }
833 };
834
835 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
836 @Override
837 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700838 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100839 }
840
841 @Override
842 public boolean onPackageChanged(String packageName, int uid, String[] components) {
843 // We're interested in all changes, even if just some components get enabled / disabled.
844 return true;
845 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200846
847 @Override
848 public void onPackageDisappeared(String packageName, int reason) {
849 removeAgentsOfPackage(packageName);
850 }
Adrian Roos82142c22014-03-27 14:56:59 +0100851 };
Adrian Roosca36b952014-05-16 18:52:29 +0200852
Adrian Roosb5e47222015-08-14 15:53:06 -0700853 private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker() {
854 @Override
855 public void onStrongAuthRequiredChanged(int userId) {
856 refreshAgentList(userId);
857 }
858 };
859
Adrian Roos9dbe1902014-08-13 18:25:52 +0200860 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200861
862 @Override
863 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200864 String action = intent.getAction();
865 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700866 refreshAgentList(getSendingUserId());
867 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200868 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100869 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200870 if (userId > 0) {
871 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200872 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100873 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
874 int userId = getUserId(intent);
875 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100876 synchronized (mUserIsTrusted) {
877 mUserIsTrusted.delete(userId);
878 }
879 synchronized (mDeviceLockedForUser) {
880 mDeviceLockedForUser.delete(userId);
881 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100882 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100883 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100884 }
885 }
886 }
887
888 private int getUserId(Intent intent) {
889 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
890 if (userId > 0) {
891 return userId;
892 } else {
893 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
894 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200895 }
896 }
897
898 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200899 IntentFilter filter = new IntentFilter();
900 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
901 filter.addAction(Intent.ACTION_USER_PRESENT);
Adrian Roos3870d452014-09-05 18:22:28 +0200902 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100903 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200904 context.registerReceiverAsUser(this,
905 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200906 filter,
Adrian Roosca36b952014-05-16 18:52:29 +0200907 null /* permission */,
908 null /* scheduler */);
909 }
910 }
Adrian Roos82142c22014-03-27 14:56:59 +0100911}