summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Miller <jaggies@google.com>2014-08-26 17:12:29 -0700
committerJim Miller <jaggies@google.com>2014-11-05 18:17:56 -0800
commite303bf443532c2ad756260133f00747bcff11e69 (patch)
tree35c58c456a33e6a83ea5cad631811683b5861641
parent12b239e6d39ad5a35f68e7bcd5f644a793b5cb74 (diff)
downloadframeworks_base-e303bf443532c2ad756260133f00747bcff11e69.zip
frameworks_base-e303bf443532c2ad756260133f00747bcff11e69.tar.gz
frameworks_base-e303bf443532c2ad756260133f00747bcff11e69.tar.bz2
Update TrustAgentService API after review
This change incorporates API council feedback and enables the TrustAgent whitelisting API. It also contains a minor cleanup of DPM's use of UserHandle to eliminate unnecessary object creation. Fixes bug 17008504 Change-Id: I63cc50169fde54b34406845818bcaf6aadc1a3db
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java50
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl7
-rw-r--r--core/java/android/service/trust/ITrustAgentService.aidl4
-rw-r--r--core/java/android/service/trust/ITrustAgentServiceCallback.aidl2
-rw-r--r--core/java/android/service/trust/TrustAgentService.java92
-rw-r--r--packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java13
-rw-r--r--services/core/java/com/android/server/trust/TrustAgentWrapper.java22
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java7
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java161
10 files changed, 217 insertions, 143 deletions
diff --git a/api/current.txt b/api/current.txt
index 6851bbf..4993e99 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5317,6 +5317,7 @@ package android.app.admin {
method public boolean getScreenCaptureDisabled(android.content.ComponentName);
method public boolean getStorageEncryption(android.content.ComponentName);
method public int getStorageEncryptionStatus();
+ method public java.util.List<android.os.PersistableBundle> getTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName);
method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
method public boolean installCaCert(android.content.ComponentName, byte[]);
@@ -5365,6 +5366,7 @@ package android.app.admin {
method public void setScreenCaptureDisabled(android.content.ComponentName, boolean);
method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public int setStorageEncryption(android.content.ComponentName, boolean);
+ method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallAllUserCaCerts(android.content.ComponentName);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 74502fc..d3ff79d 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -31,6 +31,7 @@ import android.content.pm.ResolveInfo;
import android.net.ProxyInfo;
import android.os.Bundle;
import android.os.Handler;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
@@ -40,6 +41,7 @@ import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
import android.service.restrictions.RestrictionsReceiver;
+import android.service.trust.TrustAgentService;
import android.util.Log;
import com.android.org.conscrypt.TrustedCertificateStore;
@@ -2604,25 +2606,29 @@ public class DevicePolicyManager {
}
/**
- * Sets a list of features to enable for a TrustAgent component. This is meant to be
- * used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which will disable all
- * trust agents but those with features enabled by this function call.
+ * Sets a list of configuration features to enable for a TrustAgent component. This is meant
+ * to be used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which disables all
+ * trust agents but those enabled by this function call. If flag
+ * {@link #KEYGUARD_DISABLE_TRUST_AGENTS} is not set, then this call has no effect.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
- * this method; if it has not, a security exception will be thrown.
+ * this method; if not, a security exception will be thrown.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @param agent Which component to enable features for.
- * @param features List of features to enable. Consult specific TrustAgent documentation for
- * the feature list.
- * @hide
+ * @param target Component name of the agent to be enabled.
+ * @param options TrustAgent-specific feature bundle. If null for any admin, agent
+ * will be strictly disabled according to the state of the
+ * {@link #KEYGUARD_DISABLE_TRUST_AGENTS} flag.
+ * <p>If {@link #KEYGUARD_DISABLE_TRUST_AGENTS} is set and options is not null for all admins,
+ * then it's up to the TrustAgent itself to aggregate the values from all device admins.
+ * <p>Consult documentation for the specific TrustAgent to determine legal options parameters.
*/
- public void setTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
- List<String> features) {
+ public void setTrustAgentConfiguration(ComponentName admin, ComponentName target,
+ PersistableBundle options) {
if (mService != null) {
try {
- mService.setTrustAgentFeaturesEnabled(admin, agent, features, UserHandle.myUserId());
+ mService.setTrustAgentConfiguration(admin, target, options, UserHandle.myUserId());
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2630,24 +2636,30 @@ public class DevicePolicyManager {
}
/**
- * Gets list of enabled features for the given TrustAgent component. If admin is
- * null, this will return the intersection of all features enabled for the given agent by all
- * admins.
+ * Gets configuration for the given trust agent based on aggregating all calls to
+ * {@link #setTrustAgentConfiguration(ComponentName, ComponentName, PersistableBundle)} for
+ * all device admins.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param agent Which component to get enabled features for.
- * @return List of enabled features.
- * @hide
+ * @return configuration for the given trust agent.
*/
- public List<String> getTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent) {
+ public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
+ ComponentName agent) {
+ return getTrustAgentConfiguration(admin, agent, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
+ ComponentName agent, int userHandle) {
if (mService != null) {
try {
- return mService.getTrustAgentFeaturesEnabled(admin, agent, UserHandle.myUserId());
+ return mService.getTrustAgentConfiguration(admin, agent, userHandle);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
- return new ArrayList<String>(); // empty list
+ return new ArrayList<PersistableBundle>(); // empty list
}
/**
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index c8e1780..07aa800 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.ProxyInfo;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.UserHandle;
import java.util.List;
@@ -183,8 +184,10 @@ interface IDevicePolicyManager {
boolean getCrossProfileCallerIdDisabled(in ComponentName who);
boolean getCrossProfileCallerIdDisabledForUser(int userId);
- void setTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, in List<String> features, int userId);
- List<String> getTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, int userId);
+ void setTrustAgentConfiguration(in ComponentName admin, in ComponentName agent,
+ in PersistableBundle args, int userId);
+ List<PersistableBundle> getTrustAgentConfiguration(in ComponentName admin,
+ in ComponentName agent, int userId);
boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName);
boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName);
diff --git a/core/java/android/service/trust/ITrustAgentService.aidl b/core/java/android/service/trust/ITrustAgentService.aidl
index bd80a3f..bb0c2b2 100644
--- a/core/java/android/service/trust/ITrustAgentService.aidl
+++ b/core/java/android/service/trust/ITrustAgentService.aidl
@@ -15,7 +15,7 @@
*/
package android.service.trust;
-import android.os.Bundle;
+import android.os.PersistableBundle;
import android.service.trust.ITrustAgentServiceCallback;
/**
@@ -25,6 +25,6 @@ import android.service.trust.ITrustAgentServiceCallback;
interface ITrustAgentService {
oneway void onUnlockAttempt(boolean successful);
oneway void onTrustTimeout();
+ oneway void onConfigure(in List<PersistableBundle> options, IBinder token);
oneway void setCallback(ITrustAgentServiceCallback callback);
- oneway void setTrustAgentFeaturesEnabled(in Bundle options, IBinder token);
}
diff --git a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
index b107bcc..76b2be0 100644
--- a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
+++ b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
@@ -27,5 +27,5 @@ oneway interface ITrustAgentServiceCallback {
void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser);
void revokeTrust();
void setManagingTrust(boolean managingTrust);
- void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token);
+ void onConfigureCompleted(boolean result, IBinder token);
}
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 3ef5b37..00d60c0 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -29,11 +29,14 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.util.Slog;
+import java.util.List;
+
/**
* A service that notifies the system about whether it believes the environment of the device
* to be trusted.
@@ -86,16 +89,46 @@ public class TrustAgentService extends Service {
*/
public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
+ private static final int MSG_UNLOCK_ATTEMPT = 1;
+ private static final int MSG_CONFIGURE = 2;
+ private static final int MSG_TRUST_TIMEOUT = 3;
+
/**
- * A white list of features that the given trust agent should support when otherwise disabled
- * by device policy.
- * @hide
+ * Container class for a list of configuration options and helper methods
*/
- public static final String KEY_FEATURES = "trust_agent_features";
+ public static final class Configuration {
+ public final List<PersistableBundle> options;
+ public Configuration(List<PersistableBundle> opts) {
+ options = opts;
+ }
- private static final int MSG_UNLOCK_ATTEMPT = 1;
- private static final int MSG_SET_TRUST_AGENT_FEATURES_ENABLED = 2;
- private static final int MSG_TRUST_TIMEOUT = 3;
+ /**
+ * Very basic method to determine if all bundles have the given feature, regardless
+ * of type.
+ * @param option String to search for.
+ * @return true if found in all bundles.
+ */
+ public boolean hasOption(String option) {
+ if (options == null || options.size() == 0) return false;
+ final int N = options.size();
+ for (int i = 0; i < N; i++) {
+ if (!options.get(i).containsKey(option)) return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Class containing raw data for a given configuration request.
+ */
+ private static final class ConfigurationData {
+ final IBinder token;
+ final List<PersistableBundle> options;
+ ConfigurationData(List<PersistableBundle> opts, IBinder t) {
+ options = opts;
+ token = t;
+ }
+ }
private ITrustAgentServiceCallback mCallback;
@@ -112,13 +145,12 @@ public class TrustAgentService extends Service {
case MSG_UNLOCK_ATTEMPT:
onUnlockAttempt(msg.arg1 != 0);
break;
- case MSG_SET_TRUST_AGENT_FEATURES_ENABLED:
- Bundle features = msg.peekData();
- IBinder token = (IBinder) msg.obj;
- boolean result = onSetTrustAgentFeaturesEnabled(features);
+ case MSG_CONFIGURE:
+ ConfigurationData data = (ConfigurationData) msg.obj;
+ boolean result = onConfigure(new Configuration(data.options));
try {
synchronized (mLock) {
- mCallback.onSetTrustAgentFeaturesEnabledCompleted(result, token);
+ mCallback.onConfigureCompleted(result, data.token);
}
} catch (RemoteException e) {
onError("calling onSetTrustAgentFeaturesEnabledCompleted()");
@@ -171,23 +203,16 @@ public class TrustAgentService extends Service {
}
/**
- * Called when device policy wants to restrict features in the agent in response to
- * {@link DevicePolicyManager#setTrustAgentFeaturesEnabled(ComponentName, ComponentName, java.util.List) }.
- * Agents that support this feature should overload this method and return 'true'.
+ * Called when device policy admin wants to enable specific options for agent in response to
+ * {@link DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)} and
+ * {@link DevicePolicyManager#setTrustAgentConfiguration(ComponentName, ComponentName,
+ * PersistableBundle)}.
+ * <p>Agents that support configuration options should overload this method and return 'true'.
*
- * The list of options can be obtained by calling
- * options.getStringArrayList({@link #KEY_FEATURES}). Presence of a feature string in the list
- * means it should be enabled ("white-listed"). Absence of the feature means it should be
- * disabled. An empty list means all features should be disabled.
- *
- * This function is only called if {@link DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} is
- * set.
- *
- * @param options Option feature bundle.
- * @return true if the {@link TrustAgentService} supports this feature.
- * @hide
+ * @param options bundle containing all options or null if none.
+ * @return true if the {@link TrustAgentService} supports configuration options.
*/
- public boolean onSetTrustAgentFeaturesEnabled(Bundle options) {
+ public boolean onConfigure(Configuration options) {
return false;
}
@@ -295,6 +320,12 @@ public class TrustAgentService extends Service {
}
@Override /* Binder API */
+ public void onConfigure(List<PersistableBundle> args, IBinder token) {
+ mHandler.obtainMessage(MSG_CONFIGURE, new ConfigurationData(args, token))
+ .sendToTarget();
+ }
+
+ @Override /* Binder API */
public void setCallback(ITrustAgentServiceCallback callback) {
synchronized (mLock) {
mCallback = callback;
@@ -313,13 +344,6 @@ public class TrustAgentService extends Service {
}
}
}
-
- @Override /* Binder API */
- public void setTrustAgentFeaturesEnabled(Bundle features, IBinder token) {
- Message msg = mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_ENABLED, token);
- msg.setData(features);
- msg.sendToTarget();
- }
}
}
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
index c650a0f..09c7165 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
@@ -21,7 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.os.Bundle;
+import android.os.PersistableBundle;
import android.preference.PreferenceManager;
import android.service.trust.TrustAgentService;
import android.support.v4.content.LocalBroadcastManager;
@@ -90,8 +90,15 @@ public class SampleTrustAgent extends TrustAgentService
}
@Override
- public boolean onSetTrustAgentFeaturesEnabled(Bundle options) {
- Log.v(TAG, "Policy options received: " + options.getStringArrayList(KEY_FEATURES));
+ public boolean onConfigure(Configuration config) {
+ if (config != null && config.options != null) {
+ for (int i = 0; i < config.options.size(); i++) {
+ PersistableBundle options = config.options.get(i);
+ Log.v(TAG, "Policy options received: " + options.toString());
+ }
+ } else {
+ Log.w(TAG, "onConfigure() called with no options");
+ }
// TODO: Handle options
return true; // inform DPM that we support it
}
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index b1c918d..b2bcf75 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -27,11 +27,11 @@ import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Binder;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PatternMatcher;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -218,7 +218,7 @@ public class TrustAgentWrapper {
}
@Override
- public void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token) {
+ public void onConfigureCompleted(boolean result, IBinder token) {
if (DEBUG) Slog.v(TAG, "onSetTrustAgentFeaturesEnabledCompleted(result=" + result);
mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED,
result ? 1 : 0, 0, token).sendToTarget();
@@ -318,23 +318,19 @@ public class TrustAgentWrapper {
DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if ((dpm.getKeyguardDisabledFeatures(null)
+ if ((dpm.getKeyguardDisabledFeatures(null, mUserId)
& DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) {
- List<String> features = dpm.getTrustAgentFeaturesEnabled(null, mName);
+ List<PersistableBundle> config = dpm.getTrustAgentConfiguration(
+ null, mName, mUserId);
trustDisabled = true;
- if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Features = "
- + features);
- if (features != null && features.size() > 0) {
- Bundle bundle = new Bundle();
- bundle.putStringArrayList(TrustAgentService.KEY_FEATURES,
- (ArrayList<String>)features);
+ if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Config = " + config);
+ if (config != null && config.size() > 0) {
if (DEBUG) {
Slog.v(TAG, "TrustAgent " + mName.flattenToShortString()
- + " disabled until it acknowledges "+ features);
+ + " disabled until it acknowledges "+ config);
}
mSetTrustAgentFeaturesToken = new Binder();
- mTrustAgentService.setTrustAgentFeaturesEnabled(bundle,
- mSetTrustAgentFeaturesToken);
+ mTrustAgentService.onConfigure(config, mSetTrustAgentFeaturesToken);
}
}
final long maxTimeToLock = dpm.getMaximumTimeToLock(null);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 4437e12..fe5cb33 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -48,6 +48,7 @@ import android.os.DeadObjectException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -228,10 +229,10 @@ public class TrustManagerService extends SystemService {
if (!enabledAgents.contains(name)) continue;
if (disableTrustAgents) {
- List<String> features =
- dpm.getTrustAgentFeaturesEnabled(null /* admin */, name);
+ List<PersistableBundle> config =
+ dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
// Disable agent if no features are enabled.
- if (features == null || features.isEmpty()) continue;
+ if (config == null || config.isEmpty()) continue;
}
AgentInfo agentInfo = new AgentInfo();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 308fcd8..2c6a222 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -60,6 +60,7 @@ import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.IPowerManager;
+import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Process;
import android.os.RecoverySystem;
@@ -96,6 +97,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.org.conscrypt.TrustedCertificateStore;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
import org.xmlpull.v1.XmlPullParser;
@@ -322,7 +324,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
= "permitted-accessiblity-services";
private static final String TAG_ENCRYPTION_REQUESTED = "encryption-requested";
private static final String TAG_MANAGE_TRUST_AGENT_FEATURES = "manage-trust-agent-features";
- private static final String TAG_TRUST_AGENT_FEATURE = "feature";
+ private static final String TAG_TRUST_AGENT_COMPONENT_OPTIONS = "trust-agent-component-options";
private static final String TAG_TRUST_AGENT_COMPONENT = "component";
private static final String TAG_PASSWORD_EXPIRATION_DATE = "password-expiration-date";
private static final String TAG_PASSWORD_EXPIRATION_TIMEOUT = "password-expiration-timeout";
@@ -389,6 +391,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none
+
int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED;
boolean encryptionRequested = false;
@@ -397,6 +400,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
boolean requireAutoTime = false; // Can only be set by a device owner.
+ static class TrustAgentInfo {
+ public PersistableBundle options;
+ TrustAgentInfo(PersistableBundle bundle) {
+ options = bundle;
+ }
+ }
+
Set<String> accountTypesWithManagementDisabled = new HashSet<String>();
// The list of permitted accessibility services package namesas set by a profile
@@ -413,7 +423,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean specifiesGlobalProxy = false;
String globalProxySpec = null;
String globalProxyExclusionList = null;
- HashMap<String, List<String>> trustAgentFeatures = new HashMap<String, List<String>>();
+
+ HashMap<String, TrustAgentInfo> trustAgentInfos = new HashMap<String, TrustAgentInfo>();
List<String> crossProfileWidgetProviders;
@@ -551,16 +562,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
out.endTag(null, TAG_DISABLE_ACCOUNT_MANAGEMENT);
}
- if (!trustAgentFeatures.isEmpty()) {
- Set<Entry<String, List<String>>> set = trustAgentFeatures.entrySet();
+ if (!trustAgentInfos.isEmpty()) {
+ Set<Entry<String, TrustAgentInfo>> set = trustAgentInfos.entrySet();
out.startTag(null, TAG_MANAGE_TRUST_AGENT_FEATURES);
- for (Entry<String, List<String>> component : set) {
+ for (Entry<String, TrustAgentInfo> entry : set) {
+ TrustAgentInfo trustAgentInfo = entry.getValue();
out.startTag(null, TAG_TRUST_AGENT_COMPONENT);
- out.attribute(null, ATTR_VALUE, component.getKey());
- for (String feature : component.getValue()) {
- out.startTag(null, TAG_TRUST_AGENT_FEATURE);
- out.attribute(null, ATTR_VALUE, feature);
- out.endTag(null, TAG_TRUST_AGENT_FEATURE);
+ out.attribute(null, ATTR_VALUE, entry.getKey());
+ if (trustAgentInfo.options != null) {
+ out.startTag(null, TAG_TRUST_AGENT_COMPONENT_OPTIONS);
+ try {
+ trustAgentInfo.options.saveToXml(out);
+ } catch (XmlPullParserException e) {
+ Log.e(LOG_TAG, "Failed to save TrustAgent options", e);
+ }
+ out.endTag(null, TAG_TRUST_AGENT_COMPONENT_OPTIONS);
}
out.endTag(null, TAG_TRUST_AGENT_COMPONENT);
}
@@ -679,7 +695,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else if (TAG_DISABLE_ACCOUNT_MANAGEMENT.equals(tag)) {
accountTypesWithManagementDisabled = readDisableAccountInfo(parser, tag);
} else if (TAG_MANAGE_TRUST_AGENT_FEATURES.equals(tag)) {
- trustAgentFeatures = getAllTrustAgentFeatures(parser, tag);
+ trustAgentInfos = getAllTrustAgentInfos(parser, tag);
} else if (TAG_CROSS_PROFILE_WIDGET_PROVIDERS.equals(tag)) {
crossProfileWidgetProviders = getCrossProfileWidgetProviders(parser, tag);
} else if (TAG_PERMITTED_ACCESSIBILITY_SERVICES.equals(tag)) {
@@ -738,11 +754,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return result;
}
- private HashMap<String, List<String>> getAllTrustAgentFeatures(XmlPullParser parser,
- String tag) throws XmlPullParserException, IOException {
+ private HashMap<String, TrustAgentInfo> getAllTrustAgentInfos(
+ XmlPullParser parser, String tag) throws XmlPullParserException, IOException {
int outerDepthDAM = parser.getDepth();
int typeDAM;
- HashMap<String, List<String>> result = new HashMap<String, List<String>>();
+ HashMap<String, TrustAgentInfo> result = new HashMap<String, TrustAgentInfo>();
while ((typeDAM=parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) {
@@ -751,7 +767,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
String tagDAM = parser.getName();
if (TAG_TRUST_AGENT_COMPONENT.equals(tagDAM)) {
final String component = parser.getAttributeValue(null, ATTR_VALUE);
- result.put(component, getTrustAgentFeatures(parser, tag));
+ final TrustAgentInfo trustAgentInfo = getTrustAgentInfo(parser, tag);
+ result.put(component, trustAgentInfo);
} else {
Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
}
@@ -759,20 +776,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return result;
}
- private List<String> getTrustAgentFeatures(XmlPullParser parser, String tag)
+ private TrustAgentInfo getTrustAgentInfo(XmlPullParser parser, String tag)
throws XmlPullParserException, IOException {
int outerDepthDAM = parser.getDepth();
int typeDAM;
- ArrayList<String> result = new ArrayList<String>();
+ TrustAgentInfo result = new TrustAgentInfo(null);
while ((typeDAM=parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) {
continue;
}
String tagDAM = parser.getName();
- if (TAG_TRUST_AGENT_FEATURE.equals(tagDAM)) {
- final String feature = parser.getAttributeValue(null, ATTR_VALUE);
- result.add(feature);
+ if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tagDAM)) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.restoreFromXml(parser);
+ result.options = bundle;
} else {
Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
}
@@ -1174,7 +1192,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
int userHandle) {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo ui : profiles) {
- int id = ui.getUserHandle().getIdentifier();
+ int id = ui.id;
sendAdminCommandLocked(action, reqPolicy, id);
}
}
@@ -1591,7 +1609,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo ui : profiles) {
- int profileUserHandle = ui.getUserHandle().getIdentifier();
+ int profileUserHandle = ui.id;
final DevicePolicyData policy = getUserData(profileUserHandle);
final int count = policy.mAdminList.size();
if (count > 0) {
@@ -1878,7 +1896,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -1925,7 +1943,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -1972,7 +1990,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2033,7 +2051,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2131,7 +2149,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2188,7 +2206,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2232,7 +2250,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2279,7 +2297,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2326,7 +2344,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2373,7 +2391,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2420,7 +2438,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2526,7 +2544,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
int count = 0;
ActiveAdmin strictestAdmin = null;
for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
for (ActiveAdmin admin : policy.mAdminList) {
if (admin.maximumFailedPasswordsForWipe ==
ActiveAdmin.DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
@@ -2738,7 +2756,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -3055,7 +3073,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void updatePasswordExpirationsLocked(int userHandle) {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- int profileId = userInfo.getUserHandle().getIdentifier();
+ int profileId = userInfo.id;
DevicePolicyData policy = getUserData(profileId);
final int N = policy.mAdminList.size();
if (N > 0) {
@@ -4106,13 +4124,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- public void setTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
- List<String>features, int userHandle) {
+ public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent,
+ PersistableBundle args, int userHandle) {
if (!mHasFeature) {
return;
}
enforceCrossUserPermission(userHandle);
- enforceNotManagedProfile(userHandle, "manage trust agent features");
+ enforceNotManagedProfile(userHandle, "set trust agent configuration");
synchronized (this) {
if (admin == null) {
throw new NullPointerException("admin is null");
@@ -4122,57 +4140,68 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
- ap.trustAgentFeatures.put(agent.flattenToString(), features);
+ ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args));
saveSettingsLocked(userHandle);
syncDeviceCapabilitiesLocked(getUserData(userHandle));
}
}
- public List<String> getTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
- int userHandle) {
+ public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
+ ComponentName agent, int userHandle) {
if (!mHasFeature) {
return null;
}
enforceCrossUserPermission(userHandle);
+ if (agent == null) {
+ throw new NullPointerException("agent is null");
+ }
+
synchronized (this) {
- if (agent == null) {
- throw new NullPointerException("agent is null");
- }
final String componentName = agent.flattenToString();
if (admin != null) {
final ActiveAdmin ap = getActiveAdminUncheckedLocked(admin, userHandle);
- return (ap != null) ? ap.trustAgentFeatures.get(componentName) : null;
+ if (ap == null) return null;
+ TrustAgentInfo trustAgentInfo = ap.trustAgentInfos.get(componentName);
+ if (trustAgentInfo == null || trustAgentInfo.options == null) return null;
+ List<PersistableBundle> result = new ArrayList<PersistableBundle>();
+ result.add(trustAgentInfo.options);
+ return result;
}
// Return strictest policy for this user and profiles that are visible from this user.
- List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
- List<String> result = null;
+ final List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
+ List<PersistableBundle> result = null;
+
+ // Search through all admins that use KEYGUARD_DISABLE_TRUST_AGENTS and keep track
+ // of the options. If any admin doesn't have options, discard options for the rest
+ // and return null.
+ boolean allAdminsHaveOptions = true;
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin ap = policy.mAdminList.get(i);
- // Compute the intersection of all features for active admins that disable
- // trust agents:
- if ((ap.disabledKeyguardFeatures
- & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) {
- final List<String> features = ap.trustAgentFeatures.get(componentName);
- if (result == null) {
- if (features == null || features.size() == 0) {
- result = new ArrayList<String>();
- Slog.w(LOG_TAG, "admin " + ap.info.getPackageName()
- + " has null trust agent feature set; all will be disabled");
- } else {
- result = new ArrayList<String>(features.size());
- result.addAll(features);
+ for (int i=0; i < N; i++) {
+ final ActiveAdmin active = policy.mAdminList.get(i);
+ final boolean disablesTrust = (active.disabledKeyguardFeatures
+ & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
+ final TrustAgentInfo info = active.trustAgentInfos.get(componentName);
+ if (info != null && info.options != null && !info.options.isEmpty()) {
+ if (disablesTrust) {
+ if (result == null) {
+ result = new ArrayList<PersistableBundle>();
}
+ result.add(info.options);
} else {
- result.retainAll(features);
+ Log.w(LOG_TAG, "Ignoring admin " + active.info
+ + " because it has trust options but doesn't declare "
+ + "KEYGUARD_DISABLE_TRUST_AGENTS");
}
+ } else if (disablesTrust) {
+ allAdminsHaveOptions = false;
+ break;
}
}
}
- return result;
+ return allAdminsHaveOptions ? result : null;
}
}