blob: b9e8851d53f13cc98dbf55f76b4f444a3870a310 [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 Roos53a6b062015-06-29 17:49:17 -0700108 private final SparseBooleanArray mUserHasAuthenticated = 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 Roos53a6b062015-06-29 17:49:17 -0700121 @GuardedBy("mUserHasAuthenticatedSinceBoot")
122 private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
123
Adrian Rooscbe614f2014-10-28 20:16:12 +0100124 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700125 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100126
Adrian Roos82142c22014-03-27 14:56:59 +0100127 public TrustManagerService(Context context) {
128 super(context);
129 mContext = context;
130 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100131 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200132 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100133 }
134
135 @Override
136 public void onStart() {
137 publishBinderService(Context.TRUST_SERVICE, mService);
138 }
139
140 @Override
141 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200142 if (isSafeMode()) {
143 // No trust agents in safe mode.
144 return;
145 }
146 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100147 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200148 mReceiver.register(mContext);
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;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700233 if (!getUserHasAuthenticated(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
Adrian Roos481a6df2014-11-20 19:48:56 +0100292 boolean isDeviceLockedInner(int userId) {
293 synchronized (mDeviceLockedForUser) {
294 return mDeviceLockedForUser.get(userId, true);
295 }
296 }
297
298 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700299 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100300 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100301 + " must be USER_ALL or a specific user.", new Throwable("here"));
302 userId = UserHandle.USER_ALL;
303 }
304
305 List<UserInfo> userInfos;
306 if (userId == UserHandle.USER_ALL) {
307 userInfos = mUserManager.getUsers(true /* excludeDying */);
308 } else {
309 userInfos = new ArrayList<>();
310 userInfos.add(mUserManager.getUserInfo(userId));
311 }
312
313 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
314
315 for (int i = 0; i < userInfos.size(); i++) {
316 UserInfo info = userInfos.get(i);
317
318 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700319 || !info.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100320 continue;
321 }
322
323 int id = info.id;
324 boolean secure = mLockPatternUtils.isSecure(id);
325 boolean trusted = aggregateIsTrusted(id);
326 boolean showingKeyguard = true;
327 if (mCurrentUser == id) {
328 try {
329 showingKeyguard = wm.isKeyguardLocked();
330 } catch (RemoteException e) {
331 }
332 }
333 boolean deviceLocked = secure && showingKeyguard && !trusted;
334
335 boolean changed;
336 synchronized (mDeviceLockedForUser) {
337 changed = isDeviceLockedInner(id) != deviceLocked;
338 mDeviceLockedForUser.put(id, deviceLocked);
339 }
340 if (changed) {
341 dispatchDeviceLocked(id, deviceLocked);
342 }
343 }
344 }
345
346 private void dispatchDeviceLocked(int userId, boolean isLocked) {
347 for (int i = 0; i < mActiveAgents.size(); i++) {
348 AgentInfo agent = mActiveAgents.valueAt(i);
349 if (agent.userId == userId) {
350 if (isLocked) {
351 agent.agent.onDeviceLocked();
352 } else{
353 agent.agent.onDeviceUnlocked();
354 }
355 }
356 }
357 }
358
Marco Fucci4e68f112014-08-29 12:31:48 -0700359 void updateDevicePolicyFeatures() {
Adrian Roos8f211582014-07-29 15:09:57 +0200360 for (int i = 0; i < mActiveAgents.size(); i++) {
361 AgentInfo info = mActiveAgents.valueAt(i);
362 if (info.agent.isConnected()) {
363 info.agent.updateDevicePolicyFeatures();
364 }
365 }
366 }
367
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200368 private void removeAgentsOfPackage(String packageName) {
369 boolean trustMayHaveChanged = false;
370 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
371 AgentInfo info = mActiveAgents.valueAt(i);
372 if (packageName.equals(info.component.getPackageName())) {
373 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200374 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200375 trustMayHaveChanged = true;
376 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100377 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200378 mActiveAgents.removeAt(i);
379 }
380 }
381 if (trustMayHaveChanged) {
382 updateTrustAll();
383 }
384 }
385
386 public void resetAgent(ComponentName name, int userId) {
387 boolean trustMayHaveChanged = false;
388 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
389 AgentInfo info = mActiveAgents.valueAt(i);
390 if (name.equals(info.component) && userId == info.userId) {
391 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200392 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200393 trustMayHaveChanged = true;
394 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100395 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200396 mActiveAgents.removeAt(i);
397 }
398 }
399 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700400 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200401 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700402 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200403 }
404
Adrian Roos82142c22014-03-27 14:56:59 +0100405 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
406 if (resolveInfo == null || resolveInfo.serviceInfo == null
407 || resolveInfo.serviceInfo.metaData == null) return null;
408 String cn = null;
409 XmlResourceParser parser = null;
410 Exception caughtException = null;
411 try {
412 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
413 TrustAgentService.TRUST_AGENT_META_DATA);
414 if (parser == null) {
415 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
416 return null;
417 }
418 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
419 AttributeSet attrs = Xml.asAttributeSet(parser);
420 int type;
421 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
422 && type != XmlPullParser.START_TAG) {
423 // Drain preamble.
424 }
425 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200426 if (!"trust-agent".equals(nodeName)) {
427 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100428 return null;
429 }
430 TypedArray sa = res
431 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
432 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
433 sa.recycle();
434 } catch (PackageManager.NameNotFoundException e) {
435 caughtException = e;
436 } catch (IOException e) {
437 caughtException = e;
438 } catch (XmlPullParserException e) {
439 caughtException = e;
440 } finally {
441 if (parser != null) parser.close();
442 }
443 if (caughtException != null) {
444 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
445 return null;
446 }
447 if (cn == null) {
448 return null;
449 }
450 if (cn.indexOf('/') < 0) {
451 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
452 }
453 return ComponentName.unflattenFromString(cn);
454 }
455
456 private ComponentName getComponentName(ResolveInfo resolveInfo) {
457 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
458 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
459 }
460
Adrian Roos3870d452014-09-05 18:22:28 +0200461 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
462 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
463 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
464 return;
465 }
466 PackageManager pm = mContext.getPackageManager();
467 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
468 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
469 for (ResolveInfo resolveInfo : resolveInfos) {
470 ComponentName componentName = getComponentName(resolveInfo);
471 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
472 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
473 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
474 + "is not a system package.");
475 continue;
476 }
477 discoveredAgents.add(componentName);
478 }
479
480 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
481 if (previouslyEnabledAgents != null) {
482 discoveredAgents.addAll(previouslyEnabledAgents);
483 }
484 utils.setEnabledTrustAgents(discoveredAgents, userId);
485 Settings.Secure.putIntForUser(mContext.getContentResolver(),
486 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
487 }
488
489 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
490 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
491 0 /* flags */, userId);
492 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
493 for (ResolveInfo resolveInfo : resolveInfos) {
494 if (resolveInfo.serviceInfo == null) continue;
495 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
496 String packageName = resolveInfo.serviceInfo.packageName;
497 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
498 != PackageManager.PERMISSION_GRANTED) {
499 ComponentName name = getComponentName(resolveInfo);
500 Log.w(TAG, "Skipping agent " + name + " because package does not have"
501 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
502 continue;
503 }
504 allowedAgents.add(resolveInfo);
505 }
506 return allowedAgents;
507 }
508
Adrian Roos82142c22014-03-27 14:56:59 +0100509 // Agent dispatch and aggregation
510
511 private boolean aggregateIsTrusted(int userId) {
Jorim Jaggi237b0612015-05-01 14:28:49 -0700512 if (!getUserHasAuthenticated(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200513 return false;
514 }
Adrian Roos82142c22014-03-27 14:56:59 +0100515 for (int i = 0; i < mActiveAgents.size(); i++) {
516 AgentInfo info = mActiveAgents.valueAt(i);
517 if (info.userId == userId) {
518 if (info.agent.isTrusted()) {
519 return true;
520 }
521 }
522 }
523 return false;
524 }
525
Adrian Roos7861c662014-07-25 15:37:28 +0200526 private boolean aggregateIsTrustManaged(int userId) {
Jorim Jaggi237b0612015-05-01 14:28:49 -0700527 if (!getUserHasAuthenticated(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200528 return false;
529 }
530 for (int i = 0; i < mActiveAgents.size(); i++) {
531 AgentInfo info = mActiveAgents.valueAt(i);
532 if (info.userId == userId) {
533 if (info.agent.isManagingTrust()) {
534 return true;
535 }
536 }
537 }
538 return false;
539 }
540
Adrian Roos82142c22014-03-27 14:56:59 +0100541 private void dispatchUnlockAttempt(boolean successful, int userId) {
542 for (int i = 0; i < mActiveAgents.size(); i++) {
543 AgentInfo info = mActiveAgents.valueAt(i);
544 if (info.userId == userId) {
545 info.agent.onUnlockAttempt(successful);
546 }
547 }
Adrian Roos7046bfd2014-05-16 21:20:54 +0200548
Adrian Roos9dbe1902014-08-13 18:25:52 +0200549 if (successful) {
550 updateUserHasAuthenticated(userId);
551 }
552 }
553
554 private void updateUserHasAuthenticated(int userId) {
Jorim Jaggi237b0612015-05-01 14:28:49 -0700555 boolean changed = setUserHasAuthenticated(userId);
556 if (changed) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700557 refreshAgentList(userId);
Adrian Roos7046bfd2014-05-16 21:20:54 +0200558 }
Adrian Roos82142c22014-03-27 14:56:59 +0100559 }
560
Jorim Jaggi237b0612015-05-01 14:28:49 -0700561 private boolean getUserHasAuthenticated(int userId) {
Adrian Roos53a6b062015-06-29 17:49:17 -0700562 return mUserHasAuthenticated.get(userId);
Jorim Jaggi237b0612015-05-01 14:28:49 -0700563 }
564
565 /**
566 * @return whether the value has changed
567 */
568 private boolean setUserHasAuthenticated(int userId) {
Adrian Roos53a6b062015-06-29 17:49:17 -0700569 if (!mUserHasAuthenticated.get(userId)) {
570 mUserHasAuthenticated.put(userId, true);
571 synchronized (mUserHasAuthenticatedSinceBoot) {
Jorim Jaggi237b0612015-05-01 14:28:49 -0700572 mUserHasAuthenticatedSinceBoot.put(userId, true);
Jorim Jaggi237b0612015-05-01 14:28:49 -0700573 }
Adrian Roos53a6b062015-06-29 17:49:17 -0700574 return true;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700575 }
Adrian Roos53a6b062015-06-29 17:49:17 -0700576 return false;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700577 }
578
579 private void clearUserHasAuthenticated(int userId) {
Adrian Roos53a6b062015-06-29 17:49:17 -0700580 if (userId == UserHandle.USER_ALL) {
581 mUserHasAuthenticated.clear();
582 } else {
583 mUserHasAuthenticated.put(userId, false);
584 }
585 }
586
587 private boolean getUserHasAuthenticatedSinceBoot(int userId) {
Jorim Jaggi237b0612015-05-01 14:28:49 -0700588 synchronized (mUserHasAuthenticatedSinceBoot) {
Adrian Roos53a6b062015-06-29 17:49:17 -0700589 return mUserHasAuthenticatedSinceBoot.get(userId);
Jorim Jaggi237b0612015-05-01 14:28:49 -0700590 }
591 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200592
593 private void requireCredentialEntry(int userId) {
Jorim Jaggi237b0612015-05-01 14:28:49 -0700594 clearUserHasAuthenticated(userId);
595 refreshAgentList(userId);
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200596 }
597
Adrian Roos82142c22014-03-27 14:56:59 +0100598 // Listeners
599
600 private void addListener(ITrustListener listener) {
601 for (int i = 0; i < mTrustListeners.size(); i++) {
602 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
603 return;
604 }
605 }
606 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200607 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100608 }
609
610 private void removeListener(ITrustListener listener) {
611 for (int i = 0; i < mTrustListeners.size(); i++) {
612 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700613 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100614 return;
615 }
616 }
617 }
618
Adrian Roos94e15a52015-04-16 12:23:18 -0700619 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
620 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100621 for (int i = 0; i < mTrustListeners.size(); i++) {
622 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700623 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200624 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200625 Slog.d(TAG, "Removing dead TrustListener.");
626 mTrustListeners.remove(i);
627 i--;
628 } catch (RemoteException e) {
629 Slog.e(TAG, "Exception while notifying TrustListener.", e);
630 }
631 }
632 }
633
634 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
635 for (int i = 0; i < mTrustListeners.size(); i++) {
636 try {
637 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
638 } catch (DeadObjectException e) {
639 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200640 mTrustListeners.remove(i);
641 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100642 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200643 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100644 }
645 }
646 }
647
Adrian Rooscbe614f2014-10-28 20:16:12 +0100648 // User lifecycle
649
650 @Override
651 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100652 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100653 }
654
655 @Override
656 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100657 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
658 }
659
660 @Override
661 public void onSwitchUser(int userId) {
662 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100663 }
664
Adrian Roos82142c22014-03-27 14:56:59 +0100665 // Plumbing
666
667 private final IBinder mService = new ITrustManager.Stub() {
668 @Override
669 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
670 enforceReportPermission();
671 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
672 .sendToTarget();
673 }
674
675 @Override
676 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
677 enforceReportPermission();
678 // coalesce refresh messages.
679 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
680 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
681 }
682
683 @Override
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200684 public void reportRequireCredentialEntry(int userId) throws RemoteException {
685 enforceReportPermission();
Xiaohui Chen09e02912015-08-05 09:44:56 -0700686 if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200687 mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget();
688 } else {
689 throw new IllegalArgumentException(
690 "userId must be an explicit user id or USER_ALL");
691 }
692 }
693
694 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100695 public void reportKeyguardShowingChanged() throws RemoteException {
696 enforceReportPermission();
697 // coalesce refresh messages.
698 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
699 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
700 }
701
702 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100703 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
704 enforceListenerPermission();
705 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
706 }
707
708 @Override
709 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
710 enforceListenerPermission();
711 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
712 }
713
Adrian Roosbcd07652014-10-22 16:57:16 +0200714 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100715 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200716 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100717 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roosbcd07652014-10-22 16:57:16 +0200718 userId = resolveProfileParent(userId);
Adrian Roos50bfeec2014-11-20 16:21:11 +0100719
Adrian Roos481a6df2014-11-20 19:48:56 +0100720 return isDeviceLockedInner(userId);
Adrian Roosbcd07652014-10-22 16:57:16 +0200721 }
722
Adrian Roos82893682015-04-02 16:17:46 +0200723 @Override
724 public boolean isDeviceSecure(int userId) throws RemoteException {
725 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
726 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
727 userId = resolveProfileParent(userId);
728
729 long token = Binder.clearCallingIdentity();
730 try {
731 return new LockPatternUtils(mContext).isSecure(userId);
732 } finally {
733 Binder.restoreCallingIdentity(token);
734 }
735 }
736
Jorim Jaggi237b0612015-05-01 14:28:49 -0700737 @Override
738 public boolean hasUserAuthenticatedSinceBoot(int userId) throws RemoteException {
739 mContext.enforceCallingOrSelfPermission(
740 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, null);
741 long token = Binder.clearCallingIdentity();
742 try {
Adrian Roos53a6b062015-06-29 17:49:17 -0700743 return getUserHasAuthenticatedSinceBoot(userId);
Jorim Jaggi237b0612015-05-01 14:28:49 -0700744 } finally {
745 Binder.restoreCallingIdentity(token);
746 }
747 }
748
Adrian Roos82142c22014-03-27 14:56:59 +0100749 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200750 mContext.enforceCallingOrSelfPermission(
751 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100752 }
753
754 private void enforceListenerPermission() {
755 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
756 "register trust listener");
757 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200758
759 @Override
760 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
761 mContext.enforceCallingPermission(Manifest.permission.DUMP,
762 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200763 if (isSafeMode()) {
764 fout.println("disabled because the system is in safe mode.");
765 return;
766 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100767 if (!mTrustAgentsCanRun) {
768 fout.println("disabled because the third-party apps can't run yet.");
769 return;
770 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200771 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200772 mHandler.runWithScissors(new Runnable() {
773 @Override
774 public void run() {
775 fout.println("Trust manager state:");
776 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100777 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200778 }
779 }
780 }, 1500);
781 }
782
783 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
784 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
785 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700786 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100787 fout.println("(managed profile)");
788 fout.println(" disabled because switching to this user is not possible.");
789 return;
790 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200791 if (isCurrent) {
792 fout.print(" (current)");
793 }
794 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200795 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100796 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roos53a6b062015-06-29 17:49:17 -0700797 fout.print(", hasAuthenticated=" + dumpBool(getUserHasAuthenticated(user.id)));
798 fout.print(", hasAuthenticatedSinceBoot="
799 + dumpBool(getUserHasAuthenticatedSinceBoot(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200800 fout.println();
801 fout.println(" Enabled agents:");
802 boolean duplicateSimpleNames = false;
803 ArraySet<String> simpleNames = new ArraySet<String>();
804 for (AgentInfo info : mActiveAgents) {
805 if (info.userId != user.id) { continue; }
806 boolean trusted = info.agent.isTrusted();
807 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200808 fout.print(" bound=" + dumpBool(info.agent.isBound()));
809 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200810 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
811 fout.print(", trusted=" + dumpBool(trusted));
812 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200813 if (trusted) {
814 fout.println(" message=\"" + info.agent.getMessage() + "\"");
815 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200816 if (!info.agent.isConnected()) {
817 String restartTime = TrustArchive.formatDuration(
818 info.agent.getScheduledRestartUptimeMillis()
819 - SystemClock.uptimeMillis());
820 fout.println(" restartScheduledAt=" + restartTime);
821 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200822 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
823 duplicateSimpleNames = true;
824 }
825 }
826 fout.println(" Events:");
827 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
828 fout.println();
829 }
830
831 private String dumpBool(boolean b) {
832 return b ? "1" : "0";
833 }
Adrian Roos82142c22014-03-27 14:56:59 +0100834 };
835
Adrian Roosbcd07652014-10-22 16:57:16 +0200836 private int resolveProfileParent(int userId) {
837 long identity = Binder.clearCallingIdentity();
838 try {
839 UserInfo parent = mUserManager.getProfileParent(userId);
840 if (parent != null) {
841 return parent.getUserHandle().getIdentifier();
842 }
843 return userId;
844 } finally {
845 Binder.restoreCallingIdentity(identity);
846 }
847 }
848
Adrian Roos82142c22014-03-27 14:56:59 +0100849 private final Handler mHandler = new Handler() {
850 @Override
851 public void handleMessage(Message msg) {
852 switch (msg.what) {
853 case MSG_REGISTER_LISTENER:
854 addListener((ITrustListener) msg.obj);
855 break;
856 case MSG_UNREGISTER_LISTENER:
857 removeListener((ITrustListener) msg.obj);
858 break;
859 case MSG_DISPATCH_UNLOCK_ATTEMPT:
860 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
861 break;
862 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700863 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100864 // This is also called when the security mode of a user changes.
865 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100866 break;
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200867 case MSG_REQUIRE_CREDENTIAL_ENTRY:
868 requireCredentialEntry(msg.arg1);
869 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100870 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100871 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100872 break;
873 case MSG_START_USER:
874 case MSG_CLEANUP_USER:
875 refreshAgentList(msg.arg1);
876 break;
877 case MSG_SWITCH_USER:
878 mCurrentUser = msg.arg1;
879 refreshDeviceLockedForUser(UserHandle.USER_ALL);
880 break;
Adrian Roos82142c22014-03-27 14:56:59 +0100881 }
882 }
883 };
884
885 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
886 @Override
887 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700888 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100889 }
890
891 @Override
892 public boolean onPackageChanged(String packageName, int uid, String[] components) {
893 // We're interested in all changes, even if just some components get enabled / disabled.
894 return true;
895 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200896
897 @Override
898 public void onPackageDisappeared(String packageName, int reason) {
899 removeAgentsOfPackage(packageName);
900 }
Adrian Roos82142c22014-03-27 14:56:59 +0100901 };
Adrian Roosca36b952014-05-16 18:52:29 +0200902
Adrian Roos9dbe1902014-08-13 18:25:52 +0200903 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200904
905 @Override
906 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200907 String action = intent.getAction();
908 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700909 refreshAgentList(getSendingUserId());
910 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200911 } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200912 updateUserHasAuthenticated(getSendingUserId());
Adrian Roos3870d452014-09-05 18:22:28 +0200913 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100914 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200915 if (userId > 0) {
916 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200917 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100918 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
919 int userId = getUserId(intent);
920 if (userId > 0) {
Adrian Roos53a6b062015-06-29 17:49:17 -0700921 mUserHasAuthenticated.delete(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100922 synchronized (mUserIsTrusted) {
923 mUserIsTrusted.delete(userId);
924 }
925 synchronized (mDeviceLockedForUser) {
926 mDeviceLockedForUser.delete(userId);
927 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100928 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100929 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100930 }
931 }
932 }
933
934 private int getUserId(Intent intent) {
935 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
936 if (userId > 0) {
937 return userId;
938 } else {
939 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
940 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200941 }
942 }
943
944 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200945 IntentFilter filter = new IntentFilter();
946 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
947 filter.addAction(Intent.ACTION_USER_PRESENT);
Adrian Roos3870d452014-09-05 18:22:28 +0200948 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100949 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200950 context.registerReceiverAsUser(this,
951 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200952 filter,
Adrian Roosca36b952014-05-16 18:52:29 +0200953 null /* permission */,
954 null /* scheduler */);
955 }
956 }
Adrian Roos82142c22014-03-27 14:56:59 +0100957}