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