Merge "Update TrustAgentService API after review" into lmp-mr1-dev

This commit is contained in:
Jim Miller
2014-11-06 02:52:19 +00:00
committed by Android (Google) Code Review
10 changed files with 218 additions and 144 deletions

View File

@@ -5323,6 +5323,7 @@ package android.app.admin {
method public boolean getScreenCaptureDisabled(android.content.ComponentName); method public boolean getScreenCaptureDisabled(android.content.ComponentName);
method public boolean getStorageEncryption(android.content.ComponentName); method public boolean getStorageEncryption(android.content.ComponentName);
method public int getStorageEncryptionStatus(); 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 hasCaCertInstalled(android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int); method public boolean hasGrantedPolicy(android.content.ComponentName, int);
method public boolean installCaCert(android.content.ComponentName, byte[]); method public boolean installCaCert(android.content.ComponentName, byte[]);
@@ -5371,6 +5372,7 @@ package android.app.admin {
method public void setScreenCaptureDisabled(android.content.ComponentName, boolean); method public void setScreenCaptureDisabled(android.content.ComponentName, boolean);
method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String); method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public int setStorageEncryption(android.content.ComponentName, boolean); 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 void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle); method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallAllUserCaCerts(android.content.ComponentName); method public void uninstallAllUserCaCerts(android.content.ComponentName);

View File

@@ -31,6 +31,7 @@ import android.content.pm.ResolveInfo;
import android.net.ProxyInfo; import android.net.ProxyInfo;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.PersistableBundle;
import android.os.Process; import android.os.Process;
import android.os.RemoteCallback; import android.os.RemoteCallback;
import android.os.RemoteException; import android.os.RemoteException;
@@ -40,6 +41,7 @@ import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.security.Credentials; import android.security.Credentials;
import android.service.restrictions.RestrictionsReceiver; import android.service.restrictions.RestrictionsReceiver;
import android.service.trust.TrustAgentService;
import android.util.Log; import android.util.Log;
import com.android.org.conscrypt.TrustedCertificateStore; 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 * Sets a list of configuration features to enable for a TrustAgent component. This is meant
* used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which will disable all * to be used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which disables all
* trust agents but those with features enabled by this function call. * 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 * <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call * {@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 admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param agent Which component to enable features for. * @param target Component name of the agent to be enabled.
* @param features List of features to enable. Consult specific TrustAgent documentation for * @param options TrustAgent-specific feature bundle. If null for any admin, agent
* the feature list. * will be strictly disabled according to the state of the
* @hide * {@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, public void setTrustAgentConfiguration(ComponentName admin, ComponentName target,
List<String> features) { PersistableBundle options) {
if (mService != null) { if (mService != null) {
try { try {
mService.setTrustAgentFeaturesEnabled(admin, agent, features, UserHandle.myUserId()); mService.setTrustAgentConfiguration(admin, target, options, UserHandle.myUserId());
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", 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 * Gets configuration for the given trust agent based on aggregating all calls to
* null, this will return the intersection of all features enabled for the given agent by all * {@link #setTrustAgentConfiguration(ComponentName, ComponentName, PersistableBundle)} for
* admins. * all device admins.
* *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param agent Which component to get enabled features for. * @param agent Which component to get enabled features for.
* @return List of enabled features. * @return configuration for the given trust agent.
* @hide
*/ */
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) { if (mService != null) {
try { try {
return mService.getTrustAgentFeaturesEnabled(admin, agent, UserHandle.myUserId()); return mService.getTrustAgentConfiguration(admin, agent, userHandle);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e); Log.w(TAG, "Failed talking with device policy service", e);
} }
} }
return new ArrayList<String>(); // empty list return new ArrayList<PersistableBundle>(); // empty list
} }
/** /**

View File

@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.ProxyInfo; import android.net.ProxyInfo;
import android.os.Bundle; import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.RemoteCallback; import android.os.RemoteCallback;
import android.os.UserHandle; import android.os.UserHandle;
import java.util.List; import java.util.List;
@@ -183,8 +184,10 @@ interface IDevicePolicyManager {
boolean getCrossProfileCallerIdDisabled(in ComponentName who); boolean getCrossProfileCallerIdDisabled(in ComponentName who);
boolean getCrossProfileCallerIdDisabledForUser(int userId); boolean getCrossProfileCallerIdDisabledForUser(int userId);
void setTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, in List<String> features, int userId); void setTrustAgentConfiguration(in ComponentName admin, in ComponentName agent,
List<String> getTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, int userId); in PersistableBundle args, int userId);
List<PersistableBundle> getTrustAgentConfiguration(in ComponentName admin,
in ComponentName agent, int userId);
boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName); boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName);
boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName); boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName);

View File

@@ -15,7 +15,7 @@
*/ */
package android.service.trust; package android.service.trust;
import android.os.Bundle; import android.os.PersistableBundle;
import android.service.trust.ITrustAgentServiceCallback; import android.service.trust.ITrustAgentServiceCallback;
/** /**
@@ -25,6 +25,6 @@ import android.service.trust.ITrustAgentServiceCallback;
interface ITrustAgentService { interface ITrustAgentService {
oneway void onUnlockAttempt(boolean successful); oneway void onUnlockAttempt(boolean successful);
oneway void onTrustTimeout(); oneway void onTrustTimeout();
oneway void onConfigure(in List<PersistableBundle> options, IBinder token);
oneway void setCallback(ITrustAgentServiceCallback callback); oneway void setCallback(ITrustAgentServiceCallback callback);
oneway void setTrustAgentFeaturesEnabled(in Bundle options, IBinder token);
} }

View File

@@ -27,5 +27,5 @@ oneway interface ITrustAgentServiceCallback {
void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser); void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser);
void revokeTrust(); void revokeTrust();
void setManagingTrust(boolean managingTrust); void setManagingTrust(boolean managingTrust);
void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token); void onConfigureCompleted(boolean result, IBinder token);
} }

View File

@@ -29,11 +29,14 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.PersistableBundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import android.util.Slog; import android.util.Slog;
import java.util.List;
/** /**
* A service that notifies the system about whether it believes the environment of the device * A service that notifies the system about whether it believes the environment of the device
* to be trusted. * to be trusted.
@@ -86,17 +89,47 @@ public class TrustAgentService extends Service {
*/ */
public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent"; public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
/**
* A white list of features that the given trust agent should support when otherwise disabled
* by device policy.
* @hide
*/
public static final String KEY_FEATURES = "trust_agent_features";
private static final int MSG_UNLOCK_ATTEMPT = 1; private static final int MSG_UNLOCK_ATTEMPT = 1;
private static final int MSG_SET_TRUST_AGENT_FEATURES_ENABLED = 2; private static final int MSG_CONFIGURE = 2;
private static final int MSG_TRUST_TIMEOUT = 3; private static final int MSG_TRUST_TIMEOUT = 3;
/**
* Container class for a list of configuration options and helper methods
*/
public static final class Configuration {
public final List<PersistableBundle> options;
public Configuration(List<PersistableBundle> opts) {
options = opts;
}
/**
* 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; private ITrustAgentServiceCallback mCallback;
private Runnable mPendingGrantTrustTask; private Runnable mPendingGrantTrustTask;
@@ -112,13 +145,12 @@ public class TrustAgentService extends Service {
case MSG_UNLOCK_ATTEMPT: case MSG_UNLOCK_ATTEMPT:
onUnlockAttempt(msg.arg1 != 0); onUnlockAttempt(msg.arg1 != 0);
break; break;
case MSG_SET_TRUST_AGENT_FEATURES_ENABLED: case MSG_CONFIGURE:
Bundle features = msg.peekData(); ConfigurationData data = (ConfigurationData) msg.obj;
IBinder token = (IBinder) msg.obj; boolean result = onConfigure(new Configuration(data.options));
boolean result = onSetTrustAgentFeaturesEnabled(features);
try { try {
synchronized (mLock) { synchronized (mLock) {
mCallback.onSetTrustAgentFeaturesEnabledCompleted(result, token); mCallback.onConfigureCompleted(result, data.token);
} }
} catch (RemoteException e) { } catch (RemoteException e) {
onError("calling onSetTrustAgentFeaturesEnabledCompleted()"); 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 * Called when device policy admin wants to enable specific options for agent in response to
* {@link DevicePolicyManager#setTrustAgentFeaturesEnabled(ComponentName, ComponentName, java.util.List) }. * {@link DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)} and
* Agents that support this feature should overload this method and return 'true'. * {@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 * @param options bundle containing all options or null if none.
* options.getStringArrayList({@link #KEY_FEATURES}). Presence of a feature string in the list * @return true if the {@link TrustAgentService} supports configuration options.
* 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
*/ */
public boolean onSetTrustAgentFeaturesEnabled(Bundle options) { public boolean onConfigure(Configuration options) {
return false; return false;
} }
@@ -294,6 +319,12 @@ public class TrustAgentService extends Service {
mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT); mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
} }
@Override /* Binder API */
public void onConfigure(List<PersistableBundle> args, IBinder token) {
mHandler.obtainMessage(MSG_CONFIGURE, new ConfigurationData(args, token))
.sendToTarget();
}
@Override /* Binder API */ @Override /* Binder API */
public void setCallback(ITrustAgentServiceCallback callback) { public void setCallback(ITrustAgentServiceCallback callback) {
synchronized (mLock) { synchronized (mLock) {
@@ -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();
}
} }
} }

View File

@@ -21,7 +21,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.PersistableBundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.service.trust.TrustAgentService; import android.service.trust.TrustAgentService;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
@@ -90,8 +90,15 @@ public class SampleTrustAgent extends TrustAgentService
} }
@Override @Override
public boolean onSetTrustAgentFeaturesEnabled(Bundle options) { public boolean onConfigure(Configuration config) {
Log.v(TAG, "Policy options received: " + options.getStringArrayList(KEY_FEATURES)); 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 // TODO: Handle options
return true; // inform DPM that we support it return true; // inform DPM that we support it
} }

View File

@@ -27,11 +27,11 @@ import android.content.IntentFilter;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.net.Uri; import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.PatternMatcher; import android.os.PatternMatcher;
import android.os.PersistableBundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
@@ -218,7 +218,7 @@ public class TrustAgentWrapper {
} }
@Override @Override
public void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token) { public void onConfigureCompleted(boolean result, IBinder token) {
if (DEBUG) Slog.v(TAG, "onSetTrustAgentFeaturesEnabledCompleted(result=" + result); if (DEBUG) Slog.v(TAG, "onSetTrustAgentFeaturesEnabledCompleted(result=" + result);
mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED, mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED,
result ? 1 : 0, 0, token).sendToTarget(); result ? 1 : 0, 0, token).sendToTarget();
@@ -318,23 +318,19 @@ public class TrustAgentWrapper {
DevicePolicyManager dpm = DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
if ((dpm.getKeyguardDisabledFeatures(null) if ((dpm.getKeyguardDisabledFeatures(null, mUserId)
& DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) { & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) {
List<String> features = dpm.getTrustAgentFeaturesEnabled(null, mName); List<PersistableBundle> config = dpm.getTrustAgentConfiguration(
null, mName, mUserId);
trustDisabled = true; trustDisabled = true;
if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Features = " if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Config = " + config);
+ features); if (config != null && config.size() > 0) {
if (features != null && features.size() > 0) {
Bundle bundle = new Bundle();
bundle.putStringArrayList(TrustAgentService.KEY_FEATURES,
(ArrayList<String>)features);
if (DEBUG) { if (DEBUG) {
Slog.v(TAG, "TrustAgent " + mName.flattenToShortString() Slog.v(TAG, "TrustAgent " + mName.flattenToShortString()
+ " disabled until it acknowledges "+ features); + " disabled until it acknowledges "+ config);
} }
mSetTrustAgentFeaturesToken = new Binder(); mSetTrustAgentFeaturesToken = new Binder();
mTrustAgentService.setTrustAgentFeaturesEnabled(bundle, mTrustAgentService.onConfigure(config, mSetTrustAgentFeaturesToken);
mSetTrustAgentFeaturesToken);
} }
} }
final long maxTimeToLock = dpm.getMaximumTimeToLock(null); final long maxTimeToLock = dpm.getMaximumTimeToLock(null);

View File

@@ -48,6 +48,7 @@ import android.os.DeadObjectException;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.PersistableBundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
@@ -228,10 +229,10 @@ public class TrustManagerService extends SystemService {
if (!enabledAgents.contains(name)) continue; if (!enabledAgents.contains(name)) continue;
if (disableTrustAgents) { if (disableTrustAgents) {
List<String> features = List<PersistableBundle> config =
dpm.getTrustAgentFeaturesEnabled(null /* admin */, name); dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
// Disable agent if no features are enabled. // Disable agent if no features are enabled.
if (features == null || features.isEmpty()) continue; if (config == null || config.isEmpty()) continue;
} }
AgentInfo agentInfo = new AgentInfo(); AgentInfo agentInfo = new AgentInfo();

View File

@@ -60,6 +60,7 @@ import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.IPowerManager; import android.os.IPowerManager;
import android.os.PersistableBundle;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.Process; import android.os.Process;
import android.os.RecoverySystem; import android.os.RecoverySystem;
@@ -96,6 +97,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.org.conscrypt.TrustedCertificateStore; import com.android.org.conscrypt.TrustedCertificateStore;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.SystemService; import com.android.server.SystemService;
import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
@@ -322,7 +324,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
= "permitted-accessiblity-services"; = "permitted-accessiblity-services";
private static final String TAG_ENCRYPTION_REQUESTED = "encryption-requested"; 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_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_TRUST_AGENT_COMPONENT = "component";
private static final String TAG_PASSWORD_EXPIRATION_DATE = "password-expiration-date"; private static final String TAG_PASSWORD_EXPIRATION_DATE = "password-expiration-date";
private static final String TAG_PASSWORD_EXPIRATION_TIMEOUT = "password-expiration-timeout"; 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; long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none
int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED; int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED;
boolean encryptionRequested = false; 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 disableScreenCapture = false; // Can only be set by a device/profile owner.
boolean requireAutoTime = false; // Can only be set by a device 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>(); Set<String> accountTypesWithManagementDisabled = new HashSet<String>();
// The list of permitted accessibility services package namesas set by a profile // 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; boolean specifiesGlobalProxy = false;
String globalProxySpec = null; String globalProxySpec = null;
String globalProxyExclusionList = 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; List<String> crossProfileWidgetProviders;
@@ -551,16 +562,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
out.endTag(null, TAG_DISABLE_ACCOUNT_MANAGEMENT); out.endTag(null, TAG_DISABLE_ACCOUNT_MANAGEMENT);
} }
if (!trustAgentFeatures.isEmpty()) { if (!trustAgentInfos.isEmpty()) {
Set<Entry<String, List<String>>> set = trustAgentFeatures.entrySet(); Set<Entry<String, TrustAgentInfo>> set = trustAgentInfos.entrySet();
out.startTag(null, TAG_MANAGE_TRUST_AGENT_FEATURES); 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.startTag(null, TAG_TRUST_AGENT_COMPONENT);
out.attribute(null, ATTR_VALUE, component.getKey()); out.attribute(null, ATTR_VALUE, entry.getKey());
for (String feature : component.getValue()) { if (trustAgentInfo.options != null) {
out.startTag(null, TAG_TRUST_AGENT_FEATURE); out.startTag(null, TAG_TRUST_AGENT_COMPONENT_OPTIONS);
out.attribute(null, ATTR_VALUE, feature); try {
out.endTag(null, TAG_TRUST_AGENT_FEATURE); 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); 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)) { } else if (TAG_DISABLE_ACCOUNT_MANAGEMENT.equals(tag)) {
accountTypesWithManagementDisabled = readDisableAccountInfo(parser, tag); accountTypesWithManagementDisabled = readDisableAccountInfo(parser, tag);
} else if (TAG_MANAGE_TRUST_AGENT_FEATURES.equals(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)) { } else if (TAG_CROSS_PROFILE_WIDGET_PROVIDERS.equals(tag)) {
crossProfileWidgetProviders = getCrossProfileWidgetProviders(parser, tag); crossProfileWidgetProviders = getCrossProfileWidgetProviders(parser, tag);
} else if (TAG_PERMITTED_ACCESSIBILITY_SERVICES.equals(tag)) { } else if (TAG_PERMITTED_ACCESSIBILITY_SERVICES.equals(tag)) {
@@ -738,11 +754,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return result; return result;
} }
private HashMap<String, List<String>> getAllTrustAgentFeatures(XmlPullParser parser, private HashMap<String, TrustAgentInfo> getAllTrustAgentInfos(
String tag) throws XmlPullParserException, IOException { XmlPullParser parser, String tag) throws XmlPullParserException, IOException {
int outerDepthDAM = parser.getDepth(); int outerDepthDAM = parser.getDepth();
int typeDAM; 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 while ((typeDAM=parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) { && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) { if (typeDAM == END_TAG || typeDAM == TEXT) {
@@ -751,7 +767,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
String tagDAM = parser.getName(); String tagDAM = parser.getName();
if (TAG_TRUST_AGENT_COMPONENT.equals(tagDAM)) { if (TAG_TRUST_AGENT_COMPONENT.equals(tagDAM)) {
final String component = parser.getAttributeValue(null, ATTR_VALUE); 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 { } else {
Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM); Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
} }
@@ -759,20 +776,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return result; return result;
} }
private List<String> getTrustAgentFeatures(XmlPullParser parser, String tag) private TrustAgentInfo getTrustAgentInfo(XmlPullParser parser, String tag)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {
int outerDepthDAM = parser.getDepth(); int outerDepthDAM = parser.getDepth();
int typeDAM; int typeDAM;
ArrayList<String> result = new ArrayList<String>(); TrustAgentInfo result = new TrustAgentInfo(null);
while ((typeDAM=parser.next()) != END_DOCUMENT while ((typeDAM=parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) { && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) { if (typeDAM == END_TAG || typeDAM == TEXT) {
continue; continue;
} }
String tagDAM = parser.getName(); String tagDAM = parser.getName();
if (TAG_TRUST_AGENT_FEATURE.equals(tagDAM)) { if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tagDAM)) {
final String feature = parser.getAttributeValue(null, ATTR_VALUE); PersistableBundle bundle = new PersistableBundle();
result.add(feature); bundle.restoreFromXml(parser);
result.options = bundle;
} else { } else {
Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM); Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
} }
@@ -1174,7 +1192,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
int userHandle) { int userHandle) {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo ui : profiles) { for (UserInfo ui : profiles) {
int id = ui.getUserHandle().getIdentifier(); int id = ui.id;
sendAdminCommandLocked(action, reqPolicy, id); sendAdminCommandLocked(action, reqPolicy, id);
} }
} }
@@ -1591,7 +1609,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo ui : profiles) { for (UserInfo ui : profiles) {
int profileUserHandle = ui.getUserHandle().getIdentifier(); int profileUserHandle = ui.id;
final DevicePolicyData policy = getUserData(profileUserHandle); final DevicePolicyData policy = getUserData(profileUserHandle);
final int count = policy.mAdminList.size(); final int count = policy.mAdminList.size();
if (count > 0) { 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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i); ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2033,7 +2051,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i); ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2131,7 +2149,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i); ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2526,7 +2544,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
int count = 0; int count = 0;
ActiveAdmin strictestAdmin = null; ActiveAdmin strictestAdmin = null;
for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) { for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
for (ActiveAdmin admin : policy.mAdminList) { for (ActiveAdmin admin : policy.mAdminList) {
if (admin.maximumFailedPasswordsForWipe == if (admin.maximumFailedPasswordsForWipe ==
ActiveAdmin.DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) { 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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i); ActiveAdmin admin = policy.mAdminList.get(i);
@@ -3055,7 +3073,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void updatePasswordExpirationsLocked(int userHandle) { private void updatePasswordExpirationsLocked(int userHandle) {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) { for (UserInfo userInfo : profiles) {
int profileId = userInfo.getUserHandle().getIdentifier(); int profileId = userInfo.id;
DevicePolicyData policy = getUserData(profileId); DevicePolicyData policy = getUserData(profileId);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
if (N > 0) { if (N > 0) {
@@ -4106,13 +4124,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
} }
public void setTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent, public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent,
List<String>features, int userHandle) { PersistableBundle args, int userHandle) {
if (!mHasFeature) { if (!mHasFeature) {
return; return;
} }
enforceCrossUserPermission(userHandle); enforceCrossUserPermission(userHandle);
enforceNotManagedProfile(userHandle, "manage trust agent features"); enforceNotManagedProfile(userHandle, "set trust agent configuration");
synchronized (this) { synchronized (this) {
if (admin == null) { if (admin == null) {
throw new NullPointerException("admin is null"); throw new NullPointerException("admin is null");
@@ -4122,57 +4140,68 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
ActiveAdmin ap = getActiveAdminForCallerLocked(admin, ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
ap.trustAgentFeatures.put(agent.flattenToString(), features); ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args));
saveSettingsLocked(userHandle); saveSettingsLocked(userHandle);
syncDeviceCapabilitiesLocked(getUserData(userHandle)); syncDeviceCapabilitiesLocked(getUserData(userHandle));
} }
} }
public List<String> getTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent, public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
int userHandle) { ComponentName agent, int userHandle) {
if (!mHasFeature) { if (!mHasFeature) {
return null; return null;
} }
enforceCrossUserPermission(userHandle); enforceCrossUserPermission(userHandle);
if (agent == null) {
throw new NullPointerException("agent is null");
}
synchronized (this) { synchronized (this) {
if (agent == null) {
throw new NullPointerException("agent is null");
}
final String componentName = agent.flattenToString(); final String componentName = agent.flattenToString();
if (admin != null) { if (admin != null) {
final ActiveAdmin ap = getActiveAdminUncheckedLocked(admin, userHandle); 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. // Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle); final List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
List<String> result = null; 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) { for (UserInfo userInfo : profiles) {
DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier()); DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size(); final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) { for (int i=0; i < N; i++) {
ActiveAdmin ap = policy.mAdminList.get(i); final ActiveAdmin active = policy.mAdminList.get(i);
// Compute the intersection of all features for active admins that disable final boolean disablesTrust = (active.disabledKeyguardFeatures
// trust agents: & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
if ((ap.disabledKeyguardFeatures final TrustAgentInfo info = active.trustAgentInfos.get(componentName);
& DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) { if (info != null && info.options != null && !info.options.isEmpty()) {
final List<String> features = ap.trustAgentFeatures.get(componentName); if (disablesTrust) {
if (result == null) { if (result == null) {
if (features == null || features.size() == 0) { result = new ArrayList<PersistableBundle>();
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);
} }
result.add(info.options);
} else { } 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;
} }
} }