OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / services / core / java / com / android / server / trust / TrustManagerService.java
1 /*
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
17 package com.android.server.trust;
18
19 import com.android.internal.annotations.GuardedBy;
20 import com.android.internal.content.PackageMonitor;
21 import com.android.internal.widget.LockPatternUtils;
22 import com.android.server.SystemService;
23
24 import org.xmlpull.v1.XmlPullParser;
25 import org.xmlpull.v1.XmlPullParserException;
26
27 import android.Manifest;
28 import android.app.ActivityManager;
29 import android.app.ActivityManagerNative;
30 import android.app.admin.DevicePolicyManager;
31 import android.app.trust.ITrustListener;
32 import android.app.trust.ITrustManager;
33 import android.content.BroadcastReceiver;
34 import android.content.ComponentName;
35 import android.content.Context;
36 import android.content.Intent;
37 import android.content.IntentFilter;
38 import android.content.pm.ApplicationInfo;
39 import android.content.pm.PackageManager;
40 import android.content.pm.ResolveInfo;
41 import android.content.pm.UserInfo;
42 import android.content.res.Resources;
43 import android.content.res.TypedArray;
44 import android.content.res.XmlResourceParser;
45 import android.graphics.drawable.Drawable;
46 import android.os.Binder;
47 import android.os.DeadObjectException;
48 import android.os.Handler;
49 import android.os.IBinder;
50 import android.os.Message;
51 import android.os.PersistableBundle;
52 import android.os.RemoteException;
53 import android.os.SystemClock;
54 import android.os.UserHandle;
55 import android.os.UserManager;
56 import android.os.storage.StorageManager;
57 import android.provider.Settings;
58 import android.service.trust.TrustAgentService;
59 import android.util.ArraySet;
60 import android.util.AttributeSet;
61 import android.util.Log;
62 import android.util.Slog;
63 import android.util.SparseBooleanArray;
64 import android.util.Xml;
65 import android.view.IWindowManager;
66 import android.view.WindowManagerGlobal;
67
68 import java.io.FileDescriptor;
69 import java.io.IOException;
70 import java.io.PrintWriter;
71 import java.util.ArrayList;
72 import 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  */
88 public 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);
95     private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
96
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;
101     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;
105     private static final int MSG_SET_DEVICE_LOCKED = 10;
106     private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 11;
107     private static final int MSG_UNLOCK_USER = 12;
108
109     private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
110
111     private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
112     private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
113     private final Receiver mReceiver = new Receiver();
114
115     /* package */ final TrustArchive mArchive = new TrustArchive();
116     private final Context mContext;
117     private final LockPatternUtils mLockPatternUtils;
118     private final UserManager mUserManager;
119     private final ActivityManager mActivityManager;
120
121     @GuardedBy("mUserIsTrusted")
122     private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
123
124     @GuardedBy("mDeviceLockedForUser")
125     private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
126
127     @GuardedBy("mDeviceLockedForUser")
128     private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
129
130     private final StrongAuthTracker mStrongAuthTracker;
131
132     private boolean mTrustAgentsCanRun = false;
133     private int mCurrentUser = UserHandle.USER_SYSTEM;
134
135     public TrustManagerService(Context context) {
136         super(context);
137         mContext = context;
138         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
139         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
140         mLockPatternUtils = new LockPatternUtils(context);
141         mStrongAuthTracker = new StrongAuthTracker(context);
142     }
143
144     @Override
145     public void onStart() {
146         publishBinderService(Context.TRUST_SERVICE, mService);
147     }
148
149     @Override
150     public void onBootPhase(int phase) {
151         if (isSafeMode()) {
152             // No trust agents in safe mode.
153             return;
154         }
155         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
156             mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
157             mReceiver.register(mContext);
158             mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
159         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
160             mTrustAgentsCanRun = true;
161             refreshAgentList(UserHandle.USER_ALL);
162         } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
163             maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
164         }
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) {
195             updateTrust(userInfo.id, 0);
196         }
197     }
198
199     public void updateTrust(int userId, int flags) {
200         boolean managed = aggregateIsTrustManaged(userId);
201         dispatchOnTrustManagedChanged(managed, userId);
202         if (mStrongAuthTracker.isTrustAllowedForUser(userId)
203                 && isTrustUsuallyManagedInternal(userId) != managed) {
204             updateTrustUsuallyManaged(userId, managed);
205         }
206         boolean trusted = aggregateIsTrusted(userId);
207         boolean changed;
208         synchronized (mUserIsTrusted) {
209             changed = mUserIsTrusted.get(userId) != trusted;
210             mUserIsTrusted.put(userId, trusted);
211         }
212         dispatchOnTrustChanged(trusted, userId, flags);
213         if (changed) {
214             refreshDeviceLockedForUser(userId);
215         }
216     }
217
218     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
230     void refreshAgentList(int userIdOrAll) {
231         if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
232         if (!mTrustAgentsCanRun) {
233             return;
234         }
235         if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
236             Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
237                     + " must be USER_ALL or a specific user.", new Throwable("here"));
238             userIdOrAll = UserHandle.USER_ALL;
239         }
240         PackageManager pm = mContext.getPackageManager();
241
242         List<UserInfo> userInfos;
243         if (userIdOrAll == UserHandle.USER_ALL) {
244             userInfos = mUserManager.getUsers(true /* excludeDying */);
245         } else {
246             userInfos = new ArrayList<>();
247             userInfos.add(mUserManager.getUserInfo(userIdOrAll));
248         }
249         LockPatternUtils lockPatternUtils = mLockPatternUtils;
250
251         ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
252         obsoleteAgents.addAll(mActiveAgents);
253
254         for (UserInfo userInfo : userInfos) {
255             if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
256                     || userInfo.guestToRemove) continue;
257             if (!userInfo.supportsSwitchToByUser()) continue;
258             if (!StorageManager.isUserKeyUnlocked(userInfo.id)) continue;
259             if (!mActivityManager.isUserRunning(userInfo.id)) continue;
260             if (!lockPatternUtils.isSecure(userInfo.id)) continue;
261             if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) continue;
262             DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
263             int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
264             final boolean disableTrustAgents =
265                     (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
266
267             List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
268             if (enabledAgents == null) {
269                 continue;
270             }
271             List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
272             for (ResolveInfo resolveInfo : resolveInfos) {
273                 ComponentName name = getComponentName(resolveInfo);
274
275                 if (!enabledAgents.contains(name)) continue;
276                 if (disableTrustAgents) {
277                     List<PersistableBundle> config =
278                             dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
279                     // Disable agent if no features are enabled.
280                     if (config == null || config.isEmpty()) continue;
281                 }
282
283                 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 {
294                     obsoleteAgents.remove(agentInfo);
295                 }
296             }
297         }
298
299         boolean trustMayHaveChanged = false;
300         for (int i = 0; i < obsoleteAgents.size(); i++) {
301             AgentInfo info = obsoleteAgents.valueAt(i);
302             if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
303                 if (info.agent.isManagingTrust()) {
304                     trustMayHaveChanged = true;
305                 }
306                 info.agent.destroy();
307                 mActiveAgents.remove(info);
308             }
309         }
310
311         if (trustMayHaveChanged) {
312             if (userIdOrAll == UserHandle.USER_ALL) {
313                 updateTrustAll();
314             } else {
315                 updateTrust(userIdOrAll, 0);
316             }
317         }
318     }
319
320     public void setDeviceLockedForUser(int userId, boolean locked) {
321         if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
322             synchronized (mDeviceLockedForUser) {
323                 mDeviceLockedForUser.put(userId, locked);
324             }
325             if (locked) {
326                 try {
327                     ActivityManagerNative.getDefault().notifyLockedProfile(userId);
328                 } catch (RemoteException e) {
329                 }
330             }
331         }
332     }
333
334     boolean isDeviceLockedInner(int userId) {
335         synchronized (mDeviceLockedForUser) {
336             return mDeviceLockedForUser.get(userId, true);
337         }
338     }
339
340     private void refreshDeviceLockedForUser(int userId) {
341         if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
342             Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
343                     + " 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
361                     || !info.supportsSwitchToByUser()) {
362                 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
401     void updateDevicePolicyFeatures() {
402         boolean changed = false;
403         for (int i = 0; i < mActiveAgents.size(); i++) {
404             AgentInfo info = mActiveAgents.valueAt(i);
405             if (info.agent.isConnected()) {
406                 info.agent.updateDevicePolicyFeatures();
407                 changed = true;
408             }
409         }
410         if (changed) {
411             mArchive.logDevicePolicyChanged();
412         }
413     }
414
415     private void removeAgentsOfPackage(String packageName) {
416         boolean trustMayHaveChanged = false;
417         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
418             AgentInfo info = mActiveAgents.valueAt(i);
419             if (packageName.equals(info.component.getPackageName())) {
420                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
421                 if (info.agent.isManagingTrust()) {
422                     trustMayHaveChanged = true;
423                 }
424                 info.agent.destroy();
425                 mActiveAgents.removeAt(i);
426             }
427         }
428         if (trustMayHaveChanged) {
429             updateTrustAll();
430         }
431     }
432
433     public void resetAgent(ComponentName name, int userId) {
434         boolean trustMayHaveChanged = false;
435         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
436             AgentInfo info = mActiveAgents.valueAt(i);
437             if (name.equals(info.component) && userId == info.userId) {
438                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
439                 if (info.agent.isManagingTrust()) {
440                     trustMayHaveChanged = true;
441                 }
442                 info.agent.destroy();
443                 mActiveAgents.removeAt(i);
444             }
445         }
446         if (trustMayHaveChanged) {
447             updateTrust(userId, 0);
448         }
449         refreshAgentList(userId);
450     }
451
452     private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
453         if (resolveInfo == null || resolveInfo.serviceInfo == null
454                 || resolveInfo.serviceInfo.metaData == null) return null;
455         String cn = null;
456         XmlResourceParser parser = null;
457         Exception caughtException = null;
458         try {
459             parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
460                     TrustAgentService.TRUST_AGENT_META_DATA);
461             if (parser == null) {
462                 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
463                 return null;
464             }
465             Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
466             AttributeSet attrs = Xml.asAttributeSet(parser);
467             int type;
468             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
469                     && type != XmlPullParser.START_TAG) {
470                 // Drain preamble.
471             }
472             String nodeName = parser.getName();
473             if (!"trust-agent".equals(nodeName)) {
474                 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
475                 return null;
476             }
477             TypedArray sa = res
478                     .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
479             cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
480             sa.recycle();
481         } catch (PackageManager.NameNotFoundException e) {
482             caughtException = e;
483         } catch (IOException e) {
484             caughtException = e;
485         } catch (XmlPullParserException e) {
486             caughtException = e;
487         } finally {
488             if (parser != null) parser.close();
489         }
490         if (caughtException != null) {
491             Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
492             return null;
493         }
494         if (cn == null) {
495             return null;
496         }
497         if (cn.indexOf('/') < 0) {
498             cn = resolveInfo.serviceInfo.packageName + "/" + cn;
499         }
500         return ComponentName.unflattenFromString(cn);
501     }
502
503     private ComponentName getComponentName(ResolveInfo resolveInfo) {
504         if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
505         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
506     }
507
508     private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
509         if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
510                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
511             return;
512         }
513         PackageManager pm = mContext.getPackageManager();
514         List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
515         ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
516         for (ResolveInfo resolveInfo : resolveInfos) {
517             ComponentName componentName = getComponentName(resolveInfo);
518             int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
519             if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
520                 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
521                         + "is not a system package.");
522                 continue;
523             }
524             discoveredAgents.add(componentName);
525         }
526
527         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
528         if (previouslyEnabledAgents != null) {
529             discoveredAgents.addAll(previouslyEnabledAgents);
530         }
531         utils.setEnabledTrustAgents(discoveredAgents, userId);
532         Settings.Secure.putIntForUser(mContext.getContentResolver(),
533                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
534     }
535
536     private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
537         List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
538                 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
539                 userId);
540         ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
541         for (ResolveInfo resolveInfo : resolveInfos) {
542             if (resolveInfo.serviceInfo == null) continue;
543             if (resolveInfo.serviceInfo.applicationInfo == null) continue;
544             String packageName = resolveInfo.serviceInfo.packageName;
545             if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
546                     != PackageManager.PERMISSION_GRANTED) {
547                 ComponentName name = getComponentName(resolveInfo);
548                 Log.w(TAG, "Skipping agent " + name + " because package does not have"
549                         + " permission " + PERMISSION_PROVIDE_AGENT + ".");
550                 continue;
551             }
552             allowedAgents.add(resolveInfo);
553         }
554         return allowedAgents;
555     }
556
557     // Agent dispatch and aggregation
558
559     private boolean aggregateIsTrusted(int userId) {
560         if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
561             return false;
562         }
563         for (int i = 0; i < mActiveAgents.size(); i++) {
564             AgentInfo info = mActiveAgents.valueAt(i);
565             if (info.userId == userId) {
566                 if (info.agent.isTrusted()) {
567                     return true;
568                 }
569             }
570         }
571         return false;
572     }
573
574     private boolean aggregateIsTrustManaged(int userId) {
575         if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
576             return false;
577         }
578         for (int i = 0; i < mActiveAgents.size(); i++) {
579             AgentInfo info = mActiveAgents.valueAt(i);
580             if (info.userId == userId) {
581                 if (info.agent.isManagingTrust()) {
582                     return true;
583                 }
584             }
585         }
586         return false;
587     }
588
589     private void dispatchUnlockAttempt(boolean successful, int userId) {
590         if (successful) {
591             mStrongAuthTracker.allowTrustFromUnlock(userId);
592         }
593
594         for (int i = 0; i < mActiveAgents.size(); i++) {
595             AgentInfo info = mActiveAgents.valueAt(i);
596             if (info.userId == userId) {
597                 info.agent.onUnlockAttempt(successful);
598             }
599         }
600     }
601
602     // Listeners
603
604     private void addListener(ITrustListener listener) {
605         for (int i = 0; i < mTrustListeners.size(); i++) {
606             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
607                 return;
608             }
609         }
610         mTrustListeners.add(listener);
611         updateTrustAll();
612     }
613
614     private void removeListener(ITrustListener listener) {
615         for (int i = 0; i < mTrustListeners.size(); i++) {
616             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
617                 mTrustListeners.remove(i);
618                 return;
619             }
620         }
621     }
622
623     private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
624         if (DEBUG) {
625             Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
626                     + Integer.toHexString(flags) + ")");
627         }
628         if (!enabled) flags = 0;
629         for (int i = 0; i < mTrustListeners.size(); i++) {
630             try {
631                 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
632             } catch (DeadObjectException e) {
633                 Slog.d(TAG, "Removing dead TrustListener.");
634                 mTrustListeners.remove(i);
635                 i--;
636             } catch (RemoteException e) {
637                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
638             }
639         }
640     }
641
642     private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
643         if (DEBUG) {
644             Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
645         }
646         for (int i = 0; i < mTrustListeners.size(); i++) {
647             try {
648                 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
649             } catch (DeadObjectException e) {
650                 Slog.d(TAG, "Removing dead TrustListener.");
651                 mTrustListeners.remove(i);
652                 i--;
653             } catch (RemoteException e) {
654                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
655             }
656         }
657     }
658
659     // User lifecycle
660
661     @Override
662     public void onStartUser(int userId) {
663         mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
664     }
665
666     @Override
667     public void onCleanupUser(int userId) {
668         mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
669     }
670
671     @Override
672     public void onSwitchUser(int userId) {
673         mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
674     }
675
676     @Override
677     public void onUnlockUser(int userId) {
678         mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
679     }
680
681     // Plumbing
682
683     private final IBinder mService = new ITrustManager.Stub() {
684         @Override
685         public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
686             enforceReportPermission();
687             mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
688                     .sendToTarget();
689         }
690
691         @Override
692         public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
693             enforceReportPermission();
694             // coalesce refresh messages.
695             mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
696             mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
697         }
698
699         @Override
700         public void reportKeyguardShowingChanged() throws RemoteException {
701             enforceReportPermission();
702             // coalesce refresh messages.
703             mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
704             mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
705         }
706
707         @Override
708         public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
709             enforceListenerPermission();
710             mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
711         }
712
713         @Override
714         public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
715             enforceListenerPermission();
716             mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
717         }
718
719         @Override
720         public boolean isDeviceLocked(int userId) throws RemoteException {
721             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
722                     false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
723
724             long token = Binder.clearCallingIdentity();
725             try {
726                 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
727                     userId = resolveProfileParent(userId);
728                 }
729                 return isDeviceLockedInner(userId);
730             } finally {
731                 Binder.restoreCallingIdentity(token);
732             }
733         }
734
735         @Override
736         public boolean isDeviceSecure(int userId) throws RemoteException {
737             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
738                     false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
739
740             long token = Binder.clearCallingIdentity();
741             try {
742                 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
743                     userId = resolveProfileParent(userId);
744                 }
745                 return mLockPatternUtils.isSecure(userId);
746             } finally {
747                 Binder.restoreCallingIdentity(token);
748             }
749         }
750
751         private void enforceReportPermission() {
752             mContext.enforceCallingOrSelfPermission(
753                     Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
754         }
755
756         private void enforceListenerPermission() {
757             mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
758                     "register trust listener");
759         }
760
761         @Override
762         protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
763             mContext.enforceCallingPermission(Manifest.permission.DUMP,
764                     "dumping TrustManagerService");
765             if (isSafeMode()) {
766                 fout.println("disabled because the system is in safe mode.");
767                 return;
768             }
769             if (!mTrustAgentsCanRun) {
770                 fout.println("disabled because the third-party apps can't run yet.");
771                 return;
772             }
773             final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
774             mHandler.runWithScissors(new Runnable() {
775                 @Override
776                 public void run() {
777                     fout.println("Trust manager state:");
778                     for (UserInfo user : userInfos) {
779                         dumpUser(fout, user, user.id == mCurrentUser);
780                     }
781                 }
782             }, 1500);
783         }
784
785         private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
786             fout.printf(" User \"%s\" (id=%d, flags=%#x)",
787                     user.name, user.id, user.flags);
788             if (!user.supportsSwitchToByUser()) {
789                 fout.println("(managed profile)");
790                 fout.println("   disabled because switching to this user is not possible.");
791                 return;
792             }
793             if (isCurrent) {
794                 fout.print(" (current)");
795             }
796             fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
797             fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
798             fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
799             fout.print(", strongAuthRequired=" + dumpHex(
800                     mStrongAuthTracker.getStrongAuthForUser(user.id)));
801             fout.println();
802             fout.println("   Enabled agents:");
803             boolean duplicateSimpleNames = false;
804             ArraySet<String> simpleNames = new ArraySet<String>();
805             for (AgentInfo info : mActiveAgents) {
806                 if (info.userId != user.id) { continue; }
807                 boolean trusted = info.agent.isTrusted();
808                 fout.print("    "); fout.println(info.component.flattenToShortString());
809                 fout.print("     bound=" + dumpBool(info.agent.isBound()));
810                 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
811                 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
812                 fout.print(", trusted=" + dumpBool(trusted));
813                 fout.println();
814                 if (trusted) {
815                     fout.println("      message=\"" + info.agent.getMessage() + "\"");
816                 }
817                 if (!info.agent.isConnected()) {
818                     String restartTime = TrustArchive.formatDuration(
819                             info.agent.getScheduledRestartUptimeMillis()
820                                     - SystemClock.uptimeMillis());
821                     fout.println("      restartScheduledAt=" + restartTime);
822                 }
823                 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
824                     duplicateSimpleNames = true;
825                 }
826             }
827             fout.println("   Events:");
828             mArchive.dump(fout, 50, user.id, "    " /* linePrefix */, duplicateSimpleNames);
829             fout.println();
830         }
831
832         private String dumpBool(boolean b) {
833             return b ? "1" : "0";
834         }
835
836         private String dumpHex(int i) {
837             return "0x" + Integer.toHexString(i);
838         }
839
840         @Override
841         public void setDeviceLockedForUser(int userId, boolean value) {
842             enforceReportPermission();
843             mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
844                     .sendToTarget();
845         }
846
847         @Override
848         public boolean isTrustUsuallyManaged(int userId) {
849             mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
850                     "query trust state");
851             return isTrustUsuallyManagedInternal(userId);
852         }
853     };
854
855     private boolean isTrustUsuallyManagedInternal(int userId) {
856         synchronized (mTrustUsuallyManagedForUser) {
857             int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
858             if (i >= 0) {
859                 return mTrustUsuallyManagedForUser.valueAt(i);
860             }
861         }
862         // It's not in memory yet, get the value from persisted storage instead
863         boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
864         synchronized (mTrustUsuallyManagedForUser) {
865             int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
866             if (i >= 0) {
867                 // Someone set the trust usually managed in the mean time. Better use that.
868                 return mTrustUsuallyManagedForUser.valueAt(i);
869             } else {
870                 // .. otherwise it's safe to cache the fetched value now.
871                 mTrustUsuallyManagedForUser.put(userId, persistedValue);
872                 return persistedValue;
873             }
874         }
875     }
876
877     private int resolveProfileParent(int userId) {
878         long identity = Binder.clearCallingIdentity();
879         try {
880             UserInfo parent = mUserManager.getProfileParent(userId);
881             if (parent != null) {
882                 return parent.getUserHandle().getIdentifier();
883             }
884             return userId;
885         } finally {
886             Binder.restoreCallingIdentity(identity);
887         }
888     }
889
890     private final Handler mHandler = new Handler() {
891         @Override
892         public void handleMessage(Message msg) {
893             switch (msg.what) {
894                 case MSG_REGISTER_LISTENER:
895                     addListener((ITrustListener) msg.obj);
896                     break;
897                 case MSG_UNREGISTER_LISTENER:
898                     removeListener((ITrustListener) msg.obj);
899                     break;
900                 case MSG_DISPATCH_UNLOCK_ATTEMPT:
901                     dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
902                     break;
903                 case MSG_ENABLED_AGENTS_CHANGED:
904                     refreshAgentList(UserHandle.USER_ALL);
905                     // This is also called when the security mode of a user changes.
906                     refreshDeviceLockedForUser(UserHandle.USER_ALL);
907                     break;
908                 case MSG_KEYGUARD_SHOWING_CHANGED:
909                     refreshDeviceLockedForUser(mCurrentUser);
910                     break;
911                 case MSG_START_USER:
912                 case MSG_CLEANUP_USER:
913                 case MSG_UNLOCK_USER:
914                     refreshAgentList(msg.arg1);
915                     break;
916                 case MSG_SWITCH_USER:
917                     mCurrentUser = msg.arg1;
918                     refreshDeviceLockedForUser(UserHandle.USER_ALL);
919                     break;
920                 case MSG_SET_DEVICE_LOCKED:
921                     setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
922                     break;
923                 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
924                     SparseBooleanArray usuallyManaged;
925                     synchronized (mTrustUsuallyManagedForUser) {
926                         usuallyManaged = mTrustUsuallyManagedForUser.clone();
927                     }
928
929                     for (int i = 0; i < usuallyManaged.size(); i++) {
930                         int userId = usuallyManaged.keyAt(i);
931                         boolean value = usuallyManaged.valueAt(i);
932                         if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
933                             mLockPatternUtils.setTrustUsuallyManaged(value, userId);
934                         }
935                     }
936                     break;
937             }
938         }
939     };
940
941     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
942         @Override
943         public void onSomePackagesChanged() {
944             refreshAgentList(UserHandle.USER_ALL);
945         }
946
947         @Override
948         public boolean onPackageChanged(String packageName, int uid, String[] components) {
949             // We're interested in all changes, even if just some components get enabled / disabled.
950             return true;
951         }
952
953         @Override
954         public void onPackageDisappeared(String packageName, int reason) {
955             removeAgentsOfPackage(packageName);
956         }
957     };
958
959     private class Receiver extends BroadcastReceiver {
960
961         @Override
962         public void onReceive(Context context, Intent intent) {
963             String action = intent.getAction();
964             if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
965                 refreshAgentList(getSendingUserId());
966                 updateDevicePolicyFeatures();
967             } else if (Intent.ACTION_USER_ADDED.equals(action)) {
968                 int userId = getUserId(intent);
969                 if (userId > 0) {
970                     maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
971                 }
972             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
973                 int userId = getUserId(intent);
974                 if (userId > 0) {
975                     synchronized (mUserIsTrusted) {
976                         mUserIsTrusted.delete(userId);
977                     }
978                     synchronized (mDeviceLockedForUser) {
979                         mDeviceLockedForUser.delete(userId);
980                     }
981                     refreshAgentList(userId);
982                     refreshDeviceLockedForUser(userId);
983                 }
984             }
985         }
986
987         private int getUserId(Intent intent) {
988             int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
989             if (userId > 0) {
990                 return userId;
991             } else {
992                 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
993                 return -100;
994             }
995         }
996
997         public void register(Context context) {
998             IntentFilter filter = new IntentFilter();
999             filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1000             filter.addAction(Intent.ACTION_USER_ADDED);
1001             filter.addAction(Intent.ACTION_USER_REMOVED);
1002             context.registerReceiverAsUser(this,
1003                     UserHandle.ALL,
1004                     filter,
1005                     null /* permission */,
1006                     null /* scheduler */);
1007         }
1008     }
1009
1010     private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1011
1012         SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1013
1014         public StrongAuthTracker(Context context) {
1015             super(context);
1016         }
1017
1018         @Override
1019         public void onStrongAuthRequiredChanged(int userId) {
1020             mStartFromSuccessfulUnlock.delete(userId);
1021
1022             if (DEBUG) {
1023                 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1024                         + " trustAllowed=" + isTrustAllowedForUser(userId)
1025                         + " agentsCanRun=" + canAgentsRunForUser(userId));
1026             }
1027
1028             refreshAgentList(userId);
1029
1030             // The list of active trust agents may not have changed, if there was a previous call
1031             // to allowTrustFromUnlock, so we update the trust here too.
1032             updateTrust(userId, 0 /* flags */);
1033         }
1034
1035         boolean canAgentsRunForUser(int userId) {
1036             return mStartFromSuccessfulUnlock.get(userId)
1037                     || super.isTrustAllowedForUser(userId);
1038         }
1039
1040         /**
1041          * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1042          * changes again. Must only be called when we know about a successful unlock already
1043          * before the underlying StrongAuthTracker.
1044          *
1045          * Note that this only changes whether trust agents can be started, not the actual trusted
1046          * value.
1047          */
1048         void allowTrustFromUnlock(int userId) {
1049             if (userId < UserHandle.USER_SYSTEM) {
1050                 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1051             }
1052             boolean previous = canAgentsRunForUser(userId);
1053             mStartFromSuccessfulUnlock.put(userId, true);
1054
1055             if (DEBUG) {
1056                 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1057                         + " trustAllowed=" + isTrustAllowedForUser(userId)
1058                         + " agentsCanRun=" + canAgentsRunForUser(userId));
1059             }
1060
1061             if (canAgentsRunForUser(userId) != previous) {
1062                 refreshAgentList(userId);
1063             }
1064         }
1065     }
1066 }