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
17package com.android.server.trust;
18
19import android.Manifest;
20import android.annotation.UserIdInt;
21import android.app.ActivityManager;
22import android.app.admin.DevicePolicyManager;
23import android.app.trust.ITrustListener;
24import android.app.trust.ITrustManager;
25import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.Context;
28import android.content.Intent;
29import android.content.IntentFilter;
30import android.content.pm.ApplicationInfo;
31import android.content.pm.PackageManager;
32import android.content.pm.ResolveInfo;
33import android.content.pm.UserInfo;
34import android.content.res.Resources;
35import android.content.res.TypedArray;
36import android.content.res.XmlResourceParser;
37import android.graphics.drawable.Drawable;
38import android.os.Binder;
39import android.os.Build;
40import android.os.DeadObjectException;
41import android.os.Handler;
42import android.os.IBinder;
43import android.os.Message;
44import android.os.PersistableBundle;
45import android.os.RemoteException;
46import android.os.SystemClock;
47import android.os.UserHandle;
48import android.os.UserManager;
49import android.os.storage.StorageManager;
50import android.provider.Settings;
51import android.service.trust.TrustAgentService;
52import android.util.ArraySet;
53import android.util.AttributeSet;
54import android.util.Log;
55import android.util.Slog;
56import android.util.SparseBooleanArray;
57import android.util.Xml;
58import android.view.IWindowManager;
59import android.view.WindowManagerGlobal;
60import com.android.internal.annotations.GuardedBy;
61import com.android.internal.content.PackageMonitor;
62import com.android.internal.util.DumpUtils;
63import com.android.internal.widget.LockPatternUtils;
64import com.android.server.SystemService;
65import java.io.FileDescriptor;
66import java.io.IOException;
67import java.io.PrintWriter;
68import java.util.ArrayList;
69import java.util.List;
70import org.xmlpull.v1.XmlPullParser;
71import org.xmlpull.v1.XmlPullParserException;
72
73/**
74 * Manages trust agents and trust listeners.
75 *
76 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
77 * of each user and notifies them about events that are relevant to them.
78 * It start and stops them based on the value of
79 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
80 *
81 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
82 * trust state changes for any user.
83 *
84 * Trust state and the setting of enabled agents is kept per user and each user has its own
85 * instance of a {@link android.service.trust.TrustAgentService}.
86 */
87public class TrustManagerService extends SystemService {
88    private static final String TAG = "TrustManagerService";
89    static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
90
91    private static final Intent TRUST_AGENT_INTENT =
92            new Intent(TrustAgentService.SERVICE_INTERFACE);
93    private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
94
95    private static final int MSG_REGISTER_LISTENER = 1;
96    private static final int MSG_UNREGISTER_LISTENER = 2;
97    private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
98    private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
99    private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
100    private static final int MSG_START_USER = 7;
101    private static final int MSG_CLEANUP_USER = 8;
102    private static final int MSG_SWITCH_USER = 9;
103    private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 10;
104    private static final int MSG_UNLOCK_USER = 11;
105    private static final int MSG_STOP_USER = 12;
106    private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
107
108    private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
109
110    private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
111    private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
112    private final Receiver mReceiver = new Receiver();
113
114    /* package */ final TrustArchive mArchive = new TrustArchive();
115    private final Context mContext;
116    private final LockPatternUtils mLockPatternUtils;
117    private final UserManager mUserManager;
118    private final ActivityManager mActivityManager;
119
120    @GuardedBy("mUserIsTrusted")
121    private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
122
123    @GuardedBy("mDeviceLockedForUser")
124    private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
125
126    @GuardedBy("mDeviceLockedForUser")
127    private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
128
129    private final StrongAuthTracker mStrongAuthTracker;
130
131    private boolean mTrustAgentsCanRun = false;
132    private int mCurrentUser = UserHandle.USER_SYSTEM;
133
134    public TrustManagerService(Context context) {
135        super(context);
136        mContext = context;
137        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
138        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
139        mLockPatternUtils = new LockPatternUtils(context);
140        mStrongAuthTracker = new StrongAuthTracker(context);
141    }
142
143    @Override
144    public void onStart() {
145        publishBinderService(Context.TRUST_SERVICE, mService);
146    }
147
148    @Override
149    public void onBootPhase(int phase) {
150        if (isSafeMode()) {
151            // No trust agents in safe mode.
152            return;
153        }
154        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
155            mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
156            mReceiver.register(mContext);
157            mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
158        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
159            mTrustAgentsCanRun = true;
160            refreshAgentList(UserHandle.USER_ALL);
161            refreshDeviceLockedForUser(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        SettingsAttrs 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    public long addEscrowToken(byte[] token, int userId) {
231        return mLockPatternUtils.addEscrowToken(token, userId);
232    }
233
234    public boolean removeEscrowToken(long handle, int userId) {
235        return mLockPatternUtils.removeEscrowToken(handle, userId);
236    }
237
238    public boolean isEscrowTokenActive(long handle, int userId) {
239        return mLockPatternUtils.isEscrowTokenActive(handle, userId);
240    }
241
242    public void unlockUserWithToken(long handle, byte[] token, int userId) {
243        mLockPatternUtils.unlockUserWithToken(handle, token, userId);
244    }
245
246    void refreshAgentList(int userIdOrAll) {
247        if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
248        if (!mTrustAgentsCanRun) {
249            return;
250        }
251        if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
252            Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
253                    + " must be USER_ALL or a specific user.", new Throwable("here"));
254            userIdOrAll = UserHandle.USER_ALL;
255        }
256        PackageManager pm = mContext.getPackageManager();
257
258        List<UserInfo> userInfos;
259        if (userIdOrAll == UserHandle.USER_ALL) {
260            userInfos = mUserManager.getUsers(true /* excludeDying */);
261        } else {
262            userInfos = new ArrayList<>();
263            userInfos.add(mUserManager.getUserInfo(userIdOrAll));
264        }
265        LockPatternUtils lockPatternUtils = mLockPatternUtils;
266
267        ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
268        obsoleteAgents.addAll(mActiveAgents);
269
270        for (UserInfo userInfo : userInfos) {
271            if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
272                    || userInfo.guestToRemove) continue;
273            if (!userInfo.supportsSwitchToByUser()) {
274                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
275                        + ": switchToByUser=false");
276                continue;
277            }
278            if (!mActivityManager.isUserRunning(userInfo.id)) {
279                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
280                        + ": user not started");
281                continue;
282            }
283            if (!lockPatternUtils.isSecure(userInfo.id)) {
284                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
285                        + ": no secure credential");
286                continue;
287            }
288
289            DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
290            int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
291            final boolean disableTrustAgents =
292                    (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
293
294            List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
295            if (enabledAgents == null) {
296                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
297                        + ": no agents enabled by user");
298                continue;
299            }
300            List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
301            for (ResolveInfo resolveInfo : resolveInfos) {
302                ComponentName name = getComponentName(resolveInfo);
303
304                if (!enabledAgents.contains(name)) {
305                    if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
306                            + name.flattenToShortString() + " u"+ userInfo.id
307                            + ": not enabled by user");
308                    continue;
309                }
310                if (disableTrustAgents) {
311                    List<PersistableBundle> config =
312                            dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
313                    // Disable agent if no features are enabled.
314                    if (config == null || config.isEmpty()) {
315                        if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
316                                + name.flattenToShortString() + " u"+ userInfo.id
317                                + ": not allowed by DPM");
318                        continue;
319                    }
320                }
321                AgentInfo agentInfo = new AgentInfo();
322                agentInfo.component = name;
323                agentInfo.userId = userInfo.id;
324                if (!mActiveAgents.contains(agentInfo)) {
325                    agentInfo.label = resolveInfo.loadLabel(pm);
326                    agentInfo.icon = resolveInfo.loadIcon(pm);
327                    agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
328                } else {
329                    int index = mActiveAgents.indexOf(agentInfo);
330                    agentInfo = mActiveAgents.valueAt(index);
331                }
332
333                boolean directUnlock = resolveInfo.serviceInfo.directBootAware
334                    && agentInfo.settings.canUnlockProfile;
335
336                if (directUnlock) {
337                    if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
338                            + "of user " + userInfo.id + "can unlock user profile.");
339                }
340
341                if (!StorageManager.isUserKeyUnlocked(userInfo.id)
342                        && !directUnlock) {
343                    if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
344                            + "'s trust agent " + name + ": FBE still locked and "
345                            + " the agent cannot unlock user profile.");
346                    continue;
347                }
348
349                if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
350                    int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
351                    if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
352                        if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
353                            || !directUnlock) {
354                            if (DEBUG)
355                                Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
356                                    + ": prevented by StrongAuthTracker = 0x"
357                                    + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
358                                    userInfo.id)));
359                            continue;
360                        }
361                    }
362                }
363
364                if (agentInfo.agent == null) {
365                    agentInfo.agent = new TrustAgentWrapper(mContext, this,
366                            new Intent().setComponent(name), userInfo.getUserHandle());
367                }
368
369                if (!mActiveAgents.contains(agentInfo)) {
370                    mActiveAgents.add(agentInfo);
371                } else {
372                    obsoleteAgents.remove(agentInfo);
373                }
374            }
375        }
376
377        boolean trustMayHaveChanged = false;
378        for (int i = 0; i < obsoleteAgents.size(); i++) {
379            AgentInfo info = obsoleteAgents.valueAt(i);
380            if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
381                if (info.agent.isManagingTrust()) {
382                    trustMayHaveChanged = true;
383                }
384                info.agent.destroy();
385                mActiveAgents.remove(info);
386            }
387        }
388
389        if (trustMayHaveChanged) {
390            if (userIdOrAll == UserHandle.USER_ALL) {
391                updateTrustAll();
392            } else {
393                updateTrust(userIdOrAll, 0);
394            }
395        }
396    }
397
398    boolean isDeviceLockedInner(int userId) {
399        synchronized (mDeviceLockedForUser) {
400            return mDeviceLockedForUser.get(userId, true);
401        }
402    }
403
404    private void refreshDeviceLockedForUser(int userId) {
405        if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
406            Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
407                    + " must be USER_ALL or a specific user.", new Throwable("here"));
408            userId = UserHandle.USER_ALL;
409        }
410
411        List<UserInfo> userInfos;
412        if (userId == UserHandle.USER_ALL) {
413            userInfos = mUserManager.getUsers(true /* excludeDying */);
414        } else {
415            userInfos = new ArrayList<>();
416            userInfos.add(mUserManager.getUserInfo(userId));
417        }
418
419        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
420
421        for (int i = 0; i < userInfos.size(); i++) {
422            UserInfo info = userInfos.get(i);
423
424            if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
425                    || !info.supportsSwitchToByUser()) {
426                continue;
427            }
428
429            int id = info.id;
430            boolean secure = mLockPatternUtils.isSecure(id);
431            boolean trusted = aggregateIsTrusted(id);
432            boolean showingKeyguard = true;
433            if (mCurrentUser == id) {
434                try {
435                    showingKeyguard = wm.isKeyguardLocked();
436                } catch (RemoteException e) {
437                }
438            }
439            boolean deviceLocked = secure && showingKeyguard && !trusted;
440            setDeviceLockedForUser(id, deviceLocked);
441        }
442    }
443
444    private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
445        final boolean changed;
446        synchronized (mDeviceLockedForUser) {
447            changed = isDeviceLockedInner(userId) != locked;
448            mDeviceLockedForUser.put(userId, locked);
449        }
450        if (changed) {
451            dispatchDeviceLocked(userId, locked);
452        }
453    }
454
455    private void dispatchDeviceLocked(int userId, boolean isLocked) {
456        for (int i = 0; i < mActiveAgents.size(); i++) {
457            AgentInfo agent = mActiveAgents.valueAt(i);
458            if (agent.userId == userId) {
459                if (isLocked) {
460                    agent.agent.onDeviceLocked();
461                } else{
462                    agent.agent.onDeviceUnlocked();
463                }
464            }
465        }
466    }
467
468    void updateDevicePolicyFeatures() {
469        boolean changed = false;
470        for (int i = 0; i < mActiveAgents.size(); i++) {
471            AgentInfo info = mActiveAgents.valueAt(i);
472            if (info.agent.isConnected()) {
473                info.agent.updateDevicePolicyFeatures();
474                changed = true;
475            }
476        }
477        if (changed) {
478            mArchive.logDevicePolicyChanged();
479        }
480    }
481
482    private void removeAgentsOfPackage(String packageName) {
483        boolean trustMayHaveChanged = false;
484        for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
485            AgentInfo info = mActiveAgents.valueAt(i);
486            if (packageName.equals(info.component.getPackageName())) {
487                Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
488                if (info.agent.isManagingTrust()) {
489                    trustMayHaveChanged = true;
490                }
491                info.agent.destroy();
492                mActiveAgents.removeAt(i);
493            }
494        }
495        if (trustMayHaveChanged) {
496            updateTrustAll();
497        }
498    }
499
500    public void resetAgent(ComponentName name, int userId) {
501        boolean trustMayHaveChanged = false;
502        for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
503            AgentInfo info = mActiveAgents.valueAt(i);
504            if (name.equals(info.component) && userId == info.userId) {
505                Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
506                if (info.agent.isManagingTrust()) {
507                    trustMayHaveChanged = true;
508                }
509                info.agent.destroy();
510                mActiveAgents.removeAt(i);
511            }
512        }
513        if (trustMayHaveChanged) {
514            updateTrust(userId, 0);
515        }
516        refreshAgentList(userId);
517    }
518
519    private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) {
520        if (resolveInfo == null || resolveInfo.serviceInfo == null
521                || resolveInfo.serviceInfo.metaData == null) return null;
522        String cn = null;
523        boolean canUnlockProfile = false;
524
525        XmlResourceParser parser = null;
526        Exception caughtException = null;
527        try {
528            parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
529                    TrustAgentService.TRUST_AGENT_META_DATA);
530            if (parser == null) {
531                Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
532                return null;
533            }
534            Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
535            AttributeSet attrs = Xml.asAttributeSet(parser);
536            int type;
537            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
538                    && type != XmlPullParser.START_TAG) {
539                // Drain preamble.
540            }
541            String nodeName = parser.getName();
542            if (!"trust-agent".equals(nodeName)) {
543                Slog.w(TAG, "Meta-data does not start with trust-agent tag");
544                return null;
545            }
546            TypedArray sa = res
547                    .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
548            cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
549            canUnlockProfile = sa.getBoolean(
550                    com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
551            sa.recycle();
552        } catch (PackageManager.NameNotFoundException e) {
553            caughtException = e;
554        } catch (IOException e) {
555            caughtException = e;
556        } catch (XmlPullParserException e) {
557            caughtException = e;
558        } finally {
559            if (parser != null) parser.close();
560        }
561        if (caughtException != null) {
562            Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
563            return null;
564        }
565        if (cn == null) {
566            return null;
567        }
568        if (cn.indexOf('/') < 0) {
569            cn = resolveInfo.serviceInfo.packageName + "/" + cn;
570        }
571        return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
572    }
573
574    private ComponentName getComponentName(ResolveInfo resolveInfo) {
575        if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
576        return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
577    }
578
579    private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
580        if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
581                Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
582            return;
583        }
584        PackageManager pm = mContext.getPackageManager();
585        List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
586        ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
587        for (ResolveInfo resolveInfo : resolveInfos) {
588            ComponentName componentName = getComponentName(resolveInfo);
589            int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
590            if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
591                Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
592                        + "is not a system package.");
593                continue;
594            }
595            discoveredAgents.add(componentName);
596        }
597
598        List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
599        if (previouslyEnabledAgents != null) {
600            discoveredAgents.addAll(previouslyEnabledAgents);
601        }
602        utils.setEnabledTrustAgents(discoveredAgents, userId);
603        Settings.Secure.putIntForUser(mContext.getContentResolver(),
604                Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
605    }
606
607    private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
608        List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
609                PackageManager.GET_META_DATA |
610                PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
611                userId);
612        ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
613        for (ResolveInfo resolveInfo : resolveInfos) {
614            if (resolveInfo.serviceInfo == null) continue;
615            if (resolveInfo.serviceInfo.applicationInfo == null) continue;
616            String packageName = resolveInfo.serviceInfo.packageName;
617            if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
618                    != PackageManager.PERMISSION_GRANTED) {
619                ComponentName name = getComponentName(resolveInfo);
620                Log.w(TAG, "Skipping agent " + name + " because package does not have"
621                        + " permission " + PERMISSION_PROVIDE_AGENT + ".");
622                continue;
623            }
624            allowedAgents.add(resolveInfo);
625        }
626        return allowedAgents;
627    }
628
629    // Agent dispatch and aggregation
630
631    private boolean aggregateIsTrusted(int userId) {
632        if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
633            return false;
634        }
635        for (int i = 0; i < mActiveAgents.size(); i++) {
636            AgentInfo info = mActiveAgents.valueAt(i);
637            if (info.userId == userId) {
638                if (info.agent.isTrusted()) {
639                    return true;
640                }
641            }
642        }
643        return false;
644    }
645
646    private boolean aggregateIsTrustManaged(int userId) {
647        if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
648            return false;
649        }
650        for (int i = 0; i < mActiveAgents.size(); i++) {
651            AgentInfo info = mActiveAgents.valueAt(i);
652            if (info.userId == userId) {
653                if (info.agent.isManagingTrust()) {
654                    return true;
655                }
656            }
657        }
658        return false;
659    }
660
661    private void dispatchUnlockAttempt(boolean successful, int userId) {
662        if (successful) {
663            mStrongAuthTracker.allowTrustFromUnlock(userId);
664        }
665
666        for (int i = 0; i < mActiveAgents.size(); i++) {
667            AgentInfo info = mActiveAgents.valueAt(i);
668            if (info.userId == userId) {
669                info.agent.onUnlockAttempt(successful);
670            }
671        }
672    }
673
674    private void dispatchUnlockLockout(int timeoutMs, int userId) {
675        for (int i = 0; i < mActiveAgents.size(); i++) {
676            AgentInfo info = mActiveAgents.valueAt(i);
677            if (info.userId == userId) {
678                info.agent.onUnlockLockout(timeoutMs);
679            }
680        }
681    }
682
683    // Listeners
684
685    private void addListener(ITrustListener listener) {
686        for (int i = 0; i < mTrustListeners.size(); i++) {
687            if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
688                return;
689            }
690        }
691        mTrustListeners.add(listener);
692        updateTrustAll();
693    }
694
695    private void removeListener(ITrustListener listener) {
696        for (int i = 0; i < mTrustListeners.size(); i++) {
697            if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
698                mTrustListeners.remove(i);
699                return;
700            }
701        }
702    }
703
704    private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
705        if (DEBUG) {
706            Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
707                    + Integer.toHexString(flags) + ")");
708        }
709        if (!enabled) flags = 0;
710        for (int i = 0; i < mTrustListeners.size(); i++) {
711            try {
712                mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
713            } catch (DeadObjectException e) {
714                Slog.d(TAG, "Removing dead TrustListener.");
715                mTrustListeners.remove(i);
716                i--;
717            } catch (RemoteException e) {
718                Slog.e(TAG, "Exception while notifying TrustListener.", e);
719            }
720        }
721    }
722
723    private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
724        if (DEBUG) {
725            Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
726        }
727        for (int i = 0; i < mTrustListeners.size(); i++) {
728            try {
729                mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
730            } catch (DeadObjectException e) {
731                Slog.d(TAG, "Removing dead TrustListener.");
732                mTrustListeners.remove(i);
733                i--;
734            } catch (RemoteException e) {
735                Slog.e(TAG, "Exception while notifying TrustListener.", e);
736            }
737        }
738    }
739
740    // User lifecycle
741
742    @Override
743    public void onStartUser(int userId) {
744        mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
745    }
746
747    @Override
748    public void onCleanupUser(int userId) {
749        mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
750    }
751
752    @Override
753    public void onSwitchUser(int userId) {
754        mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
755    }
756
757    @Override
758    public void onUnlockUser(int userId) {
759        mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
760    }
761
762    @Override
763    public void onStopUser(@UserIdInt int userId) {
764        mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
765    }
766
767    // Plumbing
768
769    private final IBinder mService = new ITrustManager.Stub() {
770        @Override
771        public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
772            enforceReportPermission();
773            mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
774                    .sendToTarget();
775        }
776
777        @Override
778        public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
779            enforceReportPermission();
780            mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
781                    .sendToTarget();
782        }
783
784        @Override
785        public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
786            enforceReportPermission();
787            // coalesce refresh messages.
788            mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
789            mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
790        }
791
792        @Override
793        public void reportKeyguardShowingChanged() throws RemoteException {
794            enforceReportPermission();
795            // coalesce refresh messages.
796            mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
797            mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
798
799            // Make sure handler processes the message before returning, such that isDeviceLocked
800            // after this call will retrieve the correct value.
801            mHandler.runWithScissors(() -> {}, 0);
802        }
803
804        @Override
805        public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
806            enforceListenerPermission();
807            mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
808        }
809
810        @Override
811        public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
812            enforceListenerPermission();
813            mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
814        }
815
816        @Override
817        public boolean isDeviceLocked(int userId) throws RemoteException {
818            userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
819                    false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
820
821            long token = Binder.clearCallingIdentity();
822            try {
823                if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
824                    userId = resolveProfileParent(userId);
825                }
826                return isDeviceLockedInner(userId);
827            } finally {
828                Binder.restoreCallingIdentity(token);
829            }
830        }
831
832        @Override
833        public boolean isDeviceSecure(int userId) throws RemoteException {
834            userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
835                    false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
836
837            long token = Binder.clearCallingIdentity();
838            try {
839                if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
840                    userId = resolveProfileParent(userId);
841                }
842                return mLockPatternUtils.isSecure(userId);
843            } finally {
844                Binder.restoreCallingIdentity(token);
845            }
846        }
847
848        private void enforceReportPermission() {
849            mContext.enforceCallingOrSelfPermission(
850                    Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
851        }
852
853        private void enforceListenerPermission() {
854            mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
855                    "register trust listener");
856        }
857
858        @Override
859        protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
860            if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
861            if (isSafeMode()) {
862                fout.println("disabled because the system is in safe mode.");
863                return;
864            }
865            if (!mTrustAgentsCanRun) {
866                fout.println("disabled because the third-party apps can't run yet.");
867                return;
868            }
869            final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
870            mHandler.runWithScissors(new Runnable() {
871                @Override
872                public void run() {
873                    fout.println("Trust manager state:");
874                    for (UserInfo user : userInfos) {
875                        dumpUser(fout, user, user.id == mCurrentUser);
876                    }
877                }
878            }, 1500);
879        }
880
881        private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
882            fout.printf(" User \"%s\" (id=%d, flags=%#x)",
883                    user.name, user.id, user.flags);
884            if (!user.supportsSwitchToByUser()) {
885                fout.println("(managed profile)");
886                fout.println("   disabled because switching to this user is not possible.");
887                return;
888            }
889            if (isCurrent) {
890                fout.print(" (current)");
891            }
892            fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
893            fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
894            fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
895            fout.print(", strongAuthRequired=" + dumpHex(
896                    mStrongAuthTracker.getStrongAuthForUser(user.id)));
897            fout.println();
898            fout.println("   Enabled agents:");
899            boolean duplicateSimpleNames = false;
900            ArraySet<String> simpleNames = new ArraySet<String>();
901            for (AgentInfo info : mActiveAgents) {
902                if (info.userId != user.id) { continue; }
903                boolean trusted = info.agent.isTrusted();
904                fout.print("    "); fout.println(info.component.flattenToShortString());
905                fout.print("     bound=" + dumpBool(info.agent.isBound()));
906                fout.print(", connected=" + dumpBool(info.agent.isConnected()));
907                fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
908                fout.print(", trusted=" + dumpBool(trusted));
909                fout.println();
910                if (trusted) {
911                    fout.println("      message=\"" + info.agent.getMessage() + "\"");
912                }
913                if (!info.agent.isConnected()) {
914                    String restartTime = TrustArchive.formatDuration(
915                            info.agent.getScheduledRestartUptimeMillis()
916                                    - SystemClock.uptimeMillis());
917                    fout.println("      restartScheduledAt=" + restartTime);
918                }
919                if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
920                    duplicateSimpleNames = true;
921                }
922            }
923            fout.println("   Events:");
924            mArchive.dump(fout, 50, user.id, "    " /* linePrefix */, duplicateSimpleNames);
925            fout.println();
926        }
927
928        private String dumpBool(boolean b) {
929            return b ? "1" : "0";
930        }
931
932        private String dumpHex(int i) {
933            return "0x" + Integer.toHexString(i);
934        }
935
936        @Override
937        public void setDeviceLockedForUser(int userId, boolean locked) {
938            enforceReportPermission();
939            final long identity = Binder.clearCallingIdentity();
940            try {
941                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
942                    synchronized (mDeviceLockedForUser) {
943                        mDeviceLockedForUser.put(userId, locked);
944                    }
945                    if (locked) {
946                        try {
947                            ActivityManager.getService().notifyLockedProfile(userId);
948                        } catch (RemoteException e) {
949                        }
950                    }
951                    final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
952                    lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
953                    lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
954                    mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
955                            Manifest.permission.TRUST_LISTENER, /* options */ null);
956                }
957            } finally {
958                Binder.restoreCallingIdentity(identity);
959            }
960        }
961
962        @Override
963        public boolean isTrustUsuallyManaged(int userId) {
964            mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
965                    "query trust state");
966            return isTrustUsuallyManagedInternal(userId);
967        }
968    };
969
970    private boolean isTrustUsuallyManagedInternal(int userId) {
971        synchronized (mTrustUsuallyManagedForUser) {
972            int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
973            if (i >= 0) {
974                return mTrustUsuallyManagedForUser.valueAt(i);
975            }
976        }
977        // It's not in memory yet, get the value from persisted storage instead
978        boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
979        synchronized (mTrustUsuallyManagedForUser) {
980            int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
981            if (i >= 0) {
982                // Someone set the trust usually managed in the mean time. Better use that.
983                return mTrustUsuallyManagedForUser.valueAt(i);
984            } else {
985                // .. otherwise it's safe to cache the fetched value now.
986                mTrustUsuallyManagedForUser.put(userId, persistedValue);
987                return persistedValue;
988            }
989        }
990    }
991
992    private int resolveProfileParent(int userId) {
993        long identity = Binder.clearCallingIdentity();
994        try {
995            UserInfo parent = mUserManager.getProfileParent(userId);
996            if (parent != null) {
997                return parent.getUserHandle().getIdentifier();
998            }
999            return userId;
1000        } finally {
1001            Binder.restoreCallingIdentity(identity);
1002        }
1003    }
1004
1005    private final Handler mHandler = new Handler() {
1006        @Override
1007        public void handleMessage(Message msg) {
1008            switch (msg.what) {
1009                case MSG_REGISTER_LISTENER:
1010                    addListener((ITrustListener) msg.obj);
1011                    break;
1012                case MSG_UNREGISTER_LISTENER:
1013                    removeListener((ITrustListener) msg.obj);
1014                    break;
1015                case MSG_DISPATCH_UNLOCK_ATTEMPT:
1016                    dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
1017                    break;
1018                case MSG_DISPATCH_UNLOCK_LOCKOUT:
1019                    dispatchUnlockLockout(msg.arg1, msg.arg2);
1020                    break;
1021                case MSG_ENABLED_AGENTS_CHANGED:
1022                    refreshAgentList(UserHandle.USER_ALL);
1023                    // This is also called when the security mode of a user changes.
1024                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
1025                    break;
1026                case MSG_KEYGUARD_SHOWING_CHANGED:
1027                    refreshDeviceLockedForUser(mCurrentUser);
1028                    break;
1029                case MSG_START_USER:
1030                case MSG_CLEANUP_USER:
1031                case MSG_UNLOCK_USER:
1032                    refreshAgentList(msg.arg1);
1033                    break;
1034                case MSG_SWITCH_USER:
1035                    mCurrentUser = msg.arg1;
1036                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
1037                    break;
1038                case MSG_STOP_USER:
1039                    setDeviceLockedForUser(msg.arg1, true);
1040                    break;
1041                case MSG_FLUSH_TRUST_USUALLY_MANAGED:
1042                    SparseBooleanArray usuallyManaged;
1043                    synchronized (mTrustUsuallyManagedForUser) {
1044                        usuallyManaged = mTrustUsuallyManagedForUser.clone();
1045                    }
1046
1047                    for (int i = 0; i < usuallyManaged.size(); i++) {
1048                        int userId = usuallyManaged.keyAt(i);
1049                        boolean value = usuallyManaged.valueAt(i);
1050                        if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
1051                            mLockPatternUtils.setTrustUsuallyManaged(value, userId);
1052                        }
1053                    }
1054                    break;
1055            }
1056        }
1057    };
1058
1059    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1060        @Override
1061        public void onSomePackagesChanged() {
1062            refreshAgentList(UserHandle.USER_ALL);
1063        }
1064
1065        @Override
1066        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1067            // We're interested in all changes, even if just some components get enabled / disabled.
1068            return true;
1069        }
1070
1071        @Override
1072        public void onPackageDisappeared(String packageName, int reason) {
1073            removeAgentsOfPackage(packageName);
1074        }
1075    };
1076
1077    private static class SettingsAttrs {
1078        public ComponentName componentName;
1079        public boolean canUnlockProfile;
1080
1081        public SettingsAttrs(
1082                ComponentName componentName,
1083                boolean canUnlockProfile) {
1084            this.componentName = componentName;
1085            this.canUnlockProfile = canUnlockProfile;
1086        }
1087    };
1088
1089    private class Receiver extends BroadcastReceiver {
1090
1091        @Override
1092        public void onReceive(Context context, Intent intent) {
1093            String action = intent.getAction();
1094            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
1095                refreshAgentList(getSendingUserId());
1096                updateDevicePolicyFeatures();
1097            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
1098                int userId = getUserId(intent);
1099                if (userId > 0) {
1100                    maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
1101                }
1102            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
1103                int userId = getUserId(intent);
1104                if (userId > 0) {
1105                    synchronized (mUserIsTrusted) {
1106                        mUserIsTrusted.delete(userId);
1107                    }
1108                    synchronized (mDeviceLockedForUser) {
1109                        mDeviceLockedForUser.delete(userId);
1110                    }
1111                    synchronized (mTrustUsuallyManagedForUser) {
1112                        mTrustUsuallyManagedForUser.delete(userId);
1113                    }
1114                    refreshAgentList(userId);
1115                    refreshDeviceLockedForUser(userId);
1116                }
1117            }
1118        }
1119
1120        private int getUserId(Intent intent) {
1121            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
1122            if (userId > 0) {
1123                return userId;
1124            } else {
1125                Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
1126                return -100;
1127            }
1128        }
1129
1130        public void register(Context context) {
1131            IntentFilter filter = new IntentFilter();
1132            filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1133            filter.addAction(Intent.ACTION_USER_ADDED);
1134            filter.addAction(Intent.ACTION_USER_REMOVED);
1135            context.registerReceiverAsUser(this,
1136                    UserHandle.ALL,
1137                    filter,
1138                    null /* permission */,
1139                    null /* scheduler */);
1140        }
1141    }
1142
1143    private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1144
1145        SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1146
1147        public StrongAuthTracker(Context context) {
1148            super(context);
1149        }
1150
1151        @Override
1152        public void onStrongAuthRequiredChanged(int userId) {
1153            mStartFromSuccessfulUnlock.delete(userId);
1154
1155            if (DEBUG) {
1156                Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1157                        + " trustAllowed=" + isTrustAllowedForUser(userId)
1158                        + " agentsCanRun=" + canAgentsRunForUser(userId));
1159            }
1160
1161            refreshAgentList(userId);
1162
1163            // The list of active trust agents may not have changed, if there was a previous call
1164            // to allowTrustFromUnlock, so we update the trust here too.
1165            updateTrust(userId, 0 /* flags */);
1166        }
1167
1168        boolean canAgentsRunForUser(int userId) {
1169            return mStartFromSuccessfulUnlock.get(userId)
1170                    || super.isTrustAllowedForUser(userId);
1171        }
1172
1173        /**
1174         * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1175         * changes again. Must only be called when we know about a successful unlock already
1176         * before the underlying StrongAuthTracker.
1177         *
1178         * Note that this only changes whether trust agents can be started, not the actual trusted
1179         * value.
1180         */
1181        void allowTrustFromUnlock(int userId) {
1182            if (userId < UserHandle.USER_SYSTEM) {
1183                throw new IllegalArgumentException("userId must be a valid user: " + userId);
1184            }
1185            boolean previous = canAgentsRunForUser(userId);
1186            mStartFromSuccessfulUnlock.put(userId, true);
1187
1188            if (DEBUG) {
1189                Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1190                        + " trustAllowed=" + isTrustAllowedForUser(userId)
1191                        + " agentsCanRun=" + canAgentsRunForUser(userId));
1192            }
1193
1194            if (canAgentsRunForUser(userId) != previous) {
1195                refreshAgentList(userId);
1196            }
1197        }
1198    }
1199}
1200