blob: b54e86660a47dd495b480c096db28e0f4bff60eb [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
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800128 private final StrongAuthTracker mStrongAuthTracker;
129
Adrian Rooscbe614f2014-10-28 20:16:12 +0100130 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700131 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100132
Adrian Roos82142c22014-03-27 14:56:59 +0100133 public TrustManagerService(Context context) {
134 super(context);
135 mContext = context;
136 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100137 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200138 mLockPatternUtils = new LockPatternUtils(context);
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800139
140 mStrongAuthTracker = new StrongAuthTracker(context) {
141 @Override
142 public void onStrongAuthRequiredChanged(int userId) {
143 refreshAgentList(userId);
144 }
145 };
Adrian Roos82142c22014-03-27 14:56:59 +0100146 }
147
148 @Override
149 public void onStart() {
150 publishBinderService(Context.TRUST_SERVICE, mService);
151 }
152
153 @Override
154 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200155 if (isSafeMode()) {
156 // No trust agents in safe mode.
157 return;
158 }
159 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100160 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200161 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700162 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100163 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
164 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700165 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200166 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700167 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100168 }
169 }
170
171 // Agent management
172
173 private static final class AgentInfo {
174 CharSequence label;
175 Drawable icon;
176 ComponentName component; // service that implements ITrustAgent
177 ComponentName settings; // setting to launch to modify agent.
178 TrustAgentWrapper agent;
179 int userId;
180
181 @Override
182 public boolean equals(Object other) {
183 if (!(other instanceof AgentInfo)) {
184 return false;
185 }
186 AgentInfo o = (AgentInfo) other;
187 return component.equals(o.component) && userId == o.userId;
188 }
189
190 @Override
191 public int hashCode() {
192 return component.hashCode() * 31 + userId;
193 }
194 }
195
196 private void updateTrustAll() {
197 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
198 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700199 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100200 }
201 }
202
Adrian Roos94e15a52015-04-16 12:23:18 -0700203 public void updateTrust(int userId, int flags) {
Adrian Roosc13723f2016-01-12 20:29:03 +0100204 boolean managed = aggregateIsTrustManaged(userId);
205 dispatchOnTrustManagedChanged(managed, userId);
206 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
207 && isTrustUsuallyManagedInternal(userId) != managed) {
208 updateTrustUsuallyManaged(userId, managed);
209 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200210 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100211 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200212 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100213 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200214 mUserIsTrusted.put(userId, trusted);
215 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700216 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100217 if (changed) {
218 refreshDeviceLockedForUser(userId);
219 }
Adrian Roos82142c22014-03-27 14:56:59 +0100220 }
221
Adrian Roosc13723f2016-01-12 20:29:03 +0100222 private void updateTrustUsuallyManaged(int userId, boolean managed) {
223 synchronized (mTrustUsuallyManagedForUser) {
224 mTrustUsuallyManagedForUser.put(userId, managed);
225 }
226 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
227 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
228 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
229 mHandler.sendMessageDelayed(
230 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
231 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
232 }
233
Marco Fucci4e68f112014-08-29 12:31:48 -0700234 void refreshAgentList(int userId) {
Adrian Roos82142c22014-03-27 14:56:59 +0100235 if (DEBUG) Slog.d(TAG, "refreshAgentList()");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100236 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200237 return;
238 }
Xiaohui Chen09e02912015-08-05 09:44:56 -0700239 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roose681c272014-09-08 14:03:47 +0200240 Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
241 + " must be USER_ALL or a specific user.", new Throwable("here"));
242 userId = UserHandle.USER_ALL;
243 }
Adrian Roos82142c22014-03-27 14:56:59 +0100244 PackageManager pm = mContext.getPackageManager();
245
Marco Fucci4e68f112014-08-29 12:31:48 -0700246 List<UserInfo> userInfos;
247 if (userId == UserHandle.USER_ALL) {
248 userInfos = mUserManager.getUsers(true /* excludeDying */);
249 } else {
250 userInfos = new ArrayList<>();
251 userInfos.add(mUserManager.getUserInfo(userId));
252 }
Adrian Roos3870d452014-09-05 18:22:28 +0200253 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100254
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200255 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
256 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100257
258 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100259 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
260 || userInfo.guestToRemove) continue;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700261 if (!userInfo.supportsSwitchToByUser()) continue;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100262 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
Adrian Roos481a6df2014-11-20 19:48:56 +0100263 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
Adrian Roosb5e47222015-08-14 15:53:06 -0700264 if (!mStrongAuthTracker.isTrustAllowedForUser(userInfo.id)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200265 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
266 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700267 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200268 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
269
Adrian Roos82142c22014-03-27 14:56:59 +0100270 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200271 if (enabledAgents == null) {
Adrian Roos82142c22014-03-27 14:56:59 +0100272 continue;
273 }
Adrian Roos3870d452014-09-05 18:22:28 +0200274 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100275 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100276 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100277
Adrian Roos3870d452014-09-05 18:22:28 +0200278 if (!enabledAgents.contains(name)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200279 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700280 List<PersistableBundle> config =
281 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200282 // Disable agent if no features are enabled.
Jim Millere303bf42014-08-26 17:12:29 -0700283 if (config == null || config.isEmpty()) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200284 }
285
Adrian Roos82142c22014-03-27 14:56:59 +0100286 AgentInfo agentInfo = new AgentInfo();
287 agentInfo.component = name;
288 agentInfo.userId = userInfo.id;
289 if (!mActiveAgents.contains(agentInfo)) {
290 agentInfo.label = resolveInfo.loadLabel(pm);
291 agentInfo.icon = resolveInfo.loadIcon(pm);
292 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
293 agentInfo.agent = new TrustAgentWrapper(mContext, this,
294 new Intent().setComponent(name), userInfo.getUserHandle());
295 mActiveAgents.add(agentInfo);
296 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200297 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100298 }
299 }
300 }
301
302 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200303 for (int i = 0; i < obsoleteAgents.size(); i++) {
304 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roose681c272014-09-08 14:03:47 +0200305 if (userId == UserHandle.USER_ALL || userId == info.userId) {
306 if (info.agent.isManagingTrust()) {
307 trustMayHaveChanged = true;
308 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100309 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200310 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100311 }
Adrian Roos82142c22014-03-27 14:56:59 +0100312 }
313
314 if (trustMayHaveChanged) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100315 if (userId == UserHandle.USER_ALL) {
316 updateTrustAll();
317 } else {
Adrian Roos94e15a52015-04-16 12:23:18 -0700318 updateTrust(userId, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100319 }
Adrian Roos82142c22014-03-27 14:56:59 +0100320 }
321 }
322
Clara Bayarri56878a92015-10-29 15:43:55 +0000323 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarria1771112015-12-18 16:29:18 +0000324 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
325 synchronized (mDeviceLockedForUser) {
326 mDeviceLockedForUser.put(userId, locked);
Clara Bayarri56878a92015-10-29 15:43:55 +0000327 }
328 }
329 }
330
Adrian Roos481a6df2014-11-20 19:48:56 +0100331 boolean isDeviceLockedInner(int userId) {
332 synchronized (mDeviceLockedForUser) {
333 return mDeviceLockedForUser.get(userId, true);
334 }
335 }
336
337 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700338 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100339 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100340 + " must be USER_ALL or a specific user.", new Throwable("here"));
341 userId = UserHandle.USER_ALL;
342 }
343
344 List<UserInfo> userInfos;
345 if (userId == UserHandle.USER_ALL) {
346 userInfos = mUserManager.getUsers(true /* excludeDying */);
347 } else {
348 userInfos = new ArrayList<>();
349 userInfos.add(mUserManager.getUserInfo(userId));
350 }
351
352 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
353
354 for (int i = 0; i < userInfos.size(); i++) {
355 UserInfo info = userInfos.get(i);
356
357 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700358 || !info.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100359 continue;
360 }
361
362 int id = info.id;
363 boolean secure = mLockPatternUtils.isSecure(id);
364 boolean trusted = aggregateIsTrusted(id);
365 boolean showingKeyguard = true;
366 if (mCurrentUser == id) {
367 try {
368 showingKeyguard = wm.isKeyguardLocked();
369 } catch (RemoteException e) {
370 }
371 }
372 boolean deviceLocked = secure && showingKeyguard && !trusted;
373
374 boolean changed;
375 synchronized (mDeviceLockedForUser) {
376 changed = isDeviceLockedInner(id) != deviceLocked;
377 mDeviceLockedForUser.put(id, deviceLocked);
378 }
379 if (changed) {
380 dispatchDeviceLocked(id, deviceLocked);
381 }
382 }
383 }
384
385 private void dispatchDeviceLocked(int userId, boolean isLocked) {
386 for (int i = 0; i < mActiveAgents.size(); i++) {
387 AgentInfo agent = mActiveAgents.valueAt(i);
388 if (agent.userId == userId) {
389 if (isLocked) {
390 agent.agent.onDeviceLocked();
391 } else{
392 agent.agent.onDeviceUnlocked();
393 }
394 }
395 }
396 }
397
Marco Fucci4e68f112014-08-29 12:31:48 -0700398 void updateDevicePolicyFeatures() {
Adrian Roos8f211582014-07-29 15:09:57 +0200399 for (int i = 0; i < mActiveAgents.size(); i++) {
400 AgentInfo info = mActiveAgents.valueAt(i);
401 if (info.agent.isConnected()) {
402 info.agent.updateDevicePolicyFeatures();
403 }
404 }
405 }
406
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200407 private void removeAgentsOfPackage(String packageName) {
408 boolean trustMayHaveChanged = false;
409 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
410 AgentInfo info = mActiveAgents.valueAt(i);
411 if (packageName.equals(info.component.getPackageName())) {
412 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200413 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200414 trustMayHaveChanged = true;
415 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100416 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200417 mActiveAgents.removeAt(i);
418 }
419 }
420 if (trustMayHaveChanged) {
421 updateTrustAll();
422 }
423 }
424
425 public void resetAgent(ComponentName name, int userId) {
426 boolean trustMayHaveChanged = false;
427 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
428 AgentInfo info = mActiveAgents.valueAt(i);
429 if (name.equals(info.component) && userId == info.userId) {
430 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200431 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200432 trustMayHaveChanged = true;
433 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100434 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200435 mActiveAgents.removeAt(i);
436 }
437 }
438 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700439 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200440 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700441 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200442 }
443
Adrian Roos82142c22014-03-27 14:56:59 +0100444 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
445 if (resolveInfo == null || resolveInfo.serviceInfo == null
446 || resolveInfo.serviceInfo.metaData == null) return null;
447 String cn = null;
448 XmlResourceParser parser = null;
449 Exception caughtException = null;
450 try {
451 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
452 TrustAgentService.TRUST_AGENT_META_DATA);
453 if (parser == null) {
454 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
455 return null;
456 }
457 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
458 AttributeSet attrs = Xml.asAttributeSet(parser);
459 int type;
460 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
461 && type != XmlPullParser.START_TAG) {
462 // Drain preamble.
463 }
464 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200465 if (!"trust-agent".equals(nodeName)) {
466 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100467 return null;
468 }
469 TypedArray sa = res
470 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
471 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
472 sa.recycle();
473 } catch (PackageManager.NameNotFoundException e) {
474 caughtException = e;
475 } catch (IOException e) {
476 caughtException = e;
477 } catch (XmlPullParserException e) {
478 caughtException = e;
479 } finally {
480 if (parser != null) parser.close();
481 }
482 if (caughtException != null) {
483 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
484 return null;
485 }
486 if (cn == null) {
487 return null;
488 }
489 if (cn.indexOf('/') < 0) {
490 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
491 }
492 return ComponentName.unflattenFromString(cn);
493 }
494
495 private ComponentName getComponentName(ResolveInfo resolveInfo) {
496 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
497 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
498 }
499
Adrian Roos3870d452014-09-05 18:22:28 +0200500 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
501 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
502 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
503 return;
504 }
505 PackageManager pm = mContext.getPackageManager();
506 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
507 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
508 for (ResolveInfo resolveInfo : resolveInfos) {
509 ComponentName componentName = getComponentName(resolveInfo);
510 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
511 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
512 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
513 + "is not a system package.");
514 continue;
515 }
516 discoveredAgents.add(componentName);
517 }
518
519 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
520 if (previouslyEnabledAgents != null) {
521 discoveredAgents.addAll(previouslyEnabledAgents);
522 }
523 utils.setEnabledTrustAgents(discoveredAgents, userId);
524 Settings.Secure.putIntForUser(mContext.getContentResolver(),
525 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
526 }
527
528 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
529 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
530 0 /* flags */, userId);
531 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
532 for (ResolveInfo resolveInfo : resolveInfos) {
533 if (resolveInfo.serviceInfo == null) continue;
534 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
535 String packageName = resolveInfo.serviceInfo.packageName;
536 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
537 != PackageManager.PERMISSION_GRANTED) {
538 ComponentName name = getComponentName(resolveInfo);
539 Log.w(TAG, "Skipping agent " + name + " because package does not have"
540 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
541 continue;
542 }
543 allowedAgents.add(resolveInfo);
544 }
545 return allowedAgents;
546 }
547
Adrian Roos82142c22014-03-27 14:56:59 +0100548 // Agent dispatch and aggregation
549
550 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700551 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200552 return false;
553 }
Adrian Roos82142c22014-03-27 14:56:59 +0100554 for (int i = 0; i < mActiveAgents.size(); i++) {
555 AgentInfo info = mActiveAgents.valueAt(i);
556 if (info.userId == userId) {
557 if (info.agent.isTrusted()) {
558 return true;
559 }
560 }
561 }
562 return false;
563 }
564
Adrian Roos7861c662014-07-25 15:37:28 +0200565 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700566 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200567 return false;
568 }
569 for (int i = 0; i < mActiveAgents.size(); i++) {
570 AgentInfo info = mActiveAgents.valueAt(i);
571 if (info.userId == userId) {
572 if (info.agent.isManagingTrust()) {
573 return true;
574 }
575 }
576 }
577 return false;
578 }
579
Adrian Roos82142c22014-03-27 14:56:59 +0100580 private void dispatchUnlockAttempt(boolean successful, int userId) {
581 for (int i = 0; i < mActiveAgents.size(); i++) {
582 AgentInfo info = mActiveAgents.valueAt(i);
583 if (info.userId == userId) {
584 info.agent.onUnlockAttempt(successful);
585 }
586 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200587 }
588
Adrian Roos82142c22014-03-27 14:56:59 +0100589 // Listeners
590
591 private void addListener(ITrustListener listener) {
592 for (int i = 0; i < mTrustListeners.size(); i++) {
593 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
594 return;
595 }
596 }
597 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200598 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100599 }
600
601 private void removeListener(ITrustListener listener) {
602 for (int i = 0; i < mTrustListeners.size(); i++) {
603 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700604 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100605 return;
606 }
607 }
608 }
609
Adrian Roos94e15a52015-04-16 12:23:18 -0700610 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
611 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100612 for (int i = 0; i < mTrustListeners.size(); i++) {
613 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700614 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200615 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200616 Slog.d(TAG, "Removing dead TrustListener.");
617 mTrustListeners.remove(i);
618 i--;
619 } catch (RemoteException e) {
620 Slog.e(TAG, "Exception while notifying TrustListener.", e);
621 }
622 }
623 }
624
625 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
626 for (int i = 0; i < mTrustListeners.size(); i++) {
627 try {
628 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
629 } catch (DeadObjectException e) {
630 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200631 mTrustListeners.remove(i);
632 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100633 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200634 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100635 }
636 }
637 }
638
Adrian Rooscbe614f2014-10-28 20:16:12 +0100639 // User lifecycle
640
641 @Override
642 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100643 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100644 }
645
646 @Override
647 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100648 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
649 }
650
651 @Override
652 public void onSwitchUser(int userId) {
653 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100654 }
655
Adrian Roos82142c22014-03-27 14:56:59 +0100656 // Plumbing
657
658 private final IBinder mService = new ITrustManager.Stub() {
659 @Override
660 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
661 enforceReportPermission();
662 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
663 .sendToTarget();
664 }
665
666 @Override
667 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
668 enforceReportPermission();
669 // coalesce refresh messages.
670 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
671 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
672 }
673
674 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100675 public void reportKeyguardShowingChanged() throws RemoteException {
676 enforceReportPermission();
677 // coalesce refresh messages.
678 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
679 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
680 }
681
682 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100683 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
684 enforceListenerPermission();
685 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
686 }
687
688 @Override
689 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
690 enforceListenerPermission();
691 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
692 }
693
Adrian Roosbcd07652014-10-22 16:57:16 +0200694 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100695 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200696 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100697 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +0100698
Clara Bayarri078e91b2016-01-15 16:57:35 +0000699 long token = Binder.clearCallingIdentity();
700 try {
701 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
702 userId = resolveProfileParent(userId);
703 }
704 return isDeviceLockedInner(userId);
705 } finally {
706 Binder.restoreCallingIdentity(token);
707 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200708 }
709
Adrian Roos82893682015-04-02 16:17:46 +0200710 @Override
711 public boolean isDeviceSecure(int userId) throws RemoteException {
712 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
713 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +0200714
715 long token = Binder.clearCallingIdentity();
716 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +0000717 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
718 userId = resolveProfileParent(userId);
719 }
Clara Bayarria1771112015-12-18 16:29:18 +0000720 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200721 } finally {
722 Binder.restoreCallingIdentity(token);
723 }
724 }
725
Adrian Roos82142c22014-03-27 14:56:59 +0100726 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200727 mContext.enforceCallingOrSelfPermission(
728 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100729 }
730
731 private void enforceListenerPermission() {
732 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
733 "register trust listener");
734 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200735
736 @Override
737 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
738 mContext.enforceCallingPermission(Manifest.permission.DUMP,
739 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200740 if (isSafeMode()) {
741 fout.println("disabled because the system is in safe mode.");
742 return;
743 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100744 if (!mTrustAgentsCanRun) {
745 fout.println("disabled because the third-party apps can't run yet.");
746 return;
747 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200748 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200749 mHandler.runWithScissors(new Runnable() {
750 @Override
751 public void run() {
752 fout.println("Trust manager state:");
753 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100754 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200755 }
756 }
757 }, 1500);
758 }
759
760 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
761 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
762 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700763 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100764 fout.println("(managed profile)");
765 fout.println(" disabled because switching to this user is not possible.");
766 return;
767 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200768 if (isCurrent) {
769 fout.print(" (current)");
770 }
771 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200772 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100773 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -0700774 fout.print(", strongAuthRequired=" + dumpHex(
775 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200776 fout.println();
777 fout.println(" Enabled agents:");
778 boolean duplicateSimpleNames = false;
779 ArraySet<String> simpleNames = new ArraySet<String>();
780 for (AgentInfo info : mActiveAgents) {
781 if (info.userId != user.id) { continue; }
782 boolean trusted = info.agent.isTrusted();
783 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200784 fout.print(" bound=" + dumpBool(info.agent.isBound()));
785 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200786 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
787 fout.print(", trusted=" + dumpBool(trusted));
788 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200789 if (trusted) {
790 fout.println(" message=\"" + info.agent.getMessage() + "\"");
791 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200792 if (!info.agent.isConnected()) {
793 String restartTime = TrustArchive.formatDuration(
794 info.agent.getScheduledRestartUptimeMillis()
795 - SystemClock.uptimeMillis());
796 fout.println(" restartScheduledAt=" + restartTime);
797 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200798 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
799 duplicateSimpleNames = true;
800 }
801 }
802 fout.println(" Events:");
803 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
804 fout.println();
805 }
806
807 private String dumpBool(boolean b) {
808 return b ? "1" : "0";
809 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700810
811 private String dumpHex(int i) {
812 return "0x" + Integer.toHexString(i);
813 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000814
815 @Override
816 public void setDeviceLockedForUser(int userId, boolean value) {
Clara Bayarri00a9b892016-01-13 16:17:09 +0000817 enforceReportPermission();
Clara Bayarri56878a92015-10-29 15:43:55 +0000818 mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
819 .sendToTarget();
820 }
Adrian Roosc13723f2016-01-12 20:29:03 +0100821
822 @Override
823 public boolean isTrustUsuallyManaged(int userId) {
824 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
825 "query trust state");
826 return isTrustUsuallyManagedInternal(userId);
827 }
Adrian Roos82142c22014-03-27 14:56:59 +0100828 };
829
Adrian Roosc13723f2016-01-12 20:29:03 +0100830 private boolean isTrustUsuallyManagedInternal(int userId) {
831 synchronized (mTrustUsuallyManagedForUser) {
832 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
833 if (i >= 0) {
834 return mTrustUsuallyManagedForUser.valueAt(i);
835 }
836 }
837 // It's not in memory yet, get the value from persisted storage instead
838 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
839 synchronized (mTrustUsuallyManagedForUser) {
840 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
841 if (i >= 0) {
842 // Someone set the trust usually managed in the mean time. Better use that.
843 return mTrustUsuallyManagedForUser.valueAt(i);
844 } else {
845 // .. otherwise it's safe to cache the fetched value now.
846 mTrustUsuallyManagedForUser.put(userId, persistedValue);
847 return persistedValue;
848 }
849 }
850 }
851
Adrian Roosbcd07652014-10-22 16:57:16 +0200852 private int resolveProfileParent(int userId) {
853 long identity = Binder.clearCallingIdentity();
854 try {
855 UserInfo parent = mUserManager.getProfileParent(userId);
856 if (parent != null) {
857 return parent.getUserHandle().getIdentifier();
858 }
859 return userId;
860 } finally {
861 Binder.restoreCallingIdentity(identity);
862 }
863 }
864
Adrian Roos82142c22014-03-27 14:56:59 +0100865 private final Handler mHandler = new Handler() {
866 @Override
867 public void handleMessage(Message msg) {
868 switch (msg.what) {
869 case MSG_REGISTER_LISTENER:
870 addListener((ITrustListener) msg.obj);
871 break;
872 case MSG_UNREGISTER_LISTENER:
873 removeListener((ITrustListener) msg.obj);
874 break;
875 case MSG_DISPATCH_UNLOCK_ATTEMPT:
876 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
877 break;
878 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700879 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100880 // This is also called when the security mode of a user changes.
881 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100882 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100883 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100884 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100885 break;
886 case MSG_START_USER:
887 case MSG_CLEANUP_USER:
888 refreshAgentList(msg.arg1);
889 break;
890 case MSG_SWITCH_USER:
891 mCurrentUser = msg.arg1;
892 refreshDeviceLockedForUser(UserHandle.USER_ALL);
893 break;
Clara Bayarri56878a92015-10-29 15:43:55 +0000894 case MSG_SET_DEVICE_LOCKED:
895 setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
896 break;
Adrian Roosc13723f2016-01-12 20:29:03 +0100897 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
898 SparseBooleanArray usuallyManaged;
899 synchronized (mTrustUsuallyManagedForUser) {
900 usuallyManaged = mTrustUsuallyManagedForUser.clone();
901 }
902
903 for (int i = 0; i < usuallyManaged.size(); i++) {
904 int userId = usuallyManaged.keyAt(i);
905 boolean value = usuallyManaged.valueAt(i);
906 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
907 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
908 }
909 }
Adrian Roos82142c22014-03-27 14:56:59 +0100910 }
911 }
912 };
913
914 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
915 @Override
916 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700917 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100918 }
919
920 @Override
921 public boolean onPackageChanged(String packageName, int uid, String[] components) {
922 // We're interested in all changes, even if just some components get enabled / disabled.
923 return true;
924 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200925
926 @Override
927 public void onPackageDisappeared(String packageName, int reason) {
928 removeAgentsOfPackage(packageName);
929 }
Adrian Roos82142c22014-03-27 14:56:59 +0100930 };
Adrian Roosca36b952014-05-16 18:52:29 +0200931
Adrian Roos9dbe1902014-08-13 18:25:52 +0200932 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200933
934 @Override
935 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200936 String action = intent.getAction();
937 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700938 refreshAgentList(getSendingUserId());
939 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200940 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100941 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200942 if (userId > 0) {
943 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200944 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100945 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
946 int userId = getUserId(intent);
947 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100948 synchronized (mUserIsTrusted) {
949 mUserIsTrusted.delete(userId);
950 }
951 synchronized (mDeviceLockedForUser) {
952 mDeviceLockedForUser.delete(userId);
953 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100954 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100955 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100956 }
957 }
958 }
959
960 private int getUserId(Intent intent) {
961 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
962 if (userId > 0) {
963 return userId;
964 } else {
965 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
966 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200967 }
968 }
969
970 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200971 IntentFilter filter = new IntentFilter();
972 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
973 filter.addAction(Intent.ACTION_USER_PRESENT);
Adrian Roos3870d452014-09-05 18:22:28 +0200974 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100975 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200976 context.registerReceiverAsUser(this,
977 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200978 filter,
Adrian Roosca36b952014-05-16 18:52:29 +0200979 null /* permission */,
980 null /* scheduler */);
981 }
982 }
Adrian Roos82142c22014-03-27 14:56:59 +0100983}