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