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