blob: 9b96154b40db781a8640cf3d64c83ec21f77f5fb [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;
Nicolas Prevotc6628982016-04-14 10:11:21 +010029import android.app.ActivityManagerNative;
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
Adrian Roos517b3a42016-03-03 14:58:33 -0800107 private 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);
Adrian Roos517b3a42016-03-03 14:58:33 -0800139 mStrongAuthTracker = new StrongAuthTracker(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100140 }
141
142 @Override
143 public void onStart() {
144 publishBinderService(Context.TRUST_SERVICE, mService);
145 }
146
147 @Override
148 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200149 if (isSafeMode()) {
150 // No trust agents in safe mode.
151 return;
152 }
153 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100154 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200155 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700156 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100157 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
158 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700159 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200160 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700161 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100162 }
163 }
164
165 // Agent management
166
167 private static final class AgentInfo {
168 CharSequence label;
169 Drawable icon;
170 ComponentName component; // service that implements ITrustAgent
171 ComponentName settings; // setting to launch to modify agent.
172 TrustAgentWrapper agent;
173 int userId;
174
175 @Override
176 public boolean equals(Object other) {
177 if (!(other instanceof AgentInfo)) {
178 return false;
179 }
180 AgentInfo o = (AgentInfo) other;
181 return component.equals(o.component) && userId == o.userId;
182 }
183
184 @Override
185 public int hashCode() {
186 return component.hashCode() * 31 + userId;
187 }
188 }
189
190 private void updateTrustAll() {
191 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
192 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700193 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100194 }
195 }
196
Adrian Roos94e15a52015-04-16 12:23:18 -0700197 public void updateTrust(int userId, int flags) {
Adrian Roosc13723f2016-01-12 20:29:03 +0100198 boolean managed = aggregateIsTrustManaged(userId);
199 dispatchOnTrustManagedChanged(managed, userId);
200 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
201 && isTrustUsuallyManagedInternal(userId) != managed) {
202 updateTrustUsuallyManaged(userId, managed);
203 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200204 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100205 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200206 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100207 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200208 mUserIsTrusted.put(userId, trusted);
209 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700210 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100211 if (changed) {
212 refreshDeviceLockedForUser(userId);
213 }
Adrian Roos82142c22014-03-27 14:56:59 +0100214 }
215
Adrian Roosc13723f2016-01-12 20:29:03 +0100216 private void updateTrustUsuallyManaged(int userId, boolean managed) {
217 synchronized (mTrustUsuallyManagedForUser) {
218 mTrustUsuallyManagedForUser.put(userId, managed);
219 }
220 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
221 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
222 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
223 mHandler.sendMessageDelayed(
224 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
225 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
226 }
227
Adrian Roos517b3a42016-03-03 14:58:33 -0800228 void refreshAgentList(int userIdOrAll) {
229 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100230 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200231 return;
232 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800233 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
234 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
Adrian Roose681c272014-09-08 14:03:47 +0200235 + " must be USER_ALL or a specific user.", new Throwable("here"));
Adrian Roos517b3a42016-03-03 14:58:33 -0800236 userIdOrAll = UserHandle.USER_ALL;
Adrian Roose681c272014-09-08 14:03:47 +0200237 }
Adrian Roos82142c22014-03-27 14:56:59 +0100238 PackageManager pm = mContext.getPackageManager();
239
Marco Fucci4e68f112014-08-29 12:31:48 -0700240 List<UserInfo> userInfos;
Adrian Roos517b3a42016-03-03 14:58:33 -0800241 if (userIdOrAll == UserHandle.USER_ALL) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700242 userInfos = mUserManager.getUsers(true /* excludeDying */);
243 } else {
244 userInfos = new ArrayList<>();
Adrian Roos517b3a42016-03-03 14:58:33 -0800245 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
Marco Fucci4e68f112014-08-29 12:31:48 -0700246 }
Adrian Roos3870d452014-09-05 18:22:28 +0200247 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100248
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200249 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
250 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100251
252 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100253 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
254 || userInfo.guestToRemove) continue;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700255 if (!userInfo.supportsSwitchToByUser()) continue;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100256 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
Adrian Roos481a6df2014-11-20 19:48:56 +0100257 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
Adrian Roos517b3a42016-03-03 14:58:33 -0800258 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200259 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
260 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700261 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200262 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
263
Adrian Roos82142c22014-03-27 14:56:59 +0100264 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200265 if (enabledAgents == null) {
Adrian Roos82142c22014-03-27 14:56:59 +0100266 continue;
267 }
Adrian Roos3870d452014-09-05 18:22:28 +0200268 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100269 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100270 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100271
Adrian Roos3870d452014-09-05 18:22:28 +0200272 if (!enabledAgents.contains(name)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200273 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700274 List<PersistableBundle> config =
275 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200276 // Disable agent if no features are enabled.
Jim Millere303bf42014-08-26 17:12:29 -0700277 if (config == null || config.isEmpty()) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200278 }
279
Adrian Roos82142c22014-03-27 14:56:59 +0100280 AgentInfo agentInfo = new AgentInfo();
281 agentInfo.component = name;
282 agentInfo.userId = userInfo.id;
283 if (!mActiveAgents.contains(agentInfo)) {
284 agentInfo.label = resolveInfo.loadLabel(pm);
285 agentInfo.icon = resolveInfo.loadIcon(pm);
286 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
287 agentInfo.agent = new TrustAgentWrapper(mContext, this,
288 new Intent().setComponent(name), userInfo.getUserHandle());
289 mActiveAgents.add(agentInfo);
290 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200291 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100292 }
293 }
294 }
295
296 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200297 for (int i = 0; i < obsoleteAgents.size(); i++) {
298 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roos517b3a42016-03-03 14:58:33 -0800299 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
Adrian Roose681c272014-09-08 14:03:47 +0200300 if (info.agent.isManagingTrust()) {
301 trustMayHaveChanged = true;
302 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100303 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200304 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100305 }
Adrian Roos82142c22014-03-27 14:56:59 +0100306 }
307
308 if (trustMayHaveChanged) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800309 if (userIdOrAll == UserHandle.USER_ALL) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100310 updateTrustAll();
311 } else {
Adrian Roos517b3a42016-03-03 14:58:33 -0800312 updateTrust(userIdOrAll, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100313 }
Adrian Roos82142c22014-03-27 14:56:59 +0100314 }
315 }
316
Clara Bayarri56878a92015-10-29 15:43:55 +0000317 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarria1771112015-12-18 16:29:18 +0000318 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
319 synchronized (mDeviceLockedForUser) {
320 mDeviceLockedForUser.put(userId, locked);
Clara Bayarri56878a92015-10-29 15:43:55 +0000321 }
Nicolas Prevotc6628982016-04-14 10:11:21 +0100322 if (locked) {
323 try {
324 ActivityManagerNative.getDefault().notifyLockedProfile(userId);
325 } catch (RemoteException e) {
326 }
327 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000328 }
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) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800581 if (successful) {
582 mStrongAuthTracker.allowTrustFromUnlock(userId);
583 }
584
Adrian Roos82142c22014-03-27 14:56:59 +0100585 for (int i = 0; i < mActiveAgents.size(); i++) {
586 AgentInfo info = mActiveAgents.valueAt(i);
587 if (info.userId == userId) {
588 info.agent.onUnlockAttempt(successful);
589 }
590 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200591 }
592
Adrian Roos82142c22014-03-27 14:56:59 +0100593 // Listeners
594
595 private void addListener(ITrustListener listener) {
596 for (int i = 0; i < mTrustListeners.size(); i++) {
597 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
598 return;
599 }
600 }
601 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200602 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100603 }
604
605 private void removeListener(ITrustListener listener) {
606 for (int i = 0; i < mTrustListeners.size(); i++) {
607 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700608 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100609 return;
610 }
611 }
612 }
613
Adrian Roos94e15a52015-04-16 12:23:18 -0700614 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800615 if (DEBUG) {
616 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
617 + Integer.toHexString(flags) + ")");
618 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700619 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100620 for (int i = 0; i < mTrustListeners.size(); i++) {
621 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700622 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200623 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200624 Slog.d(TAG, "Removing dead TrustListener.");
625 mTrustListeners.remove(i);
626 i--;
627 } catch (RemoteException e) {
628 Slog.e(TAG, "Exception while notifying TrustListener.", e);
629 }
630 }
631 }
632
633 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800634 if (DEBUG) {
635 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
636 }
Adrian Roos7861c662014-07-25 15:37:28 +0200637 for (int i = 0; i < mTrustListeners.size(); i++) {
638 try {
639 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
640 } catch (DeadObjectException e) {
641 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200642 mTrustListeners.remove(i);
643 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100644 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200645 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100646 }
647 }
648 }
649
Adrian Rooscbe614f2014-10-28 20:16:12 +0100650 // User lifecycle
651
652 @Override
653 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100654 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100655 }
656
657 @Override
658 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100659 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
660 }
661
662 @Override
663 public void onSwitchUser(int userId) {
664 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100665 }
666
Adrian Roos82142c22014-03-27 14:56:59 +0100667 // Plumbing
668
669 private final IBinder mService = new ITrustManager.Stub() {
670 @Override
671 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
672 enforceReportPermission();
673 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
674 .sendToTarget();
675 }
676
677 @Override
678 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
679 enforceReportPermission();
680 // coalesce refresh messages.
681 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
682 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
683 }
684
685 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100686 public void reportKeyguardShowingChanged() throws RemoteException {
687 enforceReportPermission();
688 // coalesce refresh messages.
689 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
690 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
691 }
692
693 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100694 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
695 enforceListenerPermission();
696 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
697 }
698
699 @Override
700 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
701 enforceListenerPermission();
702 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
703 }
704
Adrian Roosbcd07652014-10-22 16:57:16 +0200705 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100706 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200707 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100708 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +0100709
Clara Bayarri078e91b2016-01-15 16:57:35 +0000710 long token = Binder.clearCallingIdentity();
711 try {
712 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
713 userId = resolveProfileParent(userId);
714 }
715 return isDeviceLockedInner(userId);
716 } finally {
717 Binder.restoreCallingIdentity(token);
718 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200719 }
720
Adrian Roos82893682015-04-02 16:17:46 +0200721 @Override
722 public boolean isDeviceSecure(int userId) throws RemoteException {
723 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
724 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +0200725
726 long token = Binder.clearCallingIdentity();
727 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +0000728 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
729 userId = resolveProfileParent(userId);
730 }
Clara Bayarria1771112015-12-18 16:29:18 +0000731 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200732 } finally {
733 Binder.restoreCallingIdentity(token);
734 }
735 }
736
Adrian Roos82142c22014-03-27 14:56:59 +0100737 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200738 mContext.enforceCallingOrSelfPermission(
739 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100740 }
741
742 private void enforceListenerPermission() {
743 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
744 "register trust listener");
745 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200746
747 @Override
748 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
749 mContext.enforceCallingPermission(Manifest.permission.DUMP,
750 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200751 if (isSafeMode()) {
752 fout.println("disabled because the system is in safe mode.");
753 return;
754 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100755 if (!mTrustAgentsCanRun) {
756 fout.println("disabled because the third-party apps can't run yet.");
757 return;
758 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200759 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200760 mHandler.runWithScissors(new Runnable() {
761 @Override
762 public void run() {
763 fout.println("Trust manager state:");
764 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100765 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200766 }
767 }
768 }, 1500);
769 }
770
771 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
772 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
773 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700774 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100775 fout.println("(managed profile)");
776 fout.println(" disabled because switching to this user is not possible.");
777 return;
778 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200779 if (isCurrent) {
780 fout.print(" (current)");
781 }
782 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200783 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100784 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -0700785 fout.print(", strongAuthRequired=" + dumpHex(
786 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200787 fout.println();
788 fout.println(" Enabled agents:");
789 boolean duplicateSimpleNames = false;
790 ArraySet<String> simpleNames = new ArraySet<String>();
791 for (AgentInfo info : mActiveAgents) {
792 if (info.userId != user.id) { continue; }
793 boolean trusted = info.agent.isTrusted();
794 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200795 fout.print(" bound=" + dumpBool(info.agent.isBound()));
796 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200797 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
798 fout.print(", trusted=" + dumpBool(trusted));
799 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200800 if (trusted) {
801 fout.println(" message=\"" + info.agent.getMessage() + "\"");
802 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200803 if (!info.agent.isConnected()) {
804 String restartTime = TrustArchive.formatDuration(
805 info.agent.getScheduledRestartUptimeMillis()
806 - SystemClock.uptimeMillis());
807 fout.println(" restartScheduledAt=" + restartTime);
808 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200809 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
810 duplicateSimpleNames = true;
811 }
812 }
813 fout.println(" Events:");
814 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
815 fout.println();
816 }
817
818 private String dumpBool(boolean b) {
819 return b ? "1" : "0";
820 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700821
822 private String dumpHex(int i) {
823 return "0x" + Integer.toHexString(i);
824 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000825
826 @Override
827 public void setDeviceLockedForUser(int userId, boolean value) {
Clara Bayarri00a9b892016-01-13 16:17:09 +0000828 enforceReportPermission();
Clara Bayarri56878a92015-10-29 15:43:55 +0000829 mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
830 .sendToTarget();
831 }
Adrian Roosc13723f2016-01-12 20:29:03 +0100832
833 @Override
834 public boolean isTrustUsuallyManaged(int userId) {
835 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
836 "query trust state");
837 return isTrustUsuallyManagedInternal(userId);
838 }
Adrian Roos82142c22014-03-27 14:56:59 +0100839 };
840
Adrian Roosc13723f2016-01-12 20:29:03 +0100841 private boolean isTrustUsuallyManagedInternal(int userId) {
842 synchronized (mTrustUsuallyManagedForUser) {
843 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
844 if (i >= 0) {
845 return mTrustUsuallyManagedForUser.valueAt(i);
846 }
847 }
848 // It's not in memory yet, get the value from persisted storage instead
849 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
850 synchronized (mTrustUsuallyManagedForUser) {
851 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
852 if (i >= 0) {
853 // Someone set the trust usually managed in the mean time. Better use that.
854 return mTrustUsuallyManagedForUser.valueAt(i);
855 } else {
856 // .. otherwise it's safe to cache the fetched value now.
857 mTrustUsuallyManagedForUser.put(userId, persistedValue);
858 return persistedValue;
859 }
860 }
861 }
862
Adrian Roosbcd07652014-10-22 16:57:16 +0200863 private int resolveProfileParent(int userId) {
864 long identity = Binder.clearCallingIdentity();
865 try {
866 UserInfo parent = mUserManager.getProfileParent(userId);
867 if (parent != null) {
868 return parent.getUserHandle().getIdentifier();
869 }
870 return userId;
871 } finally {
872 Binder.restoreCallingIdentity(identity);
873 }
874 }
875
Adrian Roos82142c22014-03-27 14:56:59 +0100876 private final Handler mHandler = new Handler() {
877 @Override
878 public void handleMessage(Message msg) {
879 switch (msg.what) {
880 case MSG_REGISTER_LISTENER:
881 addListener((ITrustListener) msg.obj);
882 break;
883 case MSG_UNREGISTER_LISTENER:
884 removeListener((ITrustListener) msg.obj);
885 break;
886 case MSG_DISPATCH_UNLOCK_ATTEMPT:
887 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
888 break;
889 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700890 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100891 // This is also called when the security mode of a user changes.
892 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100893 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100894 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100895 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100896 break;
897 case MSG_START_USER:
898 case MSG_CLEANUP_USER:
899 refreshAgentList(msg.arg1);
900 break;
901 case MSG_SWITCH_USER:
902 mCurrentUser = msg.arg1;
903 refreshDeviceLockedForUser(UserHandle.USER_ALL);
904 break;
Clara Bayarri56878a92015-10-29 15:43:55 +0000905 case MSG_SET_DEVICE_LOCKED:
906 setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
907 break;
Adrian Roosc13723f2016-01-12 20:29:03 +0100908 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
909 SparseBooleanArray usuallyManaged;
910 synchronized (mTrustUsuallyManagedForUser) {
911 usuallyManaged = mTrustUsuallyManagedForUser.clone();
912 }
913
914 for (int i = 0; i < usuallyManaged.size(); i++) {
915 int userId = usuallyManaged.keyAt(i);
916 boolean value = usuallyManaged.valueAt(i);
917 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
918 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
919 }
920 }
Adrian Roos82142c22014-03-27 14:56:59 +0100921 }
922 }
923 };
924
925 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
926 @Override
927 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700928 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100929 }
930
931 @Override
932 public boolean onPackageChanged(String packageName, int uid, String[] components) {
933 // We're interested in all changes, even if just some components get enabled / disabled.
934 return true;
935 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200936
937 @Override
938 public void onPackageDisappeared(String packageName, int reason) {
939 removeAgentsOfPackage(packageName);
940 }
Adrian Roos82142c22014-03-27 14:56:59 +0100941 };
Adrian Roosca36b952014-05-16 18:52:29 +0200942
Adrian Roos9dbe1902014-08-13 18:25:52 +0200943 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200944
945 @Override
946 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200947 String action = intent.getAction();
948 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700949 refreshAgentList(getSendingUserId());
950 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200951 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100952 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200953 if (userId > 0) {
954 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200955 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100956 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
957 int userId = getUserId(intent);
958 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100959 synchronized (mUserIsTrusted) {
960 mUserIsTrusted.delete(userId);
961 }
962 synchronized (mDeviceLockedForUser) {
963 mDeviceLockedForUser.delete(userId);
964 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100965 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100966 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100967 }
968 }
969 }
970
971 private int getUserId(Intent intent) {
972 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
973 if (userId > 0) {
974 return userId;
975 } else {
976 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
977 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200978 }
979 }
980
981 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200982 IntentFilter filter = new IntentFilter();
983 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
984 filter.addAction(Intent.ACTION_USER_PRESENT);
Adrian Roos3870d452014-09-05 18:22:28 +0200985 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100986 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200987 context.registerReceiverAsUser(this,
988 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200989 filter,
Adrian Roosca36b952014-05-16 18:52:29 +0200990 null /* permission */,
991 null /* scheduler */);
992 }
993 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800994
995 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
996
997 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
998
999 public StrongAuthTracker(Context context) {
1000 super(context);
1001 }
1002
1003 @Override
1004 public void onStrongAuthRequiredChanged(int userId) {
1005 mStartFromSuccessfulUnlock.delete(userId);
1006
1007 if (DEBUG) {
1008 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1009 + " trustAllowed=" + isTrustAllowedForUser(userId)
1010 + " agentsCanRun=" + canAgentsRunForUser(userId));
1011 }
1012
1013 refreshAgentList(userId);
1014
1015 // The list of active trust agents may not have changed, if there was a previous call
1016 // to allowTrustFromUnlock, so we update the trust here too.
1017 updateTrust(userId, 0 /* flags */);
1018 }
1019
1020 boolean canAgentsRunForUser(int userId) {
1021 return mStartFromSuccessfulUnlock.get(userId)
1022 || super.isTrustAllowedForUser(userId);
1023 }
1024
1025 /**
1026 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1027 * changes again. Must only be called when we know about a successful unlock already
1028 * before the underlying StrongAuthTracker.
1029 *
1030 * Note that this only changes whether trust agents can be started, not the actual trusted
1031 * value.
1032 */
1033 void allowTrustFromUnlock(int userId) {
1034 if (userId < UserHandle.USER_SYSTEM) {
1035 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1036 }
1037 boolean previous = canAgentsRunForUser(userId);
1038 mStartFromSuccessfulUnlock.put(userId, true);
1039
1040 if (DEBUG) {
1041 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1042 + " trustAllowed=" + isTrustAllowedForUser(userId)
1043 + " agentsCanRun=" + canAgentsRunForUser(userId));
1044 }
1045
1046 if (canAgentsRunForUser(userId) != previous) {
1047 refreshAgentList(userId);
1048 }
1049 }
1050 }
Adrian Roos82142c22014-03-27 14:56:59 +01001051}