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