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_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         boolean changed = false;
    403         for (int i = 0; i < mActiveAgents.size(); i++) {
    404             AgentInfo info = mActiveAgents.valueAt(i);
    405             if (info.agent.isConnected()) {
    406                 info.agent.updateDevicePolicyFeatures();
    407                 changed = true;
    408             }
    409         }
    410         if (changed) {
    411             mArchive.logDevicePolicyChanged();
    412         }
    413     }
    414 
    415     private void removeAgentsOfPackage(String packageName) {
    416         boolean trustMayHaveChanged = false;
    417         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
    418             AgentInfo info = mActiveAgents.valueAt(i);
    419             if (packageName.equals(info.component.getPackageName())) {
    420                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
    421                 if (info.agent.isManagingTrust()) {
    422                     trustMayHaveChanged = true;
    423                 }
    424                 info.agent.destroy();
    425                 mActiveAgents.removeAt(i);
    426             }
    427         }
    428         if (trustMayHaveChanged) {
    429             updateTrustAll();
    430         }
    431     }
    432 
    433     public void resetAgent(ComponentName name, int userId) {
    434         boolean trustMayHaveChanged = false;
    435         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
    436             AgentInfo info = mActiveAgents.valueAt(i);
    437             if (name.equals(info.component) && userId == info.userId) {
    438                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
    439                 if (info.agent.isManagingTrust()) {
    440                     trustMayHaveChanged = true;
    441                 }
    442                 info.agent.destroy();
    443                 mActiveAgents.removeAt(i);
    444             }
    445         }
    446         if (trustMayHaveChanged) {
    447             updateTrust(userId, 0);
    448         }
    449         refreshAgentList(userId);
    450     }
    451 
    452     private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
    453         if (resolveInfo == null || resolveInfo.serviceInfo == null
    454                 || resolveInfo.serviceInfo.metaData == null) return null;
    455         String cn = null;
    456         XmlResourceParser parser = null;
    457         Exception caughtException = null;
    458         try {
    459             parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
    460                     TrustAgentService.TRUST_AGENT_META_DATA);
    461             if (parser == null) {
    462                 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
    463                 return null;
    464             }
    465             Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
    466             AttributeSet attrs = Xml.asAttributeSet(parser);
    467             int type;
    468             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
    469                     && type != XmlPullParser.START_TAG) {
    470                 // Drain preamble.
    471             }
    472             String nodeName = parser.getName();
    473             if (!"trust-agent".equals(nodeName)) {
    474                 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
    475                 return null;
    476             }
    477             TypedArray sa = res
    478                     .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
    479             cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
    480             sa.recycle();
    481         } catch (PackageManager.NameNotFoundException e) {
    482             caughtException = e;
    483         } catch (IOException e) {
    484             caughtException = e;
    485         } catch (XmlPullParserException e) {
    486             caughtException = e;
    487         } finally {
    488             if (parser != null) parser.close();
    489         }
    490         if (caughtException != null) {
    491             Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
    492             return null;
    493         }
    494         if (cn == null) {
    495             return null;
    496         }
    497         if (cn.indexOf('/') < 0) {
    498             cn = resolveInfo.serviceInfo.packageName + "/" + cn;
    499         }
    500         return ComponentName.unflattenFromString(cn);
    501     }
    502 
    503     private ComponentName getComponentName(ResolveInfo resolveInfo) {
    504         if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
    505         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
    506     }
    507 
    508     private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
    509         if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
    510                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
    511             return;
    512         }
    513         PackageManager pm = mContext.getPackageManager();
    514         List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
    515         ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
    516         for (ResolveInfo resolveInfo : resolveInfos) {
    517             ComponentName componentName = getComponentName(resolveInfo);
    518             int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
    519             if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
    520                 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
    521                         + "is not a system package.");
    522                 continue;
    523             }
    524             discoveredAgents.add(componentName);
    525         }
    526 
    527         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
    528         if (previouslyEnabledAgents != null) {
    529             discoveredAgents.addAll(previouslyEnabledAgents);
    530         }
    531         utils.setEnabledTrustAgents(discoveredAgents, userId);
    532         Settings.Secure.putIntForUser(mContext.getContentResolver(),
    533                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
    534     }
    535 
    536     private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
    537         List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
    538                 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
    539                 userId);
    540         ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
    541         for (ResolveInfo resolveInfo : resolveInfos) {
    542             if (resolveInfo.serviceInfo == null) continue;
    543             if (resolveInfo.serviceInfo.applicationInfo == null) continue;
    544             String packageName = resolveInfo.serviceInfo.packageName;
    545             if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
    546                     != PackageManager.PERMISSION_GRANTED) {
    547                 ComponentName name = getComponentName(resolveInfo);
    548                 Log.w(TAG, "Skipping agent " + name + " because package does not have"
    549                         + " permission " + PERMISSION_PROVIDE_AGENT + ".");
    550                 continue;
    551             }
    552             allowedAgents.add(resolveInfo);
    553         }
    554         return allowedAgents;
    555     }
    556 
    557     // Agent dispatch and aggregation
    558 
    559     private boolean aggregateIsTrusted(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.isTrusted()) {
    567                     return true;
    568                 }
    569             }
    570         }
    571         return false;
    572     }
    573 
    574     private boolean aggregateIsTrustManaged(int userId) {
    575         if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
    576             return false;
    577         }
    578         for (int i = 0; i < mActiveAgents.size(); i++) {
    579             AgentInfo info = mActiveAgents.valueAt(i);
    580             if (info.userId == userId) {
    581                 if (info.agent.isManagingTrust()) {
    582                     return true;
    583                 }
    584             }
    585         }
    586         return false;
    587     }
    588 
    589     private void dispatchUnlockAttempt(boolean successful, int userId) {
    590         if (successful) {
    591             mStrongAuthTracker.allowTrustFromUnlock(userId);
    592         }
    593 
    594         for (int i = 0; i < mActiveAgents.size(); i++) {
    595             AgentInfo info = mActiveAgents.valueAt(i);
    596             if (info.userId == userId) {
    597                 info.agent.onUnlockAttempt(successful);
    598             }
    599         }
    600     }
    601 
    602     // Listeners
    603 
    604     private void addListener(ITrustListener listener) {
    605         for (int i = 0; i < mTrustListeners.size(); i++) {
    606             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
    607                 return;
    608             }
    609         }
    610         mTrustListeners.add(listener);
    611         updateTrustAll();
    612     }
    613 
    614     private void removeListener(ITrustListener listener) {
    615         for (int i = 0; i < mTrustListeners.size(); i++) {
    616             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
    617                 mTrustListeners.remove(i);
    618                 return;
    619             }
    620         }
    621     }
    622 
    623     private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
    624         if (DEBUG) {
    625             Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
    626                     + Integer.toHexString(flags) + ")");
    627         }
    628         if (!enabled) flags = 0;
    629         for (int i = 0; i < mTrustListeners.size(); i++) {
    630             try {
    631                 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
    632             } catch (DeadObjectException e) {
    633                 Slog.d(TAG, "Removing dead TrustListener.");
    634                 mTrustListeners.remove(i);
    635                 i--;
    636             } catch (RemoteException e) {
    637                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
    638             }
    639         }
    640     }
    641 
    642     private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
    643         if (DEBUG) {
    644             Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
    645         }
    646         for (int i = 0; i < mTrustListeners.size(); i++) {
    647             try {
    648                 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
    649             } catch (DeadObjectException e) {
    650                 Slog.d(TAG, "Removing dead TrustListener.");
    651                 mTrustListeners.remove(i);
    652                 i--;
    653             } catch (RemoteException e) {
    654                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
    655             }
    656         }
    657     }
    658 
    659     // User lifecycle
    660 
    661     @Override
    662     public void onStartUser(int userId) {
    663         mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
    664     }
    665 
    666     @Override
    667     public void onCleanupUser(int userId) {
    668         mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
    669     }
    670 
    671     @Override
    672     public void onSwitchUser(int userId) {
    673         mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
    674     }
    675 
    676     @Override
    677     public void onUnlockUser(int userId) {
    678         mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
    679     }
    680 
    681     // Plumbing
    682 
    683     private final IBinder mService = new ITrustManager.Stub() {
    684         @Override
    685         public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
    686             enforceReportPermission();
    687             mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
    688                     .sendToTarget();
    689         }
    690 
    691         @Override
    692         public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
    693             enforceReportPermission();
    694             // coalesce refresh messages.
    695             mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
    696             mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
    697         }
    698 
    699         @Override
    700         public void reportKeyguardShowingChanged() throws RemoteException {
    701             enforceReportPermission();
    702             // coalesce refresh messages.
    703             mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
    704             mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
    705         }
    706 
    707         @Override
    708         public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
    709             enforceListenerPermission();
    710             mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
    711         }
    712 
    713         @Override
    714         public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
    715             enforceListenerPermission();
    716             mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
    717         }
    718 
    719         @Override
    720         public boolean isDeviceLocked(int userId) throws RemoteException {
    721             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
    722                     false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
    723 
    724             long token = Binder.clearCallingIdentity();
    725             try {
    726                 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
    727                     userId = resolveProfileParent(userId);
    728                 }
    729                 return isDeviceLockedInner(userId);
    730             } finally {
    731                 Binder.restoreCallingIdentity(token);
    732             }
    733         }
    734 
    735         @Override
    736         public boolean isDeviceSecure(int userId) throws RemoteException {
    737             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
    738                     false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
    739 
    740             long token = Binder.clearCallingIdentity();
    741             try {
    742                 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
    743                     userId = resolveProfileParent(userId);
    744                 }
    745                 return mLockPatternUtils.isSecure(userId);
    746             } finally {
    747                 Binder.restoreCallingIdentity(token);
    748             }
    749         }
    750 
    751         private void enforceReportPermission() {
    752             mContext.enforceCallingOrSelfPermission(
    753                     Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
    754         }
    755 
    756         private void enforceListenerPermission() {
    757             mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
    758                     "register trust listener");
    759         }
    760 
    761         @Override
    762         protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
    763             mContext.enforceCallingPermission(Manifest.permission.DUMP,
    764                     "dumping TrustManagerService");
    765             if (isSafeMode()) {
    766                 fout.println("disabled because the system is in safe mode.");
    767                 return;
    768             }
    769             if (!mTrustAgentsCanRun) {
    770                 fout.println("disabled because the third-party apps can't run yet.");
    771                 return;
    772             }
    773             final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
    774             mHandler.runWithScissors(new Runnable() {
    775                 @Override
    776                 public void run() {
    777                     fout.println("Trust manager state:");
    778                     for (UserInfo user : userInfos) {
    779                         dumpUser(fout, user, user.id == mCurrentUser);
    780                     }
    781                 }
    782             }, 1500);
    783         }
    784 
    785         private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
    786             fout.printf(" User \"%s\" (id=%d, flags=%#x)",
    787                     user.name, user.id, user.flags);
    788             if (!user.supportsSwitchToByUser()) {
    789                 fout.println("(managed profile)");
    790                 fout.println("   disabled because switching to this user is not possible.");
    791                 return;
    792             }
    793             if (isCurrent) {
    794                 fout.print(" (current)");
    795             }
    796             fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
    797             fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
    798             fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
    799             fout.print(", strongAuthRequired=" + dumpHex(
    800                     mStrongAuthTracker.getStrongAuthForUser(user.id)));
    801             fout.println();
    802             fout.println("   Enabled agents:");
    803             boolean duplicateSimpleNames = false;
    804             ArraySet<String> simpleNames = new ArraySet<String>();
    805             for (AgentInfo info : mActiveAgents) {
    806                 if (info.userId != user.id) { continue; }
    807                 boolean trusted = info.agent.isTrusted();
    808                 fout.print("    "); fout.println(info.component.flattenToShortString());
    809                 fout.print("     bound=" + dumpBool(info.agent.isBound()));
    810                 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
    811                 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
    812                 fout.print(", trusted=" + dumpBool(trusted));
    813                 fout.println();
    814                 if (trusted) {
    815                     fout.println("      message=\"" + info.agent.getMessage() + "\"");
    816                 }
    817                 if (!info.agent.isConnected()) {
    818                     String restartTime = TrustArchive.formatDuration(
    819                             info.agent.getScheduledRestartUptimeMillis()
    820                                     - SystemClock.uptimeMillis());
    821                     fout.println("      restartScheduledAt=" + restartTime);
    822                 }
    823                 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
    824                     duplicateSimpleNames = true;
    825                 }
    826             }
    827             fout.println("   Events:");
    828             mArchive.dump(fout, 50, user.id, "    " /* linePrefix */, duplicateSimpleNames);
    829             fout.println();
    830         }
    831 
    832         private String dumpBool(boolean b) {
    833             return b ? "1" : "0";
    834         }
    835 
    836         private String dumpHex(int i) {
    837             return "0x" + Integer.toHexString(i);
    838         }
    839 
    840         @Override
    841         public void setDeviceLockedForUser(int userId, boolean value) {
    842             enforceReportPermission();
    843             mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
    844                     .sendToTarget();
    845         }
    846 
    847         @Override
    848         public boolean isTrustUsuallyManaged(int userId) {
    849             mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
    850                     "query trust state");
    851             return isTrustUsuallyManagedInternal(userId);
    852         }
    853     };
    854 
    855     private boolean isTrustUsuallyManagedInternal(int userId) {
    856         synchronized (mTrustUsuallyManagedForUser) {
    857             int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
    858             if (i >= 0) {
    859                 return mTrustUsuallyManagedForUser.valueAt(i);
    860             }
    861         }
    862         // It's not in memory yet, get the value from persisted storage instead
    863         boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
    864         synchronized (mTrustUsuallyManagedForUser) {
    865             int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
    866             if (i >= 0) {
    867                 // Someone set the trust usually managed in the mean time. Better use that.
    868                 return mTrustUsuallyManagedForUser.valueAt(i);
    869             } else {
    870                 // .. otherwise it's safe to cache the fetched value now.
    871                 mTrustUsuallyManagedForUser.put(userId, persistedValue);
    872                 return persistedValue;
    873             }
    874         }
    875     }
    876 
    877     private int resolveProfileParent(int userId) {
    878         long identity = Binder.clearCallingIdentity();
    879         try {
    880             UserInfo parent = mUserManager.getProfileParent(userId);
    881             if (parent != null) {
    882                 return parent.getUserHandle().getIdentifier();
    883             }
    884             return userId;
    885         } finally {
    886             Binder.restoreCallingIdentity(identity);
    887         }
    888     }
    889 
    890     private final Handler mHandler = new Handler() {
    891         @Override
    892         public void handleMessage(Message msg) {
    893             switch (msg.what) {
    894                 case MSG_REGISTER_LISTENER:
    895                     addListener((ITrustListener) msg.obj);
    896                     break;
    897                 case MSG_UNREGISTER_LISTENER:
    898                     removeListener((ITrustListener) msg.obj);
    899                     break;
    900                 case MSG_DISPATCH_UNLOCK_ATTEMPT:
    901                     dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
    902                     break;
    903                 case MSG_ENABLED_AGENTS_CHANGED:
    904                     refreshAgentList(UserHandle.USER_ALL);
    905                     // This is also called when the security mode of a user changes.
    906                     refreshDeviceLockedForUser(UserHandle.USER_ALL);
    907                     break;
    908                 case MSG_KEYGUARD_SHOWING_CHANGED:
    909                     refreshDeviceLockedForUser(mCurrentUser);
    910                     break;
    911                 case MSG_START_USER:
    912                 case MSG_CLEANUP_USER:
    913                 case MSG_UNLOCK_USER:
    914                     refreshAgentList(msg.arg1);
    915                     break;
    916                 case MSG_SWITCH_USER:
    917                     mCurrentUser = msg.arg1;
    918                     refreshDeviceLockedForUser(UserHandle.USER_ALL);
    919                     break;
    920                 case MSG_SET_DEVICE_LOCKED:
    921                     setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
    922                     break;
    923                 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
    924                     SparseBooleanArray usuallyManaged;
    925                     synchronized (mTrustUsuallyManagedForUser) {
    926                         usuallyManaged = mTrustUsuallyManagedForUser.clone();
    927                     }
    928 
    929                     for (int i = 0; i < usuallyManaged.size(); i++) {
    930                         int userId = usuallyManaged.keyAt(i);
    931                         boolean value = usuallyManaged.valueAt(i);
    932                         if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
    933                             mLockPatternUtils.setTrustUsuallyManaged(value, userId);
    934                         }
    935                     }
    936                     break;
    937             }
    938         }
    939     };
    940 
    941     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
    942         @Override
    943         public void onSomePackagesChanged() {
    944             refreshAgentList(UserHandle.USER_ALL);
    945         }
    946 
    947         @Override
    948         public boolean onPackageChanged(String packageName, int uid, String[] components) {
    949             // We're interested in all changes, even if just some components get enabled / disabled.
    950             return true;
    951         }
    952 
    953         @Override
    954         public void onPackageDisappeared(String packageName, int reason) {
    955             removeAgentsOfPackage(packageName);
    956         }
    957     };
    958 
    959     private class Receiver extends BroadcastReceiver {
    960 
    961         @Override
    962         public void onReceive(Context context, Intent intent) {
    963             String action = intent.getAction();
    964             if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
    965                 refreshAgentList(getSendingUserId());
    966                 updateDevicePolicyFeatures();
    967             } else if (Intent.ACTION_USER_ADDED.equals(action)) {
    968                 int userId = getUserId(intent);
    969                 if (userId > 0) {
    970                     maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
    971                 }
    972             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
    973                 int userId = getUserId(intent);
    974                 if (userId > 0) {
    975                     synchronized (mUserIsTrusted) {
    976                         mUserIsTrusted.delete(userId);
    977                     }
    978                     synchronized (mDeviceLockedForUser) {
    979                         mDeviceLockedForUser.delete(userId);
    980                     }
    981                     refreshAgentList(userId);
    982                     refreshDeviceLockedForUser(userId);
    983                 }
    984             }
    985         }
    986 
    987         private int getUserId(Intent intent) {
    988             int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
    989             if (userId > 0) {
    990                 return userId;
    991             } else {
    992                 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
    993                 return -100;
    994             }
    995         }
    996 
    997         public void register(Context context) {
    998             IntentFilter filter = new IntentFilter();
    999             filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
   1000             filter.addAction(Intent.ACTION_USER_ADDED);
   1001             filter.addAction(Intent.ACTION_USER_REMOVED);
   1002             context.registerReceiverAsUser(this,
   1003                     UserHandle.ALL,
   1004                     filter,
   1005                     null /* permission */,
   1006                     null /* scheduler */);
   1007         }
   1008     }
   1009 
   1010     private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
   1011 
   1012         SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
   1013 
   1014         public StrongAuthTracker(Context context) {
   1015             super(context);
   1016         }
   1017 
   1018         @Override
   1019         public void onStrongAuthRequiredChanged(int userId) {
   1020             mStartFromSuccessfulUnlock.delete(userId);
   1021 
   1022             if (DEBUG) {
   1023                 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
   1024                         + " trustAllowed=" + isTrustAllowedForUser(userId)
   1025                         + " agentsCanRun=" + canAgentsRunForUser(userId));
   1026             }
   1027 
   1028             refreshAgentList(userId);
   1029 
   1030             // The list of active trust agents may not have changed, if there was a previous call
   1031             // to allowTrustFromUnlock, so we update the trust here too.
   1032             updateTrust(userId, 0 /* flags */);
   1033         }
   1034 
   1035         boolean canAgentsRunForUser(int userId) {
   1036             return mStartFromSuccessfulUnlock.get(userId)
   1037                     || super.isTrustAllowedForUser(userId);
   1038         }
   1039 
   1040         /**
   1041          * Temporarily suppress strong auth requirements for {@param userId} until strong auth
   1042          * changes again. Must only be called when we know about a successful unlock already
   1043          * before the underlying StrongAuthTracker.
   1044          *
   1045          * Note that this only changes whether trust agents can be started, not the actual trusted
   1046          * value.
   1047          */
   1048         void allowTrustFromUnlock(int userId) {
   1049             if (userId < UserHandle.USER_SYSTEM) {
   1050                 throw new IllegalArgumentException("userId must be a valid user: " + userId);
   1051             }
   1052             boolean previous = canAgentsRunForUser(userId);
   1053             mStartFromSuccessfulUnlock.put(userId, true);
   1054 
   1055             if (DEBUG) {
   1056                 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
   1057                         + " trustAllowed=" + isTrustAllowedForUser(userId)
   1058                         + " agentsCanRun=" + canAgentsRunForUser(userId));
   1059             }
   1060 
   1061             if (canAgentsRunForUser(userId) != previous) {
   1062                 refreshAgentList(userId);
   1063             }
   1064         }
   1065     }
   1066 }
   1067