blob: 3452f41eb5873297563a626916c4fad678bf7b24 [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 Roos82142c22014-03-27 14:56:59 +010063import android.util.Xml;
Adrian Roos481a6df2014-11-20 19:48:56 +010064import android.view.IWindowManager;
Adrian Roos50bfeec2014-11-20 16:21:11 +010065import android.view.WindowManagerGlobal;
Adrian Roos82142c22014-03-27 14:56:59 +010066
Adrian Roos7a4f3d42014-05-02 12:12:20 +020067import java.io.FileDescriptor;
Adrian Roos82142c22014-03-27 14:56:59 +010068import java.io.IOException;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020069import java.io.PrintWriter;
Adrian Roos82142c22014-03-27 14:56:59 +010070import java.util.ArrayList;
71import java.util.List;
72
73/**
74 * Manages trust agents and trust listeners.
75 *
76 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
77 * of each user and notifies them about events that are relevant to them.
78 * It start and stops them based on the value of
79 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
80 *
81 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
82 * trust state changes for any user.
83 *
84 * Trust state and the setting of enabled agents is kept per user and each user has its own
85 * instance of a {@link android.service.trust.TrustAgentService}.
86 */
87public class TrustManagerService extends SystemService {
88
89 private static final boolean DEBUG = false;
90 private static final String TAG = "TrustManagerService";
91
92 private static final Intent TRUST_AGENT_INTENT =
93 new Intent(TrustAgentService.SERVICE_INTERFACE);
Adrian Roos18ea8932014-05-28 14:53:06 +020094 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
Adrian Roos82142c22014-03-27 14:56:59 +010095
96 private static final int MSG_REGISTER_LISTENER = 1;
97 private static final int MSG_UNREGISTER_LISTENER = 2;
98 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
99 private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
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;
Clara Bayarri56878a92015-10-29 15:43:55 +0000104 private static final int MSG_SET_DEVICE_LOCKED = 10;
Adrian Roosc13723f2016-01-12 20:29:03 +0100105 private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 11;
106
107 public static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
Adrian Roos82142c22014-03-27 14:56:59 +0100108
Adrian Roosb5e47222015-08-14 15:53:06 -0700109 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
110 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
Adrian Roos9dbe1902014-08-13 18:25:52 +0200111 private final Receiver mReceiver = new Receiver();
Adrian Roosb5e47222015-08-14 15:53:06 -0700112
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200113 /* package */ final TrustArchive mArchive = new TrustArchive();
Adrian Roos82142c22014-03-27 14:56:59 +0100114 private final Context mContext;
Adrian Roos3870d452014-09-05 18:22:28 +0200115 private final LockPatternUtils mLockPatternUtils;
Adrian Roosbcd07652014-10-22 16:57:16 +0200116 private final UserManager mUserManager;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100117 private final ActivityManager mActivityManager;
Adrian Roos82142c22014-03-27 14:56:59 +0100118
Adrian Roosbcd07652014-10-22 16:57:16 +0200119 @GuardedBy("mUserIsTrusted")
120 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
Adrian Roos82142c22014-03-27 14:56:59 +0100121
Adrian Roos481a6df2014-11-20 19:48:56 +0100122 @GuardedBy("mDeviceLockedForUser")
123 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
124
Adrian Roosc13723f2016-01-12 20:29:03 +0100125 @GuardedBy("mDeviceLockedForUser")
126 private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
127
Adrian Rooscbe614f2014-10-28 20:16:12 +0100128 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700129 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100130
Adrian Roos82142c22014-03-27 14:56:59 +0100131 public TrustManagerService(Context context) {
132 super(context);
133 mContext = context;
134 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100135 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200136 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100137 }
138
139 @Override
140 public void onStart() {
141 publishBinderService(Context.TRUST_SERVICE, mService);
142 }
143
144 @Override
145 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200146 if (isSafeMode()) {
147 // No trust agents in safe mode.
148 return;
149 }
150 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100151 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200152 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700153 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100154 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
155 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700156 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200157 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700158 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100159 }
160 }
161
162 // Agent management
163
164 private static final class AgentInfo {
165 CharSequence label;
166 Drawable icon;
167 ComponentName component; // service that implements ITrustAgent
168 ComponentName settings; // setting to launch to modify agent.
169 TrustAgentWrapper agent;
170 int userId;
171
172 @Override
173 public boolean equals(Object other) {
174 if (!(other instanceof AgentInfo)) {
175 return false;
176 }
177 AgentInfo o = (AgentInfo) other;
178 return component.equals(o.component) && userId == o.userId;
179 }
180
181 @Override
182 public int hashCode() {
183 return component.hashCode() * 31 + userId;
184 }
185 }
186
187 private void updateTrustAll() {
188 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
189 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700190 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100191 }
192 }
193
Adrian Roos94e15a52015-04-16 12:23:18 -0700194 public void updateTrust(int userId, int flags) {
Adrian Roosc13723f2016-01-12 20:29:03 +0100195 boolean managed = aggregateIsTrustManaged(userId);
196 dispatchOnTrustManagedChanged(managed, userId);
197 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
198 && isTrustUsuallyManagedInternal(userId) != managed) {
199 updateTrustUsuallyManaged(userId, managed);
200 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200201 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100202 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200203 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100204 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200205 mUserIsTrusted.put(userId, trusted);
206 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700207 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100208 if (changed) {
209 refreshDeviceLockedForUser(userId);
210 }
Adrian Roos82142c22014-03-27 14:56:59 +0100211 }
212
Adrian Roosc13723f2016-01-12 20:29:03 +0100213 private void updateTrustUsuallyManaged(int userId, boolean managed) {
214 synchronized (mTrustUsuallyManagedForUser) {
215 mTrustUsuallyManagedForUser.put(userId, managed);
216 }
217 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
218 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
219 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
220 mHandler.sendMessageDelayed(
221 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
222 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
223 }
224
Marco Fucci4e68f112014-08-29 12:31:48 -0700225 void refreshAgentList(int userId) {
Adrian Roos82142c22014-03-27 14:56:59 +0100226 if (DEBUG) Slog.d(TAG, "refreshAgentList()");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100227 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200228 return;
229 }
Xiaohui Chen09e02912015-08-05 09:44:56 -0700230 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roose681c272014-09-08 14:03:47 +0200231 Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
232 + " must be USER_ALL or a specific user.", new Throwable("here"));
233 userId = UserHandle.USER_ALL;
234 }
Adrian Roos82142c22014-03-27 14:56:59 +0100235 PackageManager pm = mContext.getPackageManager();
236
Marco Fucci4e68f112014-08-29 12:31:48 -0700237 List<UserInfo> userInfos;
238 if (userId == UserHandle.USER_ALL) {
239 userInfos = mUserManager.getUsers(true /* excludeDying */);
240 } else {
241 userInfos = new ArrayList<>();
242 userInfos.add(mUserManager.getUserInfo(userId));
243 }
Adrian Roos3870d452014-09-05 18:22:28 +0200244 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100245
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200246 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
247 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100248
249 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100250 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
251 || userInfo.guestToRemove) continue;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700252 if (!userInfo.supportsSwitchToByUser()) continue;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100253 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
Adrian Roos481a6df2014-11-20 19:48:56 +0100254 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
Adrian Roosb5e47222015-08-14 15:53:06 -0700255 if (!mStrongAuthTracker.isTrustAllowedForUser(userInfo.id)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200256 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
257 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700258 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200259 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
260
Adrian Roos82142c22014-03-27 14:56:59 +0100261 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200262 if (enabledAgents == null) {
Adrian Roos82142c22014-03-27 14:56:59 +0100263 continue;
264 }
Adrian Roos3870d452014-09-05 18:22:28 +0200265 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100266 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100267 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100268
Adrian Roos3870d452014-09-05 18:22:28 +0200269 if (!enabledAgents.contains(name)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200270 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700271 List<PersistableBundle> config =
272 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200273 // Disable agent if no features are enabled.
Jim Millere303bf42014-08-26 17:12:29 -0700274 if (config == null || config.isEmpty()) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200275 }
276
Adrian Roos82142c22014-03-27 14:56:59 +0100277 AgentInfo agentInfo = new AgentInfo();
278 agentInfo.component = name;
279 agentInfo.userId = userInfo.id;
280 if (!mActiveAgents.contains(agentInfo)) {
281 agentInfo.label = resolveInfo.loadLabel(pm);
282 agentInfo.icon = resolveInfo.loadIcon(pm);
283 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
284 agentInfo.agent = new TrustAgentWrapper(mContext, this,
285 new Intent().setComponent(name), userInfo.getUserHandle());
286 mActiveAgents.add(agentInfo);
287 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200288 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100289 }
290 }
291 }
292
293 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200294 for (int i = 0; i < obsoleteAgents.size(); i++) {
295 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roose681c272014-09-08 14:03:47 +0200296 if (userId == UserHandle.USER_ALL || userId == info.userId) {
297 if (info.agent.isManagingTrust()) {
298 trustMayHaveChanged = true;
299 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100300 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200301 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100302 }
Adrian Roos82142c22014-03-27 14:56:59 +0100303 }
304
305 if (trustMayHaveChanged) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100306 if (userId == UserHandle.USER_ALL) {
307 updateTrustAll();
308 } else {
Adrian Roos94e15a52015-04-16 12:23:18 -0700309 updateTrust(userId, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100310 }
Adrian Roos82142c22014-03-27 14:56:59 +0100311 }
312 }
313
Clara Bayarri56878a92015-10-29 15:43:55 +0000314 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarria1771112015-12-18 16:29:18 +0000315 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
316 synchronized (mDeviceLockedForUser) {
317 mDeviceLockedForUser.put(userId, locked);
Clara Bayarri56878a92015-10-29 15:43:55 +0000318 }
319 }
320 }
321
Adrian Roos481a6df2014-11-20 19:48:56 +0100322 boolean isDeviceLockedInner(int userId) {
323 synchronized (mDeviceLockedForUser) {
324 return mDeviceLockedForUser.get(userId, true);
325 }
326 }
327
328 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700329 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100330 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100331 + " must be USER_ALL or a specific user.", new Throwable("here"));
332 userId = UserHandle.USER_ALL;
333 }
334
335 List<UserInfo> userInfos;
336 if (userId == UserHandle.USER_ALL) {
337 userInfos = mUserManager.getUsers(true /* excludeDying */);
338 } else {
339 userInfos = new ArrayList<>();
340 userInfos.add(mUserManager.getUserInfo(userId));
341 }
342
343 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
344
345 for (int i = 0; i < userInfos.size(); i++) {
346 UserInfo info = userInfos.get(i);
347
348 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700349 || !info.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100350 continue;
351 }
352
353 int id = info.id;
354 boolean secure = mLockPatternUtils.isSecure(id);
355 boolean trusted = aggregateIsTrusted(id);
356 boolean showingKeyguard = true;
357 if (mCurrentUser == id) {
358 try {
359 showingKeyguard = wm.isKeyguardLocked();
360 } catch (RemoteException e) {
361 }
362 }
363 boolean deviceLocked = secure && showingKeyguard && !trusted;
364
365 boolean changed;
366 synchronized (mDeviceLockedForUser) {
367 changed = isDeviceLockedInner(id) != deviceLocked;
368 mDeviceLockedForUser.put(id, deviceLocked);
369 }
370 if (changed) {
371 dispatchDeviceLocked(id, deviceLocked);
372 }
373 }
374 }
375
376 private void dispatchDeviceLocked(int userId, boolean isLocked) {
377 for (int i = 0; i < mActiveAgents.size(); i++) {
378 AgentInfo agent = mActiveAgents.valueAt(i);
379 if (agent.userId == userId) {
380 if (isLocked) {
381 agent.agent.onDeviceLocked();
382 } else{
383 agent.agent.onDeviceUnlocked();
384 }
385 }
386 }
387 }
388
Marco Fucci4e68f112014-08-29 12:31:48 -0700389 void updateDevicePolicyFeatures() {
Adrian Roos8f211582014-07-29 15:09:57 +0200390 for (int i = 0; i < mActiveAgents.size(); i++) {
391 AgentInfo info = mActiveAgents.valueAt(i);
392 if (info.agent.isConnected()) {
393 info.agent.updateDevicePolicyFeatures();
394 }
395 }
396 }
397
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200398 private void removeAgentsOfPackage(String packageName) {
399 boolean trustMayHaveChanged = false;
400 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
401 AgentInfo info = mActiveAgents.valueAt(i);
402 if (packageName.equals(info.component.getPackageName())) {
403 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200404 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200405 trustMayHaveChanged = true;
406 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100407 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200408 mActiveAgents.removeAt(i);
409 }
410 }
411 if (trustMayHaveChanged) {
412 updateTrustAll();
413 }
414 }
415
416 public void resetAgent(ComponentName name, int userId) {
417 boolean trustMayHaveChanged = false;
418 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
419 AgentInfo info = mActiveAgents.valueAt(i);
420 if (name.equals(info.component) && userId == info.userId) {
421 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200422 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200423 trustMayHaveChanged = true;
424 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100425 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200426 mActiveAgents.removeAt(i);
427 }
428 }
429 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700430 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200431 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700432 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200433 }
434
Adrian Roos82142c22014-03-27 14:56:59 +0100435 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
436 if (resolveInfo == null || resolveInfo.serviceInfo == null
437 || resolveInfo.serviceInfo.metaData == null) return null;
438 String cn = null;
439 XmlResourceParser parser = null;
440 Exception caughtException = null;
441 try {
442 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
443 TrustAgentService.TRUST_AGENT_META_DATA);
444 if (parser == null) {
445 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
446 return null;
447 }
448 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
449 AttributeSet attrs = Xml.asAttributeSet(parser);
450 int type;
451 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
452 && type != XmlPullParser.START_TAG) {
453 // Drain preamble.
454 }
455 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200456 if (!"trust-agent".equals(nodeName)) {
457 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100458 return null;
459 }
460 TypedArray sa = res
461 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
462 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
463 sa.recycle();
464 } catch (PackageManager.NameNotFoundException e) {
465 caughtException = e;
466 } catch (IOException e) {
467 caughtException = e;
468 } catch (XmlPullParserException e) {
469 caughtException = e;
470 } finally {
471 if (parser != null) parser.close();
472 }
473 if (caughtException != null) {
474 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
475 return null;
476 }
477 if (cn == null) {
478 return null;
479 }
480 if (cn.indexOf('/') < 0) {
481 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
482 }
483 return ComponentName.unflattenFromString(cn);
484 }
485
486 private ComponentName getComponentName(ResolveInfo resolveInfo) {
487 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
488 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
489 }
490
Adrian Roos3870d452014-09-05 18:22:28 +0200491 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
492 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
493 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
494 return;
495 }
496 PackageManager pm = mContext.getPackageManager();
497 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
498 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
499 for (ResolveInfo resolveInfo : resolveInfos) {
500 ComponentName componentName = getComponentName(resolveInfo);
501 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
502 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
503 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
504 + "is not a system package.");
505 continue;
506 }
507 discoveredAgents.add(componentName);
508 }
509
510 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
511 if (previouslyEnabledAgents != null) {
512 discoveredAgents.addAll(previouslyEnabledAgents);
513 }
514 utils.setEnabledTrustAgents(discoveredAgents, userId);
515 Settings.Secure.putIntForUser(mContext.getContentResolver(),
516 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
517 }
518
519 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
520 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
521 0 /* flags */, userId);
522 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
523 for (ResolveInfo resolveInfo : resolveInfos) {
524 if (resolveInfo.serviceInfo == null) continue;
525 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
526 String packageName = resolveInfo.serviceInfo.packageName;
527 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
528 != PackageManager.PERMISSION_GRANTED) {
529 ComponentName name = getComponentName(resolveInfo);
530 Log.w(TAG, "Skipping agent " + name + " because package does not have"
531 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
532 continue;
533 }
534 allowedAgents.add(resolveInfo);
535 }
536 return allowedAgents;
537 }
538
Adrian Roos82142c22014-03-27 14:56:59 +0100539 // Agent dispatch and aggregation
540
541 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700542 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200543 return false;
544 }
Adrian Roos82142c22014-03-27 14:56:59 +0100545 for (int i = 0; i < mActiveAgents.size(); i++) {
546 AgentInfo info = mActiveAgents.valueAt(i);
547 if (info.userId == userId) {
548 if (info.agent.isTrusted()) {
549 return true;
550 }
551 }
552 }
553 return false;
554 }
555
Adrian Roos7861c662014-07-25 15:37:28 +0200556 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700557 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200558 return false;
559 }
560 for (int i = 0; i < mActiveAgents.size(); i++) {
561 AgentInfo info = mActiveAgents.valueAt(i);
562 if (info.userId == userId) {
563 if (info.agent.isManagingTrust()) {
564 return true;
565 }
566 }
567 }
568 return false;
569 }
570
Adrian Roos82142c22014-03-27 14:56:59 +0100571 private void dispatchUnlockAttempt(boolean successful, int userId) {
572 for (int i = 0; i < mActiveAgents.size(); i++) {
573 AgentInfo info = mActiveAgents.valueAt(i);
574 if (info.userId == userId) {
575 info.agent.onUnlockAttempt(successful);
576 }
577 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200578 }
579
Adrian Roos82142c22014-03-27 14:56:59 +0100580 // Listeners
581
582 private void addListener(ITrustListener listener) {
583 for (int i = 0; i < mTrustListeners.size(); i++) {
584 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
585 return;
586 }
587 }
588 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200589 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100590 }
591
592 private void removeListener(ITrustListener listener) {
593 for (int i = 0; i < mTrustListeners.size(); i++) {
594 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700595 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100596 return;
597 }
598 }
599 }
600
Adrian Roos94e15a52015-04-16 12:23:18 -0700601 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
602 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100603 for (int i = 0; i < mTrustListeners.size(); i++) {
604 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700605 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200606 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200607 Slog.d(TAG, "Removing dead TrustListener.");
608 mTrustListeners.remove(i);
609 i--;
610 } catch (RemoteException e) {
611 Slog.e(TAG, "Exception while notifying TrustListener.", e);
612 }
613 }
614 }
615
616 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
617 for (int i = 0; i < mTrustListeners.size(); i++) {
618 try {
619 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
620 } catch (DeadObjectException e) {
621 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200622 mTrustListeners.remove(i);
623 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100624 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200625 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100626 }
627 }
628 }
629
Adrian Rooscbe614f2014-10-28 20:16:12 +0100630 // User lifecycle
631
632 @Override
633 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100634 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100635 }
636
637 @Override
638 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100639 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
640 }
641
642 @Override
643 public void onSwitchUser(int userId) {
644 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100645 }
646
Adrian Roos82142c22014-03-27 14:56:59 +0100647 // Plumbing
648
649 private final IBinder mService = new ITrustManager.Stub() {
650 @Override
651 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
652 enforceReportPermission();
653 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
654 .sendToTarget();
655 }
656
657 @Override
658 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
659 enforceReportPermission();
660 // coalesce refresh messages.
661 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
662 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
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 Roos50bfeec2014-11-20 16:21:11 +0100689
Clara Bayarri078e91b2016-01-15 16:57:35 +0000690 long token = Binder.clearCallingIdentity();
691 try {
692 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
693 userId = resolveProfileParent(userId);
694 }
695 return isDeviceLockedInner(userId);
696 } finally {
697 Binder.restoreCallingIdentity(token);
698 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200699 }
700
Adrian Roos82893682015-04-02 16:17:46 +0200701 @Override
702 public boolean isDeviceSecure(int userId) throws RemoteException {
703 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
704 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +0200705
706 long token = Binder.clearCallingIdentity();
707 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +0000708 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
709 userId = resolveProfileParent(userId);
710 }
Clara Bayarria1771112015-12-18 16:29:18 +0000711 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200712 } finally {
713 Binder.restoreCallingIdentity(token);
714 }
715 }
716
Adrian Roos82142c22014-03-27 14:56:59 +0100717 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200718 mContext.enforceCallingOrSelfPermission(
719 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100720 }
721
722 private void enforceListenerPermission() {
723 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
724 "register trust listener");
725 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200726
727 @Override
728 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
729 mContext.enforceCallingPermission(Manifest.permission.DUMP,
730 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200731 if (isSafeMode()) {
732 fout.println("disabled because the system is in safe mode.");
733 return;
734 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100735 if (!mTrustAgentsCanRun) {
736 fout.println("disabled because the third-party apps can't run yet.");
737 return;
738 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200739 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200740 mHandler.runWithScissors(new Runnable() {
741 @Override
742 public void run() {
743 fout.println("Trust manager state:");
744 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100745 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200746 }
747 }
748 }, 1500);
749 }
750
751 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
752 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
753 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700754 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100755 fout.println("(managed profile)");
756 fout.println(" disabled because switching to this user is not possible.");
757 return;
758 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200759 if (isCurrent) {
760 fout.print(" (current)");
761 }
762 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200763 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100764 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -0700765 fout.print(", strongAuthRequired=" + dumpHex(
766 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200767 fout.println();
768 fout.println(" Enabled agents:");
769 boolean duplicateSimpleNames = false;
770 ArraySet<String> simpleNames = new ArraySet<String>();
771 for (AgentInfo info : mActiveAgents) {
772 if (info.userId != user.id) { continue; }
773 boolean trusted = info.agent.isTrusted();
774 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200775 fout.print(" bound=" + dumpBool(info.agent.isBound()));
776 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200777 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
778 fout.print(", trusted=" + dumpBool(trusted));
779 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200780 if (trusted) {
781 fout.println(" message=\"" + info.agent.getMessage() + "\"");
782 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200783 if (!info.agent.isConnected()) {
784 String restartTime = TrustArchive.formatDuration(
785 info.agent.getScheduledRestartUptimeMillis()
786 - SystemClock.uptimeMillis());
787 fout.println(" restartScheduledAt=" + restartTime);
788 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200789 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
790 duplicateSimpleNames = true;
791 }
792 }
793 fout.println(" Events:");
794 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
795 fout.println();
796 }
797
798 private String dumpBool(boolean b) {
799 return b ? "1" : "0";
800 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700801
802 private String dumpHex(int i) {
803 return "0x" + Integer.toHexString(i);
804 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000805
806 @Override
807 public void setDeviceLockedForUser(int userId, boolean value) {
Clara Bayarri00a9b892016-01-13 16:17:09 +0000808 enforceReportPermission();
Clara Bayarri56878a92015-10-29 15:43:55 +0000809 mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
810 .sendToTarget();
811 }
Adrian Roosc13723f2016-01-12 20:29:03 +0100812
813 @Override
814 public boolean isTrustUsuallyManaged(int userId) {
815 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
816 "query trust state");
817 return isTrustUsuallyManagedInternal(userId);
818 }
Adrian Roos82142c22014-03-27 14:56:59 +0100819 };
820
Adrian Roosc13723f2016-01-12 20:29:03 +0100821 private boolean isTrustUsuallyManagedInternal(int userId) {
822 synchronized (mTrustUsuallyManagedForUser) {
823 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
824 if (i >= 0) {
825 return mTrustUsuallyManagedForUser.valueAt(i);
826 }
827 }
828 // It's not in memory yet, get the value from persisted storage instead
829 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
830 synchronized (mTrustUsuallyManagedForUser) {
831 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
832 if (i >= 0) {
833 // Someone set the trust usually managed in the mean time. Better use that.
834 return mTrustUsuallyManagedForUser.valueAt(i);
835 } else {
836 // .. otherwise it's safe to cache the fetched value now.
837 mTrustUsuallyManagedForUser.put(userId, persistedValue);
838 return persistedValue;
839 }
840 }
841 }
842
Adrian Roosbcd07652014-10-22 16:57:16 +0200843 private int resolveProfileParent(int userId) {
844 long identity = Binder.clearCallingIdentity();
845 try {
846 UserInfo parent = mUserManager.getProfileParent(userId);
847 if (parent != null) {
848 return parent.getUserHandle().getIdentifier();
849 }
850 return userId;
851 } finally {
852 Binder.restoreCallingIdentity(identity);
853 }
854 }
855
Adrian Roos82142c22014-03-27 14:56:59 +0100856 private final Handler mHandler = new Handler() {
857 @Override
858 public void handleMessage(Message msg) {
859 switch (msg.what) {
860 case MSG_REGISTER_LISTENER:
861 addListener((ITrustListener) msg.obj);
862 break;
863 case MSG_UNREGISTER_LISTENER:
864 removeListener((ITrustListener) msg.obj);
865 break;
866 case MSG_DISPATCH_UNLOCK_ATTEMPT:
867 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
868 break;
869 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700870 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100871 // This is also called when the security mode of a user changes.
872 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100873 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100874 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100875 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100876 break;
877 case MSG_START_USER:
878 case MSG_CLEANUP_USER:
879 refreshAgentList(msg.arg1);
880 break;
881 case MSG_SWITCH_USER:
882 mCurrentUser = msg.arg1;
883 refreshDeviceLockedForUser(UserHandle.USER_ALL);
884 break;
Clara Bayarri56878a92015-10-29 15:43:55 +0000885 case MSG_SET_DEVICE_LOCKED:
886 setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
887 break;
Adrian Roosc13723f2016-01-12 20:29:03 +0100888 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
889 SparseBooleanArray usuallyManaged;
890 synchronized (mTrustUsuallyManagedForUser) {
891 usuallyManaged = mTrustUsuallyManagedForUser.clone();
892 }
893
894 for (int i = 0; i < usuallyManaged.size(); i++) {
895 int userId = usuallyManaged.keyAt(i);
896 boolean value = usuallyManaged.valueAt(i);
897 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
898 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
899 }
900 }
Adrian Roos82142c22014-03-27 14:56:59 +0100901 }
902 }
903 };
904
905 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
906 @Override
907 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700908 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100909 }
910
911 @Override
912 public boolean onPackageChanged(String packageName, int uid, String[] components) {
913 // We're interested in all changes, even if just some components get enabled / disabled.
914 return true;
915 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200916
917 @Override
918 public void onPackageDisappeared(String packageName, int reason) {
919 removeAgentsOfPackage(packageName);
920 }
Adrian Roos82142c22014-03-27 14:56:59 +0100921 };
Adrian Roosca36b952014-05-16 18:52:29 +0200922
Adrian Roosb5e47222015-08-14 15:53:06 -0700923 private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker() {
924 @Override
925 public void onStrongAuthRequiredChanged(int userId) {
926 refreshAgentList(userId);
927 }
928 };
929
Adrian Roos9dbe1902014-08-13 18:25:52 +0200930 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200931
932 @Override
933 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200934 String action = intent.getAction();
935 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700936 refreshAgentList(getSendingUserId());
937 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200938 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100939 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200940 if (userId > 0) {
941 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200942 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100943 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
944 int userId = getUserId(intent);
945 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100946 synchronized (mUserIsTrusted) {
947 mUserIsTrusted.delete(userId);
948 }
949 synchronized (mDeviceLockedForUser) {
950 mDeviceLockedForUser.delete(userId);
951 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100952 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100953 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100954 }
955 }
956 }
957
958 private int getUserId(Intent intent) {
959 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
960 if (userId > 0) {
961 return userId;
962 } else {
963 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
964 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200965 }
966 }
967
968 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200969 IntentFilter filter = new IntentFilter();
970 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
971 filter.addAction(Intent.ACTION_USER_PRESENT);
Adrian Roos3870d452014-09-05 18:22:28 +0200972 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100973 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200974 context.registerReceiverAsUser(this,
975 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200976 filter,
Adrian Roosca36b952014-05-16 18:52:29 +0200977 null /* permission */,
978 null /* scheduler */);
979 }
980 }
Adrian Roos82142c22014-03-27 14:56:59 +0100981}