Trust: Make setEnabledFeatures asynchronous

Unsynchronizes the call into app code from setEnabledFeatures,
replacing it with a callback mechanism. Also makes this actually
work by fixing the check in TrustManagerService to take into account
whitelisting.

Change-Id: I0831752cd2d3158eda9c8404a5569498f11ac2ac
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 950d639..d3b8d5d 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -157,7 +157,7 @@
         dispatchOnTrustChanged(aggregateIsTrusted(userId), userId);
     }
 
-    protected void refreshAgentList() {
+    void refreshAgentList() {
         if (DEBUG) Slog.d(TAG, "refreshAgentList()");
         PackageManager pm = mContext.getPackageManager();
 
@@ -168,13 +168,13 @@
         obsoleteAgents.addAll(mActiveAgents);
 
         for (UserInfo userInfo : userInfos) {
-            int disabledFeatures = lockPatternUtils.getDevicePolicyManager()
-                    .getKeyguardDisabledFeatures(null, userInfo.id);
+            DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
+            int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
             final boolean disableTrustAgents =
                     (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
 
             List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
-            if (disableTrustAgents || enabledAgents == null) {
+            if (enabledAgents == null) {
                 continue;
             }
             List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
@@ -193,6 +193,13 @@
                 ComponentName name = getComponentName(resolveInfo);
                 if (!enabledAgents.contains(name)) continue;
 
+                if (disableTrustAgents) {
+                    List<String> features =
+                            dpm.getTrustAgentFeaturesEnabled(null /* admin */, name);
+                    // Disable agent if no features are enabled.
+                    if (features == null || features.isEmpty()) continue;
+                }
+
                 AgentInfo agentInfo = new AgentInfo();
                 agentInfo.component = name;
                 agentInfo.userId = userInfo.id;
@@ -224,6 +231,15 @@
         }
     }
 
+    void updateDevicePolicyFeatures(int userId) {
+        for (int i = 0; i < mActiveAgents.size(); i++) {
+            AgentInfo info = mActiveAgents.valueAt(i);
+            if (info.agent.isConnected()) {
+                info.agent.updateDevicePolicyFeatures();
+            }
+        }
+    }
+
     private void removeAgentsOfPackage(String packageName) {
         boolean trustMayHaveChanged = false;
         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
@@ -587,6 +603,7 @@
             if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
                     intent.getAction())) {
                 refreshAgentList();
+                updateDevicePolicyFeatures(getSendingUserId());
             }
         }