blob: c1868a4566411d061f77db909abbe6379c3a6879 [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 Roos68771eb2016-05-03 14:02:36 -070056import android.os.storage.StorageManager;
Adrian Roos3870d452014-09-05 18:22:28 +020057import android.provider.Settings;
Adrian Roos82142c22014-03-27 14:56:59 +010058import android.service.trust.TrustAgentService;
59import android.util.ArraySet;
60import android.util.AttributeSet;
Adrian Roos18ea8932014-05-28 14:53:06 +020061import android.util.Log;
Adrian Roos82142c22014-03-27 14:56:59 +010062import android.util.Slog;
Adrian Roos7046bfd2014-05-16 21:20:54 +020063import android.util.SparseBooleanArray;
Adrian Roos82142c22014-03-27 14:56:59 +010064import android.util.Xml;
Adrian Roos481a6df2014-11-20 19:48:56 +010065import android.view.IWindowManager;
Adrian Roos50bfeec2014-11-20 16:21:11 +010066import android.view.WindowManagerGlobal;
Adrian Roos82142c22014-03-27 14:56:59 +010067
Adrian Roos7a4f3d42014-05-02 12:12:20 +020068import java.io.FileDescriptor;
Adrian Roos82142c22014-03-27 14:56:59 +010069import java.io.IOException;
Adrian Roos7a4f3d42014-05-02 12:12:20 +020070import java.io.PrintWriter;
Adrian Roos82142c22014-03-27 14:56:59 +010071import java.util.ArrayList;
72import java.util.List;
73
74/**
75 * Manages trust agents and trust listeners.
76 *
77 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
78 * of each user and notifies them about events that are relevant to them.
79 * It start and stops them based on the value of
80 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
81 *
82 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
83 * trust state changes for any user.
84 *
85 * Trust state and the setting of enabled agents is kept per user and each user has its own
86 * instance of a {@link android.service.trust.TrustAgentService}.
87 */
88public class TrustManagerService extends SystemService {
89
90 private static final boolean DEBUG = false;
91 private static final String TAG = "TrustManagerService";
92
93 private static final Intent TRUST_AGENT_INTENT =
94 new Intent(TrustAgentService.SERVICE_INTERFACE);
Adrian Roos18ea8932014-05-28 14:53:06 +020095 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
Adrian Roos82142c22014-03-27 14:56:59 +010096
97 private static final int MSG_REGISTER_LISTENER = 1;
98 private static final int MSG_UNREGISTER_LISTENER = 2;
99 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
100 private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
Adrian Roos481a6df2014-11-20 19:48:56 +0100101 private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
102 private static final int MSG_START_USER = 7;
103 private static final int MSG_CLEANUP_USER = 8;
104 private static final int MSG_SWITCH_USER = 9;
Clara Bayarri56878a92015-10-29 15:43:55 +0000105 private static final int MSG_SET_DEVICE_LOCKED = 10;
Adrian Roosc13723f2016-01-12 20:29:03 +0100106 private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 11;
Adrian Roos68771eb2016-05-03 14:02:36 -0700107 private static final int MSG_UNLOCK_USER = 12;
Adrian Roosc13723f2016-01-12 20:29:03 +0100108
Adrian Roos517b3a42016-03-03 14:58:33 -0800109 private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
Adrian Roos82142c22014-03-27 14:56:59 +0100110
Adrian Roosb5e47222015-08-14 15:53:06 -0700111 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
112 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
Adrian Roos9dbe1902014-08-13 18:25:52 +0200113 private final Receiver mReceiver = new Receiver();
Adrian Roosb5e47222015-08-14 15:53:06 -0700114
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200115 /* package */ final TrustArchive mArchive = new TrustArchive();
Adrian Roos82142c22014-03-27 14:56:59 +0100116 private final Context mContext;
Adrian Roos3870d452014-09-05 18:22:28 +0200117 private final LockPatternUtils mLockPatternUtils;
Adrian Roosbcd07652014-10-22 16:57:16 +0200118 private final UserManager mUserManager;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100119 private final ActivityManager mActivityManager;
Adrian Roos82142c22014-03-27 14:56:59 +0100120
Adrian Roosbcd07652014-10-22 16:57:16 +0200121 @GuardedBy("mUserIsTrusted")
122 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
Adrian Roos82142c22014-03-27 14:56:59 +0100123
Adrian Roos481a6df2014-11-20 19:48:56 +0100124 @GuardedBy("mDeviceLockedForUser")
125 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
126
Adrian Roosc13723f2016-01-12 20:29:03 +0100127 @GuardedBy("mDeviceLockedForUser")
128 private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
129
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800130 private final StrongAuthTracker mStrongAuthTracker;
131
Adrian Rooscbe614f2014-10-28 20:16:12 +0100132 private boolean mTrustAgentsCanRun = false;
Xiaohui Chen09e02912015-08-05 09:44:56 -0700133 private int mCurrentUser = UserHandle.USER_SYSTEM;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100134
Adrian Roos82142c22014-03-27 14:56:59 +0100135 public TrustManagerService(Context context) {
136 super(context);
137 mContext = context;
138 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100139 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Adrian Roos3870d452014-09-05 18:22:28 +0200140 mLockPatternUtils = new LockPatternUtils(context);
Adrian Roos517b3a42016-03-03 14:58:33 -0800141 mStrongAuthTracker = new StrongAuthTracker(context);
Adrian Roos82142c22014-03-27 14:56:59 +0100142 }
143
144 @Override
145 public void onStart() {
146 publishBinderService(Context.TRUST_SERVICE, mService);
147 }
148
149 @Override
150 public void onBootPhase(int phase) {
Adrian Roos49d53452014-10-24 15:48:39 +0200151 if (isSafeMode()) {
152 // No trust agents in safe mode.
153 return;
154 }
155 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Adrian Roos82142c22014-03-27 14:56:59 +0100156 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
Adrian Roos9dbe1902014-08-13 18:25:52 +0200157 mReceiver.register(mContext);
Adrian Roosb5e47222015-08-14 15:53:06 -0700158 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100159 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
160 mTrustAgentsCanRun = true;
Marco Fucci4e68f112014-08-29 12:31:48 -0700161 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos49d53452014-10-24 15:48:39 +0200162 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700163 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
Adrian Roos82142c22014-03-27 14:56:59 +0100164 }
165 }
166
167 // Agent management
168
169 private static final class AgentInfo {
170 CharSequence label;
171 Drawable icon;
172 ComponentName component; // service that implements ITrustAgent
173 ComponentName settings; // setting to launch to modify agent.
174 TrustAgentWrapper agent;
175 int userId;
176
177 @Override
178 public boolean equals(Object other) {
179 if (!(other instanceof AgentInfo)) {
180 return false;
181 }
182 AgentInfo o = (AgentInfo) other;
183 return component.equals(o.component) && userId == o.userId;
184 }
185
186 @Override
187 public int hashCode() {
188 return component.hashCode() * 31 + userId;
189 }
190 }
191
192 private void updateTrustAll() {
193 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
194 for (UserInfo userInfo : userInfos) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700195 updateTrust(userInfo.id, 0);
Adrian Roos82142c22014-03-27 14:56:59 +0100196 }
197 }
198
Adrian Roos94e15a52015-04-16 12:23:18 -0700199 public void updateTrust(int userId, int flags) {
Adrian Roosc13723f2016-01-12 20:29:03 +0100200 boolean managed = aggregateIsTrustManaged(userId);
201 dispatchOnTrustManagedChanged(managed, userId);
202 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
203 && isTrustUsuallyManagedInternal(userId) != managed) {
204 updateTrustUsuallyManaged(userId, managed);
205 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200206 boolean trusted = aggregateIsTrusted(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100207 boolean changed;
Adrian Roosbcd07652014-10-22 16:57:16 +0200208 synchronized (mUserIsTrusted) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100209 changed = mUserIsTrusted.get(userId) != trusted;
Adrian Roosbcd07652014-10-22 16:57:16 +0200210 mUserIsTrusted.put(userId, trusted);
211 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700212 dispatchOnTrustChanged(trusted, userId, flags);
Adrian Roos481a6df2014-11-20 19:48:56 +0100213 if (changed) {
214 refreshDeviceLockedForUser(userId);
215 }
Adrian Roos82142c22014-03-27 14:56:59 +0100216 }
217
Adrian Roosc13723f2016-01-12 20:29:03 +0100218 private void updateTrustUsuallyManaged(int userId, boolean managed) {
219 synchronized (mTrustUsuallyManagedForUser) {
220 mTrustUsuallyManagedForUser.put(userId, managed);
221 }
222 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
223 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
224 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
225 mHandler.sendMessageDelayed(
226 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
227 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
228 }
229
Adrian Roos517b3a42016-03-03 14:58:33 -0800230 void refreshAgentList(int userIdOrAll) {
231 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
Adrian Rooscbe614f2014-10-28 20:16:12 +0100232 if (!mTrustAgentsCanRun) {
Adrian Roos49d53452014-10-24 15:48:39 +0200233 return;
234 }
Adrian Roos517b3a42016-03-03 14:58:33 -0800235 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
236 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
Adrian Roose681c272014-09-08 14:03:47 +0200237 + " must be USER_ALL or a specific user.", new Throwable("here"));
Adrian Roos517b3a42016-03-03 14:58:33 -0800238 userIdOrAll = UserHandle.USER_ALL;
Adrian Roose681c272014-09-08 14:03:47 +0200239 }
Adrian Roos82142c22014-03-27 14:56:59 +0100240 PackageManager pm = mContext.getPackageManager();
241
Marco Fucci4e68f112014-08-29 12:31:48 -0700242 List<UserInfo> userInfos;
Adrian Roos517b3a42016-03-03 14:58:33 -0800243 if (userIdOrAll == UserHandle.USER_ALL) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700244 userInfos = mUserManager.getUsers(true /* excludeDying */);
245 } else {
246 userInfos = new ArrayList<>();
Adrian Roos517b3a42016-03-03 14:58:33 -0800247 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
Marco Fucci4e68f112014-08-29 12:31:48 -0700248 }
Adrian Roos3870d452014-09-05 18:22:28 +0200249 LockPatternUtils lockPatternUtils = mLockPatternUtils;
Adrian Roos82142c22014-03-27 14:56:59 +0100250
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200251 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
252 obsoleteAgents.addAll(mActiveAgents);
Adrian Roos82142c22014-03-27 14:56:59 +0100253
254 for (UserInfo userInfo : userInfos) {
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100255 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
256 || userInfo.guestToRemove) continue;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700257 if (!userInfo.supportsSwitchToByUser()) continue;
Adrian Roos68771eb2016-05-03 14:02:36 -0700258 if (!StorageManager.isUserKeyUnlocked(userInfo.id)) continue;
Adrian Rooscbe614f2014-10-28 20:16:12 +0100259 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
Adrian Roos481a6df2014-11-20 19:48:56 +0100260 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
Adrian Roos517b3a42016-03-03 14:58:33 -0800261 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200262 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
263 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
Jim Miller604e7552014-07-18 19:00:02 -0700264 final boolean disableTrustAgents =
Adrian Roosca36b952014-05-16 18:52:29 +0200265 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
266
Adrian Roos82142c22014-03-27 14:56:59 +0100267 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200268 if (enabledAgents == null) {
Adrian Roos82142c22014-03-27 14:56:59 +0100269 continue;
270 }
Adrian Roos3870d452014-09-05 18:22:28 +0200271 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
Adrian Roos82142c22014-03-27 14:56:59 +0100272 for (ResolveInfo resolveInfo : resolveInfos) {
Adrian Roos82142c22014-03-27 14:56:59 +0100273 ComponentName name = getComponentName(resolveInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100274
Adrian Roos3870d452014-09-05 18:22:28 +0200275 if (!enabledAgents.contains(name)) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200276 if (disableTrustAgents) {
Jim Millere303bf42014-08-26 17:12:29 -0700277 List<PersistableBundle> config =
278 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
Adrian Roos8f211582014-07-29 15:09:57 +0200279 // Disable agent if no features are enabled.
Jim Millere303bf42014-08-26 17:12:29 -0700280 if (config == null || config.isEmpty()) continue;
Adrian Roos8f211582014-07-29 15:09:57 +0200281 }
282
Adrian Roos82142c22014-03-27 14:56:59 +0100283 AgentInfo agentInfo = new AgentInfo();
284 agentInfo.component = name;
285 agentInfo.userId = userInfo.id;
286 if (!mActiveAgents.contains(agentInfo)) {
287 agentInfo.label = resolveInfo.loadLabel(pm);
288 agentInfo.icon = resolveInfo.loadIcon(pm);
289 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
290 agentInfo.agent = new TrustAgentWrapper(mContext, this,
291 new Intent().setComponent(name), userInfo.getUserHandle());
292 mActiveAgents.add(agentInfo);
293 } else {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200294 obsoleteAgents.remove(agentInfo);
Adrian Roos82142c22014-03-27 14:56:59 +0100295 }
296 }
297 }
298
299 boolean trustMayHaveChanged = false;
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200300 for (int i = 0; i < obsoleteAgents.size(); i++) {
301 AgentInfo info = obsoleteAgents.valueAt(i);
Adrian Roos517b3a42016-03-03 14:58:33 -0800302 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
Adrian Roose681c272014-09-08 14:03:47 +0200303 if (info.agent.isManagingTrust()) {
304 trustMayHaveChanged = true;
305 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100306 info.agent.destroy();
Adrian Roose681c272014-09-08 14:03:47 +0200307 mActiveAgents.remove(info);
Adrian Roos82142c22014-03-27 14:56:59 +0100308 }
Adrian Roos82142c22014-03-27 14:56:59 +0100309 }
310
311 if (trustMayHaveChanged) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800312 if (userIdOrAll == UserHandle.USER_ALL) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100313 updateTrustAll();
314 } else {
Adrian Roos517b3a42016-03-03 14:58:33 -0800315 updateTrust(userIdOrAll, 0);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100316 }
Adrian Roos82142c22014-03-27 14:56:59 +0100317 }
318 }
319
Clara Bayarri56878a92015-10-29 15:43:55 +0000320 public void setDeviceLockedForUser(int userId, boolean locked) {
Clara Bayarria1771112015-12-18 16:29:18 +0000321 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
322 synchronized (mDeviceLockedForUser) {
323 mDeviceLockedForUser.put(userId, locked);
Clara Bayarri56878a92015-10-29 15:43:55 +0000324 }
Nicolas Prevotc6628982016-04-14 10:11:21 +0100325 if (locked) {
326 try {
327 ActivityManagerNative.getDefault().notifyLockedProfile(userId);
328 } catch (RemoteException e) {
329 }
330 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000331 }
332 }
333
Adrian Roos481a6df2014-11-20 19:48:56 +0100334 boolean isDeviceLockedInner(int userId) {
335 synchronized (mDeviceLockedForUser) {
336 return mDeviceLockedForUser.get(userId, true);
337 }
338 }
339
340 private void refreshDeviceLockedForUser(int userId) {
Xiaohui Chen09e02912015-08-05 09:44:56 -0700341 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100342 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
Adrian Roos481a6df2014-11-20 19:48:56 +0100343 + " must be USER_ALL or a specific user.", new Throwable("here"));
344 userId = UserHandle.USER_ALL;
345 }
346
347 List<UserInfo> userInfos;
348 if (userId == UserHandle.USER_ALL) {
349 userInfos = mUserManager.getUsers(true /* excludeDying */);
350 } else {
351 userInfos = new ArrayList<>();
352 userInfos.add(mUserManager.getUserInfo(userId));
353 }
354
355 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
356
357 for (int i = 0; i < userInfos.size(); i++) {
358 UserInfo info = userInfos.get(i);
359
360 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700361 || !info.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100362 continue;
363 }
364
365 int id = info.id;
366 boolean secure = mLockPatternUtils.isSecure(id);
367 boolean trusted = aggregateIsTrusted(id);
368 boolean showingKeyguard = true;
369 if (mCurrentUser == id) {
370 try {
371 showingKeyguard = wm.isKeyguardLocked();
372 } catch (RemoteException e) {
373 }
374 }
375 boolean deviceLocked = secure && showingKeyguard && !trusted;
376
377 boolean changed;
378 synchronized (mDeviceLockedForUser) {
379 changed = isDeviceLockedInner(id) != deviceLocked;
380 mDeviceLockedForUser.put(id, deviceLocked);
381 }
382 if (changed) {
383 dispatchDeviceLocked(id, deviceLocked);
384 }
385 }
386 }
387
388 private void dispatchDeviceLocked(int userId, boolean isLocked) {
389 for (int i = 0; i < mActiveAgents.size(); i++) {
390 AgentInfo agent = mActiveAgents.valueAt(i);
391 if (agent.userId == userId) {
392 if (isLocked) {
393 agent.agent.onDeviceLocked();
394 } else{
395 agent.agent.onDeviceUnlocked();
396 }
397 }
398 }
399 }
400
Marco Fucci4e68f112014-08-29 12:31:48 -0700401 void updateDevicePolicyFeatures() {
Adrian Roos8f211582014-07-29 15:09:57 +0200402 for (int i = 0; i < mActiveAgents.size(); i++) {
403 AgentInfo info = mActiveAgents.valueAt(i);
404 if (info.agent.isConnected()) {
405 info.agent.updateDevicePolicyFeatures();
406 }
407 }
408 }
409
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200410 private void removeAgentsOfPackage(String packageName) {
411 boolean trustMayHaveChanged = false;
412 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
413 AgentInfo info = mActiveAgents.valueAt(i);
414 if (packageName.equals(info.component.getPackageName())) {
415 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200416 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200417 trustMayHaveChanged = true;
418 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100419 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200420 mActiveAgents.removeAt(i);
421 }
422 }
423 if (trustMayHaveChanged) {
424 updateTrustAll();
425 }
426 }
427
428 public void resetAgent(ComponentName name, int userId) {
429 boolean trustMayHaveChanged = false;
430 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
431 AgentInfo info = mActiveAgents.valueAt(i);
432 if (name.equals(info.component) && userId == info.userId) {
433 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
Adrian Roos7861c662014-07-25 15:37:28 +0200434 if (info.agent.isManagingTrust()) {
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200435 trustMayHaveChanged = true;
436 }
Adrian Roosfc29e0b2014-11-11 12:55:44 +0100437 info.agent.destroy();
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200438 mActiveAgents.removeAt(i);
439 }
440 }
441 if (trustMayHaveChanged) {
Adrian Roos94e15a52015-04-16 12:23:18 -0700442 updateTrust(userId, 0);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200443 }
Marco Fucci4e68f112014-08-29 12:31:48 -0700444 refreshAgentList(userId);
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200445 }
446
Adrian Roos82142c22014-03-27 14:56:59 +0100447 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
448 if (resolveInfo == null || resolveInfo.serviceInfo == null
449 || resolveInfo.serviceInfo.metaData == null) return null;
450 String cn = null;
451 XmlResourceParser parser = null;
452 Exception caughtException = null;
453 try {
454 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
455 TrustAgentService.TRUST_AGENT_META_DATA);
456 if (parser == null) {
457 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
458 return null;
459 }
460 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
461 AttributeSet attrs = Xml.asAttributeSet(parser);
462 int type;
463 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
464 && type != XmlPullParser.START_TAG) {
465 // Drain preamble.
466 }
467 String nodeName = parser.getName();
Adrian Roos7e03dfc2014-05-16 16:06:28 +0200468 if (!"trust-agent".equals(nodeName)) {
469 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
Adrian Roos82142c22014-03-27 14:56:59 +0100470 return null;
471 }
472 TypedArray sa = res
473 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
474 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
475 sa.recycle();
476 } catch (PackageManager.NameNotFoundException e) {
477 caughtException = e;
478 } catch (IOException e) {
479 caughtException = e;
480 } catch (XmlPullParserException e) {
481 caughtException = e;
482 } finally {
483 if (parser != null) parser.close();
484 }
485 if (caughtException != null) {
486 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
487 return null;
488 }
489 if (cn == null) {
490 return null;
491 }
492 if (cn.indexOf('/') < 0) {
493 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
494 }
495 return ComponentName.unflattenFromString(cn);
496 }
497
498 private ComponentName getComponentName(ResolveInfo resolveInfo) {
499 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
500 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
501 }
502
Adrian Roos3870d452014-09-05 18:22:28 +0200503 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
504 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
505 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
506 return;
507 }
508 PackageManager pm = mContext.getPackageManager();
509 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
510 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
511 for (ResolveInfo resolveInfo : resolveInfos) {
512 ComponentName componentName = getComponentName(resolveInfo);
513 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
514 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
515 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
516 + "is not a system package.");
517 continue;
518 }
519 discoveredAgents.add(componentName);
520 }
521
522 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
523 if (previouslyEnabledAgents != null) {
524 discoveredAgents.addAll(previouslyEnabledAgents);
525 }
526 utils.setEnabledTrustAgents(discoveredAgents, userId);
527 Settings.Secure.putIntForUser(mContext.getContentResolver(),
528 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
529 }
530
531 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
532 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
Adrian Roos68771eb2016-05-03 14:02:36 -0700533 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
534 userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200535 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
536 for (ResolveInfo resolveInfo : resolveInfos) {
537 if (resolveInfo.serviceInfo == null) continue;
538 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
539 String packageName = resolveInfo.serviceInfo.packageName;
540 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
541 != PackageManager.PERMISSION_GRANTED) {
542 ComponentName name = getComponentName(resolveInfo);
543 Log.w(TAG, "Skipping agent " + name + " because package does not have"
544 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
545 continue;
546 }
547 allowedAgents.add(resolveInfo);
548 }
549 return allowedAgents;
550 }
551
Adrian Roos82142c22014-03-27 14:56:59 +0100552 // Agent dispatch and aggregation
553
554 private boolean aggregateIsTrusted(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700555 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7046bfd2014-05-16 21:20:54 +0200556 return false;
557 }
Adrian Roos82142c22014-03-27 14:56:59 +0100558 for (int i = 0; i < mActiveAgents.size(); i++) {
559 AgentInfo info = mActiveAgents.valueAt(i);
560 if (info.userId == userId) {
561 if (info.agent.isTrusted()) {
562 return true;
563 }
564 }
565 }
566 return false;
567 }
568
Adrian Roos7861c662014-07-25 15:37:28 +0200569 private boolean aggregateIsTrustManaged(int userId) {
Adrian Roosb5e47222015-08-14 15:53:06 -0700570 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
Adrian Roos7861c662014-07-25 15:37:28 +0200571 return false;
572 }
573 for (int i = 0; i < mActiveAgents.size(); i++) {
574 AgentInfo info = mActiveAgents.valueAt(i);
575 if (info.userId == userId) {
576 if (info.agent.isManagingTrust()) {
577 return true;
578 }
579 }
580 }
581 return false;
582 }
583
Adrian Roos82142c22014-03-27 14:56:59 +0100584 private void dispatchUnlockAttempt(boolean successful, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800585 if (successful) {
586 mStrongAuthTracker.allowTrustFromUnlock(userId);
587 }
588
Adrian Roos82142c22014-03-27 14:56:59 +0100589 for (int i = 0; i < mActiveAgents.size(); i++) {
590 AgentInfo info = mActiveAgents.valueAt(i);
591 if (info.userId == userId) {
592 info.agent.onUnlockAttempt(successful);
593 }
594 }
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200595 }
596
Adrian Roos82142c22014-03-27 14:56:59 +0100597 // Listeners
598
599 private void addListener(ITrustListener listener) {
600 for (int i = 0; i < mTrustListeners.size(); i++) {
601 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
602 return;
603 }
604 }
605 mTrustListeners.add(listener);
Adrian Roos3870d452014-09-05 18:22:28 +0200606 updateTrustAll();
Adrian Roos82142c22014-03-27 14:56:59 +0100607 }
608
609 private void removeListener(ITrustListener listener) {
610 for (int i = 0; i < mTrustListeners.size(); i++) {
611 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
Jay Civelli979a32e2014-07-18 16:47:36 -0700612 mTrustListeners.remove(i);
Adrian Roos82142c22014-03-27 14:56:59 +0100613 return;
614 }
615 }
616 }
617
Adrian Roos94e15a52015-04-16 12:23:18 -0700618 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800619 if (DEBUG) {
620 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
621 + Integer.toHexString(flags) + ")");
622 }
Adrian Roos94e15a52015-04-16 12:23:18 -0700623 if (!enabled) flags = 0;
Adrian Roos82142c22014-03-27 14:56:59 +0100624 for (int i = 0; i < mTrustListeners.size(); i++) {
625 try {
Adrian Roos94e15a52015-04-16 12:23:18 -0700626 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200627 } catch (DeadObjectException e) {
Adrian Roos7861c662014-07-25 15:37:28 +0200628 Slog.d(TAG, "Removing dead TrustListener.");
629 mTrustListeners.remove(i);
630 i--;
631 } catch (RemoteException e) {
632 Slog.e(TAG, "Exception while notifying TrustListener.", e);
633 }
634 }
635 }
636
637 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
Adrian Roos517b3a42016-03-03 14:58:33 -0800638 if (DEBUG) {
639 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
640 }
Adrian Roos7861c662014-07-25 15:37:28 +0200641 for (int i = 0; i < mTrustListeners.size(); i++) {
642 try {
643 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
644 } catch (DeadObjectException e) {
645 Slog.d(TAG, "Removing dead TrustListener.");
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200646 mTrustListeners.remove(i);
647 i--;
Adrian Roos82142c22014-03-27 14:56:59 +0100648 } catch (RemoteException e) {
Adrian Roosa4ba56b2014-05-20 12:56:25 +0200649 Slog.e(TAG, "Exception while notifying TrustListener.", e);
Adrian Roos82142c22014-03-27 14:56:59 +0100650 }
651 }
652 }
653
Adrian Rooscbe614f2014-10-28 20:16:12 +0100654 // User lifecycle
655
656 @Override
657 public void onStartUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100658 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100659 }
660
661 @Override
662 public void onCleanupUser(int userId) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100663 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
664 }
665
666 @Override
667 public void onSwitchUser(int userId) {
668 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
Adrian Rooscbe614f2014-10-28 20:16:12 +0100669 }
670
Adrian Roos68771eb2016-05-03 14:02:36 -0700671 @Override
672 public void onUnlockUser(int userId) {
673 mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
674 }
675
Adrian Roos82142c22014-03-27 14:56:59 +0100676 // Plumbing
677
678 private final IBinder mService = new ITrustManager.Stub() {
679 @Override
680 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
681 enforceReportPermission();
682 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
683 .sendToTarget();
684 }
685
686 @Override
687 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
688 enforceReportPermission();
689 // coalesce refresh messages.
690 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
691 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
692 }
693
694 @Override
Adrian Roos481a6df2014-11-20 19:48:56 +0100695 public void reportKeyguardShowingChanged() throws RemoteException {
696 enforceReportPermission();
697 // coalesce refresh messages.
698 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
699 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
700 }
701
702 @Override
Adrian Roos82142c22014-03-27 14:56:59 +0100703 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
704 enforceListenerPermission();
705 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
706 }
707
708 @Override
709 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
710 enforceListenerPermission();
711 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
712 }
713
Adrian Roosbcd07652014-10-22 16:57:16 +0200714 @Override
Adrian Roos50bfeec2014-11-20 16:21:11 +0100715 public boolean isDeviceLocked(int userId) throws RemoteException {
Adrian Roosbcd07652014-10-22 16:57:16 +0200716 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Adrian Roos50bfeec2014-11-20 16:21:11 +0100717 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
Adrian Roos50bfeec2014-11-20 16:21:11 +0100718
Clara Bayarri078e91b2016-01-15 16:57:35 +0000719 long token = Binder.clearCallingIdentity();
720 try {
721 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
722 userId = resolveProfileParent(userId);
723 }
724 return isDeviceLockedInner(userId);
725 } finally {
726 Binder.restoreCallingIdentity(token);
727 }
Adrian Roosbcd07652014-10-22 16:57:16 +0200728 }
729
Adrian Roos82893682015-04-02 16:17:46 +0200730 @Override
731 public boolean isDeviceSecure(int userId) throws RemoteException {
732 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
733 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
Adrian Roos82893682015-04-02 16:17:46 +0200734
735 long token = Binder.clearCallingIdentity();
736 try {
Clara Bayarri8d35de82016-01-12 17:29:29 +0000737 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
738 userId = resolveProfileParent(userId);
739 }
Clara Bayarria1771112015-12-18 16:29:18 +0000740 return mLockPatternUtils.isSecure(userId);
Adrian Roos82893682015-04-02 16:17:46 +0200741 } finally {
742 Binder.restoreCallingIdentity(token);
743 }
744 }
745
Adrian Roos82142c22014-03-27 14:56:59 +0100746 private void enforceReportPermission() {
Adrian Roos2c12cfa2014-06-25 23:28:53 +0200747 mContext.enforceCallingOrSelfPermission(
748 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
Adrian Roos82142c22014-03-27 14:56:59 +0100749 }
750
751 private void enforceListenerPermission() {
752 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
753 "register trust listener");
754 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200755
756 @Override
757 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
758 mContext.enforceCallingPermission(Manifest.permission.DUMP,
759 "dumping TrustManagerService");
Adrian Roos49d53452014-10-24 15:48:39 +0200760 if (isSafeMode()) {
761 fout.println("disabled because the system is in safe mode.");
762 return;
763 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100764 if (!mTrustAgentsCanRun) {
765 fout.println("disabled because the third-party apps can't run yet.");
766 return;
767 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200768 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200769 mHandler.runWithScissors(new Runnable() {
770 @Override
771 public void run() {
772 fout.println("Trust manager state:");
773 for (UserInfo user : userInfos) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100774 dumpUser(fout, user, user.id == mCurrentUser);
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200775 }
776 }
777 }, 1500);
778 }
779
780 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
781 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
782 user.name, user.id, user.flags);
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700783 if (!user.supportsSwitchToByUser()) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100784 fout.println("(managed profile)");
785 fout.println(" disabled because switching to this user is not possible.");
786 return;
787 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200788 if (isCurrent) {
789 fout.print(" (current)");
790 }
791 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
Adrian Roos7861c662014-07-25 15:37:28 +0200792 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
Adrian Roos481a6df2014-11-20 19:48:56 +0100793 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
Adrian Roosb5e47222015-08-14 15:53:06 -0700794 fout.print(", strongAuthRequired=" + dumpHex(
795 mStrongAuthTracker.getStrongAuthForUser(user.id)));
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200796 fout.println();
797 fout.println(" Enabled agents:");
798 boolean duplicateSimpleNames = false;
799 ArraySet<String> simpleNames = new ArraySet<String>();
800 for (AgentInfo info : mActiveAgents) {
801 if (info.userId != user.id) { continue; }
802 boolean trusted = info.agent.isTrusted();
803 fout.print(" "); fout.println(info.component.flattenToShortString());
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200804 fout.print(" bound=" + dumpBool(info.agent.isBound()));
805 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
Adrian Roos7861c662014-07-25 15:37:28 +0200806 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
807 fout.print(", trusted=" + dumpBool(trusted));
808 fout.println();
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200809 if (trusted) {
810 fout.println(" message=\"" + info.agent.getMessage() + "\"");
811 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200812 if (!info.agent.isConnected()) {
813 String restartTime = TrustArchive.formatDuration(
814 info.agent.getScheduledRestartUptimeMillis()
815 - SystemClock.uptimeMillis());
816 fout.println(" restartScheduledAt=" + restartTime);
817 }
Adrian Roos7a4f3d42014-05-02 12:12:20 +0200818 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
819 duplicateSimpleNames = true;
820 }
821 }
822 fout.println(" Events:");
823 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
824 fout.println();
825 }
826
827 private String dumpBool(boolean b) {
828 return b ? "1" : "0";
829 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700830
831 private String dumpHex(int i) {
832 return "0x" + Integer.toHexString(i);
833 }
Clara Bayarri56878a92015-10-29 15:43:55 +0000834
835 @Override
836 public void setDeviceLockedForUser(int userId, boolean value) {
Clara Bayarri00a9b892016-01-13 16:17:09 +0000837 enforceReportPermission();
Clara Bayarri56878a92015-10-29 15:43:55 +0000838 mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
839 .sendToTarget();
840 }
Adrian Roosc13723f2016-01-12 20:29:03 +0100841
842 @Override
843 public boolean isTrustUsuallyManaged(int userId) {
844 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
845 "query trust state");
846 return isTrustUsuallyManagedInternal(userId);
847 }
Adrian Roos82142c22014-03-27 14:56:59 +0100848 };
849
Adrian Roosc13723f2016-01-12 20:29:03 +0100850 private boolean isTrustUsuallyManagedInternal(int userId) {
851 synchronized (mTrustUsuallyManagedForUser) {
852 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
853 if (i >= 0) {
854 return mTrustUsuallyManagedForUser.valueAt(i);
855 }
856 }
857 // It's not in memory yet, get the value from persisted storage instead
858 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
859 synchronized (mTrustUsuallyManagedForUser) {
860 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
861 if (i >= 0) {
862 // Someone set the trust usually managed in the mean time. Better use that.
863 return mTrustUsuallyManagedForUser.valueAt(i);
864 } else {
865 // .. otherwise it's safe to cache the fetched value now.
866 mTrustUsuallyManagedForUser.put(userId, persistedValue);
867 return persistedValue;
868 }
869 }
870 }
871
Adrian Roosbcd07652014-10-22 16:57:16 +0200872 private int resolveProfileParent(int userId) {
873 long identity = Binder.clearCallingIdentity();
874 try {
875 UserInfo parent = mUserManager.getProfileParent(userId);
876 if (parent != null) {
877 return parent.getUserHandle().getIdentifier();
878 }
879 return userId;
880 } finally {
881 Binder.restoreCallingIdentity(identity);
882 }
883 }
884
Adrian Roos82142c22014-03-27 14:56:59 +0100885 private final Handler mHandler = new Handler() {
886 @Override
887 public void handleMessage(Message msg) {
888 switch (msg.what) {
889 case MSG_REGISTER_LISTENER:
890 addListener((ITrustListener) msg.obj);
891 break;
892 case MSG_UNREGISTER_LISTENER:
893 removeListener((ITrustListener) msg.obj);
894 break;
895 case MSG_DISPATCH_UNLOCK_ATTEMPT:
896 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
897 break;
898 case MSG_ENABLED_AGENTS_CHANGED:
Marco Fucci4e68f112014-08-29 12:31:48 -0700899 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos481a6df2014-11-20 19:48:56 +0100900 // This is also called when the security mode of a user changes.
901 refreshDeviceLockedForUser(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100902 break;
Adrian Roos481a6df2014-11-20 19:48:56 +0100903 case MSG_KEYGUARD_SHOWING_CHANGED:
Adrian Roos7e2e40e2014-11-21 15:27:12 +0100904 refreshDeviceLockedForUser(mCurrentUser);
Adrian Roos481a6df2014-11-20 19:48:56 +0100905 break;
906 case MSG_START_USER:
907 case MSG_CLEANUP_USER:
Adrian Roos68771eb2016-05-03 14:02:36 -0700908 case MSG_UNLOCK_USER:
Adrian Roos481a6df2014-11-20 19:48:56 +0100909 refreshAgentList(msg.arg1);
910 break;
911 case MSG_SWITCH_USER:
912 mCurrentUser = msg.arg1;
913 refreshDeviceLockedForUser(UserHandle.USER_ALL);
914 break;
Clara Bayarri56878a92015-10-29 15:43:55 +0000915 case MSG_SET_DEVICE_LOCKED:
916 setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
917 break;
Adrian Roosc13723f2016-01-12 20:29:03 +0100918 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
919 SparseBooleanArray usuallyManaged;
920 synchronized (mTrustUsuallyManagedForUser) {
921 usuallyManaged = mTrustUsuallyManagedForUser.clone();
922 }
923
924 for (int i = 0; i < usuallyManaged.size(); i++) {
925 int userId = usuallyManaged.keyAt(i);
926 boolean value = usuallyManaged.valueAt(i);
927 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
928 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
929 }
930 }
Adrian Roos68771eb2016-05-03 14:02:36 -0700931 break;
Adrian Roos82142c22014-03-27 14:56:59 +0100932 }
933 }
934 };
935
936 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
937 @Override
938 public void onSomePackagesChanged() {
Marco Fucci4e68f112014-08-29 12:31:48 -0700939 refreshAgentList(UserHandle.USER_ALL);
Adrian Roos82142c22014-03-27 14:56:59 +0100940 }
941
942 @Override
943 public boolean onPackageChanged(String packageName, int uid, String[] components) {
944 // We're interested in all changes, even if just some components get enabled / disabled.
945 return true;
946 }
Adrian Roosc5f95ce2014-07-24 16:00:46 +0200947
948 @Override
949 public void onPackageDisappeared(String packageName, int reason) {
950 removeAgentsOfPackage(packageName);
951 }
Adrian Roos82142c22014-03-27 14:56:59 +0100952 };
Adrian Roosca36b952014-05-16 18:52:29 +0200953
Adrian Roos9dbe1902014-08-13 18:25:52 +0200954 private class Receiver extends BroadcastReceiver {
Adrian Roosca36b952014-05-16 18:52:29 +0200955
956 @Override
957 public void onReceive(Context context, Intent intent) {
Adrian Roos3870d452014-09-05 18:22:28 +0200958 String action = intent.getAction();
959 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Marco Fucci4e68f112014-08-29 12:31:48 -0700960 refreshAgentList(getSendingUserId());
961 updateDevicePolicyFeatures();
Adrian Roos3870d452014-09-05 18:22:28 +0200962 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
Adrian Rooscbe614f2014-10-28 20:16:12 +0100963 int userId = getUserId(intent);
Adrian Roos3870d452014-09-05 18:22:28 +0200964 if (userId > 0) {
965 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
Adrian Roos3870d452014-09-05 18:22:28 +0200966 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100967 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
968 int userId = getUserId(intent);
969 if (userId > 0) {
Adrian Roos481a6df2014-11-20 19:48:56 +0100970 synchronized (mUserIsTrusted) {
971 mUserIsTrusted.delete(userId);
972 }
973 synchronized (mDeviceLockedForUser) {
974 mDeviceLockedForUser.delete(userId);
975 }
Adrian Rooscbe614f2014-10-28 20:16:12 +0100976 refreshAgentList(userId);
Adrian Roos481a6df2014-11-20 19:48:56 +0100977 refreshDeviceLockedForUser(userId);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100978 }
979 }
980 }
981
982 private int getUserId(Intent intent) {
983 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
984 if (userId > 0) {
985 return userId;
986 } else {
987 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
988 return -100;
Adrian Roosca36b952014-05-16 18:52:29 +0200989 }
990 }
991
992 public void register(Context context) {
Adrian Roos9dbe1902014-08-13 18:25:52 +0200993 IntentFilter filter = new IntentFilter();
994 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Adrian Roos3870d452014-09-05 18:22:28 +0200995 filter.addAction(Intent.ACTION_USER_ADDED);
Adrian Rooscbe614f2014-10-28 20:16:12 +0100996 filter.addAction(Intent.ACTION_USER_REMOVED);
Adrian Roosca36b952014-05-16 18:52:29 +0200997 context.registerReceiverAsUser(this,
998 UserHandle.ALL,
Adrian Roos9dbe1902014-08-13 18:25:52 +0200999 filter,
Adrian Roosca36b952014-05-16 18:52:29 +02001000 null /* permission */,
1001 null /* scheduler */);
1002 }
1003 }
Adrian Roos517b3a42016-03-03 14:58:33 -08001004
1005 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1006
1007 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1008
1009 public StrongAuthTracker(Context context) {
1010 super(context);
1011 }
1012
1013 @Override
1014 public void onStrongAuthRequiredChanged(int userId) {
1015 mStartFromSuccessfulUnlock.delete(userId);
1016
1017 if (DEBUG) {
1018 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1019 + " trustAllowed=" + isTrustAllowedForUser(userId)
1020 + " agentsCanRun=" + canAgentsRunForUser(userId));
1021 }
1022
1023 refreshAgentList(userId);
1024
1025 // The list of active trust agents may not have changed, if there was a previous call
1026 // to allowTrustFromUnlock, so we update the trust here too.
1027 updateTrust(userId, 0 /* flags */);
1028 }
1029
1030 boolean canAgentsRunForUser(int userId) {
1031 return mStartFromSuccessfulUnlock.get(userId)
1032 || super.isTrustAllowedForUser(userId);
1033 }
1034
1035 /**
1036 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1037 * changes again. Must only be called when we know about a successful unlock already
1038 * before the underlying StrongAuthTracker.
1039 *
1040 * Note that this only changes whether trust agents can be started, not the actual trusted
1041 * value.
1042 */
1043 void allowTrustFromUnlock(int userId) {
1044 if (userId < UserHandle.USER_SYSTEM) {
1045 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1046 }
1047 boolean previous = canAgentsRunForUser(userId);
1048 mStartFromSuccessfulUnlock.put(userId, true);
1049
1050 if (DEBUG) {
1051 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1052 + " trustAllowed=" + isTrustAllowedForUser(userId)
1053 + " agentsCanRun=" + canAgentsRunForUser(userId));
1054 }
1055
1056 if (canAgentsRunForUser(userId) != previous) {
1057 refreshAgentList(userId);
1058 }
1059 }
1060 }
Adrian Roos82142c22014-03-27 14:56:59 +01001061}