diff options
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; } } |