blob: 984fb7627fea13c893a4a61bcb52967f08a4e2f5 [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 Roos481a6df2014-11-20 19:48:56 +010099 private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
100 private static final int MSG_START_USER = 7;
101 private static final int MSG_CLEANUP_USER = 8;
102 private static final int MSG_SWITCH_USER = 9;
Clara Bayarri56878a92015-10-29 15:43:55 +0000103 private static final int MSG_SET_DEVICE_LOCKED = 10;
Adrian Roosc13723f2016-01-12 20:29:03 +0100104 private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 11;
105
Adrian Roos517b3a42016-03-03 14:58:33 -0800106 private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
Adrian Roos82142c22014-03-27 14:56:59 +0100107
Adrian Roosb5e47222015-08-14 15:53:06 -0700108 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
109 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
Adrian Roos9dbe1902014-08-13 18:25:52 +0200110 private final Receiver mReceiver = new Receiver();
Adrian Roosb5e47222015-08-14 15:53:06 -0700111
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200112 /* package */ final TrustArchive mArchive = new TrustArchive();
Adrian Roos82142c22014-03-27 14:56:59 +0100113 private final Context mContext;
Adrian Roos3870d452014-09-05 18:22:28 +0200114 private final LockPatternUtils mLockPatternUtils;
Adrian Roosbcd07652014-10-22 16:57:16 +0200115 private final UserManager mUserManager;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100116 private final ActivityManager mActivityManager;
Adrian Roos82142c22014-03-27 14:56:59 +0100117
Adrian Roosbcd07652014-10-22 16:57:16 +0200118 @GuardedBy("mUserIsTrusted")
119 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
Adrian Roos82142c22014-03-27 14:56:59 +0100120
Adrian Roos481a6df2014-11-20 19:48:56 +0100121 @GuardedBy("mDeviceLockedForUser")
122 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
123
Adrian Roosc13723f2016-01-12 20:29:03 +0100124 @GuardedBy("mDeviceLockedForUser")
125 private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
126
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800127 private final StrongAuthTracker mStrongAuthTracker;
128
Adrian Rooscbe614f2014-10-28 20:16:12 +0100129 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700130 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100131
Adrian Roos82142c22014-03-27 14:56:59 +0100132 public TrustManagerService(Context context) {
133 super(context);
134 mContext = context;
135 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100136 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200137 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos517b3a42016-03-03 14:58:33 -0800138 mStrongAuthTracker = new StrongAuthTracker(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100139 }
140
141 @Override
142 public void onStart() {
143 publishBinderService(Context.TRUST_SERVICE, mService);
144 }
145
146 @Override
147 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200148 if (isSafeMode()) {
149 // No trust agents in safe mode.
150 return;
151 }
152 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100153 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200154 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700155 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100156 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
157 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700158 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200159 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700160 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100161 }
162 }
163
164 // Agent management
165
166 private static final class AgentInfo {
167 CharSequence label;
168 Drawable icon;
169 ComponentName component; // service that implements ITrustAgent
170 ComponentName settings; // setting to launch to modify agent.
171 TrustAgentWrapper agent;
172 int userId;
173
174 @Override
175 public boolean equals(Object other) {
176 if (!(other instanceof AgentInfo)) {
177 return false;
178 }
179 AgentInfo o = (AgentInfo) other;
180 return component.equals(o.component) && userId == o.userId;
181 }
182
183 @Override
184 public int hashCode() {
185 return component.hashCode() * 31 + userId;
186 }
187 }
188
189 private void updateTrustAll() {
190 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
191 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700192 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100193 }
194 }
195
Adrian Roos94e15a52015-04-16 12:23:18 -0700196 public void updateTrust(int userId, int flags) {
Adrian Roosc13723f2016-01-12 20:29:03 +0100197 boolean managed = aggregateIsTrustManaged(userId);
198 dispatchOnTrustManagedChanged(managed, userId);
199 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
200 && isTrustUsuallyManagedInternal(userId) != managed) {
201 updateTrustUsuallyManaged(userId, managed);
202 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200203 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100204 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200205 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100206 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200207 mUserIsTrusted.put(userId, trusted);
208 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700209 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100210 if (changed) {
211 refreshDeviceLockedForUser(userId);
212 }
Adrian Roos82142c22014-03-27 14:56:59 +0100213 }
214
Adrian Roosc13723f2016-01-12 20:29:03 +0100215 private void updateTrustUsuallyManaged(int userId, boolean managed) {
216 synchronized (mTrustUsuallyManagedForUser) {
217 mTrustUsuallyManagedForUser.put(userId, managed);
218 }
219 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
220 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
221 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
222 mHandler.sendMessageDelayed(
223 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
224 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
225 }
226
Adrian Roos517b3a42016-03-03 14:58:33 -0800227 void refreshAgentList(int userIdOrAll) {
228 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100229 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200230 return;
231 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800232 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
233 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
Adrian Roose681c272014-09-08 14:03:47 +0200234 + " must be USER_ALL or a specific user.", new Throwable("here"));
Adrian Roos517b3a42016-03-03 14:58:33 -0800235 userIdOrAll = UserHandle.USER_ALL;
Adrian Roose681c272014-09-08 14:03:47 +0200236 }
Adrian Roos82142c22014-03-27 14:56:59 +0100237 PackageManager pm = mContext.getPackageManager();
238
Marco Fucci4e68f112014-08-29 12:31:48 -0700239 List<UserInfo> userInfos;
Adrian Roos517b3a42016-03-03 14:58:33 -0800240 if (userIdOrAll == UserHandle.USER_ALL) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700241 userInfos = mUserManager.getUsers(true /* excludeDying */);
242 } else {
243 userInfos = new ArrayList<>();
Adrian Roos517b3a42016-03-03 14:58:33 -0800244 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
Marco Fucci4e68f112014-08-29 12:31:48 -0700245 }
Adrian Roos3870d452014-09-05 18:22:28 +0200246 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100247
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200248 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
249 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100250
251 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100252 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
253 || userInfo.guestToRemove) continue;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700254 if (!userInfo.supportsSwitchToByUser()) continue;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100255 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
Adrian Roos481a6df2014-11-20 19:48:56 +0100256 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
Adrian Roos517b3a42016-03-03 14:58:33 -0800257 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200258 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
259 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700260 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200261 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
262
Adrian Roos82142c22014-03-27 14:56:59 +0100263 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200264 if (enabledAgents == null) {
Adrian Roos82142c22014-03-27 14:56:59 +0100265 continue;
266 }
Adrian Roos3870d452014-09-05 18:22:28 +0200267 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100268 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100269 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100270
Adrian Roos3870d452014-09-05 18:22:28 +0200271 if (!enabledAgents.contains(name)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200272 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700273 List<PersistableBundle> config =
274 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200275 // Disable agent if no features are enabled.
Jim Millere303bf42014-08-26 17:12:29 -0700276 if (config == null || config.isEmpty()) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200277 }
278
Adrian Roos82142c22014-03-27 14:56:59 +0100279 AgentInfo agentInfo = new AgentInfo();
280 agentInfo.component = name;
281 agentInfo.userId = userInfo.id;
282 if (!mActiveAgents.contains(agentInfo)) {
283 agentInfo.label = resolveInfo.loadLabel(pm);
284 agentInfo.icon = resolveInfo.loadIcon(pm);
285 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
286 agentInfo.agent = new TrustAgentWrapper(mContext, this,
287 new Intent().setComponent(name), userInfo.getUserHandle());
288 mActiveAgents.add(agentInfo);
289 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200290 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100291 }
292 }
293 }
294
295 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200296 for (int i = 0; i < obsoleteAgents.size(); i++) {
297 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roos517b3a42016-03-03 14:58:33 -0800298 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
Adrian Roose681c272014-09-08 14:03:47 +0200299 if (info.agent.isManagingTrust()) {
300 trustMayHaveChanged = true;
301 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100302 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200303 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100304 }
Adrian Roos82142c22014-03-27 14:56:59 +0100305 }
306
307 if (trustMayHaveChanged) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800308 if (userIdOrAll == UserHandle.USER_ALL) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100309 updateTrustAll();
310 } else {
Adrian Roos517b3a42016-03-03 14:58:33 -0800311 updateTrust(userIdOrAll, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100312 }
Adrian Roos82142c22014-03-27 14:56:59 +0100313 }
314 }
315
Clara Bayarri56878a92015-10-29 15:43:55 +0000316 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarria1771112015-12-18 16:29:18 +0000317 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
318 synchronized (mDeviceLockedForUser) {
319 mDeviceLockedForUser.put(userId, locked);
Clara Bayarri56878a92015-10-29 15:43:55 +0000320 }
321 }
322 }
323
Adrian Roos481a6df2014-11-20 19:48:56 +0100324 boolean isDeviceLockedInner(int userId) {
325 synchronized (mDeviceLockedForUser) {
326 return mDeviceLockedForUser.get(userId, true);
327 }
328 }
329
330 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700331 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100332 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100333 + " must be USER_ALL or a specific user.", new Throwable("here"));
334 userId = UserHandle.USER_ALL;
335 }
336
337 List<UserInfo> userInfos;
338 if (userId == UserHandle.USER_ALL) {
339 userInfos = mUserManager.getUsers(true /* excludeDying */);
340 } else {
341 userInfos = new ArrayList<>();
342 userInfos.add(mUserManager.getUserInfo(userId));
343 }
344
345 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
346
347 for (int i = 0; i < userInfos.size(); i++) {
348 UserInfo info = userInfos.get(i);
349
350 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700351 || !info.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100352 continue;
353 }
354
355 int id = info.id;
356 boolean secure = mLockPatternUtils.isSecure(id);
357 boolean trusted = aggregateIsTrusted(id);
358 boolean showingKeyguard = true;
359 if (mCurrentUser == id) {
360 try {
361 showingKeyguard = wm.isKeyguardLocked();
362 } catch (RemoteException e) {
363 }
364 }
365 boolean deviceLocked = secure && showingKeyguard && !trusted;
366
367 boolean changed;
368 synchronized (mDeviceLockedForUser) {
369 changed = isDeviceLockedInner(id) != deviceLocked;
370 mDeviceLockedForUser.put(id, deviceLocked);
371 }
372 if (changed) {
373 dispatchDeviceLocked(id, deviceLocked);
374 }
375 }
376 }
377
378 private void dispatchDeviceLocked(int userId, boolean isLocked) {
379 for (int i = 0; i < mActiveAgents.size(); i++) {
380 AgentInfo agent = mActiveAgents.valueAt(i);
381 if (agent.userId == userId) {
382 if (isLocked) {
383 agent.agent.onDeviceLocked();
384 } else{
385 agent.agent.onDeviceUnlocked();
386 }
387 }
388 }
389 }
390
Marco Fucci4e68f112014-08-29 12:31:48 -0700391 void updateDevicePolicyFeatures() {
Adrian Roos8f211582014-07-29 15:09:57 +0200392 for (int i = 0; i < mActiveAgents.size(); i++) {
393 AgentInfo info = mActiveAgents.valueAt(i);
394 if (info.agent.isConnected()) {
395 info.agent.updateDevicePolicyFeatures();
396 }
397 }
398 }
399
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200400 private void removeAgentsOfPackage(String packageName) {
401 boolean trustMayHaveChanged = false;
402 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
403 AgentInfo info = mActiveAgents.valueAt(i);
404 if (packageName.equals(info.component.getPackageName())) {
405 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200406 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200407 trustMayHaveChanged = true;
408 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100409 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200410 mActiveAgents.removeAt(i);
411 }
412 }
413 if (trustMayHaveChanged) {
414 updateTrustAll();
415 }
416 }
417
418 public void resetAgent(ComponentName name, int userId) {
419 boolean trustMayHaveChanged = false;
420 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
421 AgentInfo info = mActiveAgents.valueAt(i);
422 if (name.equals(info.component) && userId == info.userId) {
423 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200424 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200425 trustMayHaveChanged = true;
426 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100427 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200428 mActiveAgents.removeAt(i);
429 }
430 }
431 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700432 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200433 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700434 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200435 }
436
Adrian Roos82142c22014-03-27 14:56:59 +0100437 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
438 if (resolveInfo == null || resolveInfo.serviceInfo == null
439 || resolveInfo.serviceInfo.metaData == null) return null;
440 String cn = null;
441 XmlResourceParser parser = null;
442 Exception caughtException = null;
443 try {
444 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
445 TrustAgentService.TRUST_AGENT_META_DATA);
446 if (parser == null) {
447 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
448 return null;
449 }
450 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
451 AttributeSet attrs = Xml.asAttributeSet(parser);
452 int type;
453 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
454 && type != XmlPullParser.START_TAG) {
455 // Drain preamble.
456 }
457 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200458 if (!"trust-agent".equals(nodeName)) {
459 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100460 return null;
461 }
462 TypedArray sa = res
463 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
464 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
465 sa.recycle();
466 } catch (PackageManager.NameNotFoundException e) {
467 caughtException = e;
468 } catch (IOException e) {
469 caughtException = e;
470 } catch (XmlPullParserException e) {
471 caughtException = e;
472 } finally {
473 if (parser != null) parser.close();
474 }
475 if (caughtException != null) {
476 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
477 return null;
478 }
479 if (cn == null) {
480 return null;
481 }
482 if (cn.indexOf('/') < 0) {
483 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
484 }
485 return ComponentName.unflattenFromString(cn);
486 }
487
488 private ComponentName getComponentName(ResolveInfo resolveInfo) {
489 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
490 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
491 }
492
Adrian Roos3870d452014-09-05 18:22:28 +0200493 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
494 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
495 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
496 return;
497 }
498 PackageManager pm = mContext.getPackageManager();
499 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
500 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
501 for (ResolveInfo resolveInfo : resolveInfos) {
502 ComponentName componentName = getComponentName(resolveInfo);
503 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
504 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
505 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
506 + "is not a system package.");
507 continue;
508 }
509 discoveredAgents.add(componentName);
510 }
511
512 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
513 if (previouslyEnabledAgents != null) {
514 discoveredAgents.addAll(previouslyEnabledAgents);
515 }
516 utils.setEnabledTrustAgents(discoveredAgents, userId);
517 Settings.Secure.putIntForUser(mContext.getContentResolver(),
518 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
519 }
520
521 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
522 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
523 0 /* flags */, userId);
524 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
525 for (ResolveInfo resolveInfo : resolveInfos) {
526 if (resolveInfo.serviceInfo == null) continue;
527 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
528 String packageName = resolveInfo.serviceInfo.packageName;
529 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
530 != PackageManager.PERMISSION_GRANTED) {
531 ComponentName name = getComponentName(resolveInfo);
532 Log.w(TAG, "Skipping agent " + name + " because package does not have"
533 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
534 continue;
535 }
536 allowedAgents.add(resolveInfo);
537 }
538 return allowedAgents;
539 }
540
Adrian Roos82142c22014-03-27 14:56:59 +0100541 // Agent dispatch and aggregation
542
543 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700544 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200545 return false;
546 }
Adrian Roos82142c22014-03-27 14:56:59 +0100547 for (int i = 0; i < mActiveAgents.size(); i++) {
548 AgentInfo info = mActiveAgents.valueAt(i);
549 if (info.userId == userId) {
550 if (info.agent.isTrusted()) {
551 return true;
552 }
553 }
554 }
555 return false;
556 }
557
Adrian Roos7861c662014-07-25 15:37:28 +0200558 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700559 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200560 return false;
561 }
562 for (int i = 0; i < mActiveAgents.size(); i++) {
563 AgentInfo info = mActiveAgents.valueAt(i);
564 if (info.userId == userId) {
565 if (info.agent.isManagingTrust()) {
566 return true;
567 }
568 }
569 }
570 return false;
571 }
572
Adrian Roos82142c22014-03-27 14:56:59 +0100573 private void dispatchUnlockAttempt(boolean successful, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800574 if (successful) {
575 mStrongAuthTracker.allowTrustFromUnlock(userId);
576 }
577
Adrian Roos82142c22014-03-27 14:56:59 +0100578 for (int i = 0; i < mActiveAgents.size(); i++) {
579 AgentInfo info = mActiveAgents.valueAt(i);
580 if (info.userId == userId) {
581 info.agent.onUnlockAttempt(successful);
582 }
583 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200584 }
585
Adrian Roos82142c22014-03-27 14:56:59 +0100586 // Listeners
587
588 private void addListener(ITrustListener listener) {
589 for (int i = 0; i < mTrustListeners.size(); i++) {
590 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
591 return;
592 }
593 }
594 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200595 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100596 }
597
598 private void removeListener(ITrustListener listener) {
599 for (int i = 0; i < mTrustListeners.size(); i++) {
600 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700601 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100602 return;
603 }
604 }
605 }
606
Adrian Roos94e15a52015-04-16 12:23:18 -0700607 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800608 if (DEBUG) {
609 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
610 + Integer.toHexString(flags) + ")");
611 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700612 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100613 for (int i = 0; i < mTrustListeners.size(); i++) {
614 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700615 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200616 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200617 Slog.d(TAG, "Removing dead TrustListener.");
618 mTrustListeners.remove(i);
619 i--;
620 } catch (RemoteException e) {
621 Slog.e(TAG, "Exception while notifying TrustListener.", e);
622 }
623 }
624 }
625
626 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800627 if (DEBUG) {
628 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
629 }
Adrian Roos7861c662014-07-25 15:37:28 +0200630 for (int i = 0; i < mTrustListeners.size(); i++) {
631 try {
632 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
633 } catch (DeadObjectException e) {
634 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200635 mTrustListeners.remove(i);
636 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100637 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200638 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100639 }
640 }
641 }
642
Adrian Rooscbe614f2014-10-28 20:16:12 +0100643 // User lifecycle
644
645 @Override
646 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100647 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100648 }
649
650 @Override
651 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100652 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
653 }
654
655 @Override
656 public void onSwitchUser(int userId) {
657 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100658 }
659
Adrian Roos82142c22014-03-27 14:56:59 +0100660 // Plumbing
661
662 private final IBinder mService = new ITrustManager.Stub() {
663 @Override
664 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
665 enforceReportPermission();
666 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
667 .sendToTarget();
668 }
669
670 @Override
671 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
672 enforceReportPermission();
673 // coalesce refresh messages.
674 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
675 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
676 }
677
678 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100679 public void reportKeyguardShowingChanged() throws RemoteException {
680 enforceReportPermission();
681 // coalesce refresh messages.
682 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
683 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
684 }
685
686 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100687 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
688 enforceListenerPermission();
689 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
690 }
691
692 @Override
693 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
694 enforceListenerPermission();
695 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
696 }
697
Adrian Roosbcd07652014-10-22 16:57:16 +0200698 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100699 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200700 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100701 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +0100702
Clara Bayarri078e91b2016-01-15 16:57:35 +0000703 long token = Binder.clearCallingIdentity();
704 try {
705 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
706 userId = resolveProfileParent(userId);
707 }
708 return isDeviceLockedInner(userId);
709 } finally {
710 Binder.restoreCallingIdentity(token);
711 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200712 }
713
Adrian Roos82893682015-04-02 16:17:46 +0200714 @Override
715 public boolean isDeviceSecure(int userId) throws RemoteException {
716 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
717 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +0200718
719 long token = Binder.clearCallingIdentity();
720 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +0000721 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
722 userId = resolveProfileParent(userId);
723 }
Clara Bayarria1771112015-12-18 16:29:18 +0000724 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200725 } finally {
726 Binder.restoreCallingIdentity(token);
727 }
728 }
729
Adrian Roos82142c22014-03-27 14:56:59 +0100730 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200731 mContext.enforceCallingOrSelfPermission(
732 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100733 }
734
735 private void enforceListenerPermission() {
736 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
737 "register trust listener");
738 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200739
740 @Override
741 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
742 mContext.enforceCallingPermission(Manifest.permission.DUMP,
743 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200744 if (isSafeMode()) {
745 fout.println("disabled because the system is in safe mode.");
746 return;
747 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100748 if (!mTrustAgentsCanRun) {
749 fout.println("disabled because the third-party apps can't run yet.");
750 return;
751 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200752 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200753 mHandler.runWithScissors(new Runnable() {
754 @Override
755 public void run() {
756 fout.println("Trust manager state:");
757 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100758 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200759 }
760 }
761 }, 1500);
762 }
763
764 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
765 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
766 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700767 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100768 fout.println("(managed profile)");
769 fout.println(" disabled because switching to this user is not possible.");
770 return;
771 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200772 if (isCurrent) {
773 fout.print(" (current)");
774 }
775 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200776 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100777 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -0700778 fout.print(", strongAuthRequired=" + dumpHex(
779 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200780 fout.println();
781 fout.println(" Enabled agents:");
782 boolean duplicateSimpleNames = false;
783 ArraySet<String> simpleNames = new ArraySet<String>();
784 for (AgentInfo info : mActiveAgents) {
785 if (info.userId != user.id) { continue; }
786 boolean trusted = info.agent.isTrusted();
787 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200788 fout.print(" bound=" + dumpBool(info.agent.isBound()));
789 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200790 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
791 fout.print(", trusted=" + dumpBool(trusted));
792 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200793 if (trusted) {
794 fout.println(" message=\"" + info.agent.getMessage() + "\"");
795 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200796 if (!info.agent.isConnected()) {
797 String restartTime = TrustArchive.formatDuration(
798 info.agent.getScheduledRestartUptimeMillis()
799 - SystemClock.uptimeMillis());
800 fout.println(" restartScheduledAt=" + restartTime);
801 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200802 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
803 duplicateSimpleNames = true;
804 }
805 }
806 fout.println(" Events:");
807 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
808 fout.println();
809 }
810
811 private String dumpBool(boolean b) {
812 return b ? "1" : "0";
813 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700814
815 private String dumpHex(int i) {
816 return "0x" + Integer.toHexString(i);
817 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000818
819 @Override
820 public void setDeviceLockedForUser(int userId, boolean value) {
Clara Bayarri00a9b892016-01-13 16:17:09 +0000821 enforceReportPermission();
Clara Bayarri56878a92015-10-29 15:43:55 +0000822 mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
823 .sendToTarget();
824 }
Adrian Roosc13723f2016-01-12 20:29:03 +0100825
826 @Override
827 public boolean isTrustUsuallyManaged(int userId) {
828 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
829 "query trust state");
830 return isTrustUsuallyManagedInternal(userId);
831 }
Adrian Roos82142c22014-03-27 14:56:59 +0100832 };
833
Adrian Roosc13723f2016-01-12 20:29:03 +0100834 private boolean isTrustUsuallyManagedInternal(int userId) {
835 synchronized (mTrustUsuallyManagedForUser) {
836 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
837 if (i >= 0) {
838 return mTrustUsuallyManagedForUser.valueAt(i);
839 }
840 }
841 // It's not in memory yet, get the value from persisted storage instead
842 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
843 synchronized (mTrustUsuallyManagedForUser) {
844 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
845 if (i >= 0) {
846 // Someone set the trust usually managed in the mean time. Better use that.
847 return mTrustUsuallyManagedForUser.valueAt(i);
848 } else {
849 // .. otherwise it's safe to cache the fetched value now.
850 mTrustUsuallyManagedForUser.put(userId, persistedValue);
851 return persistedValue;
852 }
853 }
854 }
855
Adrian Roosbcd07652014-10-22 16:57:16 +0200856 private int resolveProfileParent(int userId) {
857 long identity = Binder.clearCallingIdentity();
858 try {
859 UserInfo parent = mUserManager.getProfileParent(userId);
860 if (parent != null) {
861 return parent.getUserHandle().getIdentifier();
862 }
863 return userId;
864 } finally {
865 Binder.restoreCallingIdentity(identity);
866 }
867 }
868
Adrian Roos82142c22014-03-27 14:56:59 +0100869 private final Handler mHandler = new Handler() {
870 @Override
871 public void handleMessage(Message msg) {
872 switch (msg.what) {
873 case MSG_REGISTER_LISTENER:
874 addListener((ITrustListener) msg.obj);
875 break;
876 case MSG_UNREGISTER_LISTENER:
877 removeListener((ITrustListener) msg.obj);
878 break;
879 case MSG_DISPATCH_UNLOCK_ATTEMPT:
880 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
881 break;
882 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700883 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100884 // This is also called when the security mode of a user changes.
885 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100886 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100887 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100888 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100889 break;
890 case MSG_START_USER:
891 case MSG_CLEANUP_USER:
892 refreshAgentList(msg.arg1);
893 break;
894 case MSG_SWITCH_USER:
895 mCurrentUser = msg.arg1;
896 refreshDeviceLockedForUser(UserHandle.USER_ALL);
897 break;
Clara Bayarri56878a92015-10-29 15:43:55 +0000898 case MSG_SET_DEVICE_LOCKED:
899 setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
900 break;
Adrian Roosc13723f2016-01-12 20:29:03 +0100901 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
902 SparseBooleanArray usuallyManaged;
903 synchronized (mTrustUsuallyManagedForUser) {
904 usuallyManaged = mTrustUsuallyManagedForUser.clone();
905 }
906
907 for (int i = 0; i < usuallyManaged.size(); i++) {
908 int userId = usuallyManaged.keyAt(i);
909 boolean value = usuallyManaged.valueAt(i);
910 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
911 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
912 }
913 }
Adrian Roos82142c22014-03-27 14:56:59 +0100914 }
915 }
916 };
917
918 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
919 @Override
920 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700921 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100922 }
923
924 @Override
925 public boolean onPackageChanged(String packageName, int uid, String[] components) {
926 // We're interested in all changes, even if just some components get enabled / disabled.
927 return true;
928 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200929
930 @Override
931 public void onPackageDisappeared(String packageName, int reason) {
932 removeAgentsOfPackage(packageName);
933 }
Adrian Roos82142c22014-03-27 14:56:59 +0100934 };
Adrian Roosca36b952014-05-16 18:52:29 +0200935
Adrian Roos9dbe1902014-08-13 18:25:52 +0200936 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200937
938 @Override
939 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200940 String action = intent.getAction();
941 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700942 refreshAgentList(getSendingUserId());
943 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200944 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100945 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200946 if (userId > 0) {
947 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200948 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100949 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
950 int userId = getUserId(intent);
951 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100952 synchronized (mUserIsTrusted) {
953 mUserIsTrusted.delete(userId);
954 }
955 synchronized (mDeviceLockedForUser) {
956 mDeviceLockedForUser.delete(userId);
957 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100958 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100959 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100960 }
961 }
962 }
963
964 private int getUserId(Intent intent) {
965 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
966 if (userId > 0) {
967 return userId;
968 } else {
969 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
970 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200971 }
972 }
973
974 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200975 IntentFilter filter = new IntentFilter();
976 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
977 filter.addAction(Intent.ACTION_USER_PRESENT);
Adrian Roos3870d452014-09-05 18:22:28 +0200978 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100979 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200980 context.registerReceiverAsUser(this,
981 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200982 filter,
Adrian Roosca36b952014-05-16 18:52:29 +0200983 null /* permission */,
984 null /* scheduler */);
985 }
986 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800987
988 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
989
990 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
991
992 public StrongAuthTracker(Context context) {
993 super(context);
994 }
995
996 @Override
997 public void onStrongAuthRequiredChanged(int userId) {
998 mStartFromSuccessfulUnlock.delete(userId);
999
1000 if (DEBUG) {
1001 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1002 + " trustAllowed=" + isTrustAllowedForUser(userId)
1003 + " agentsCanRun=" + canAgentsRunForUser(userId));
1004 }
1005
1006 refreshAgentList(userId);
1007
1008 // The list of active trust agents may not have changed, if there was a previous call
1009 // to allowTrustFromUnlock, so we update the trust here too.
1010 updateTrust(userId, 0 /* flags */);
1011 }
1012
1013 boolean canAgentsRunForUser(int userId) {
1014 return mStartFromSuccessfulUnlock.get(userId)
1015 || super.isTrustAllowedForUser(userId);
1016 }
1017
1018 /**
1019 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1020 * changes again. Must only be called when we know about a successful unlock already
1021 * before the underlying StrongAuthTracker.
1022 *
1023 * Note that this only changes whether trust agents can be started, not the actual trusted
1024 * value.
1025 */
1026 void allowTrustFromUnlock(int userId) {
1027 if (userId < UserHandle.USER_SYSTEM) {
1028 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1029 }
1030 boolean previous = canAgentsRunForUser(userId);
1031 mStartFromSuccessfulUnlock.put(userId, true);
1032
1033 if (DEBUG) {
1034 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1035 + " trustAllowed=" + isTrustAllowedForUser(userId)
1036 + " agentsCanRun=" + canAgentsRunForUser(userId));
1037 }
1038
1039 if (canAgentsRunForUser(userId) != previous) {
1040 refreshAgentList(userId);
1041 }
1042 }
1043 }
Adrian Roos82142c22014-03-27 14:56:59 +01001044}