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