Fields Summary |
---|
private static final boolean | DEBUG |
private static final String | TAG |
private static final android.content.Intent | TRUST_AGENT_INTENT |
private static final String | PERMISSION_PROVIDE_AGENT |
private static final int | MSG_REGISTER_LISTENER |
private static final int | MSG_UNREGISTER_LISTENER |
private static final int | MSG_DISPATCH_UNLOCK_ATTEMPT |
private static final int | MSG_ENABLED_AGENTS_CHANGED |
private static final int | MSG_REQUIRE_CREDENTIAL_ENTRY |
private static final int | MSG_KEYGUARD_SHOWING_CHANGED |
private static final int | MSG_START_USER |
private static final int | MSG_CLEANUP_USER |
private static final int | MSG_SWITCH_USER |
private final android.util.ArraySet | mActiveAgents |
private final ArrayList | mTrustListeners |
private final Receiver | mReceiver |
private final android.util.SparseBooleanArray | mUserHasAuthenticatedSinceBoot |
final TrustArchive | mArchive |
private final android.content.Context | mContext |
private final com.android.internal.widget.LockPatternUtils | mLockPatternUtils |
private final android.os.UserManager | mUserManager |
private final android.app.ActivityManager | mActivityManager |
private final android.util.SparseBooleanArray | mUserIsTrusted |
private final android.util.SparseBooleanArray | mDeviceLockedForUser |
private boolean | mTrustAgentsCanRun |
private int | mCurrentUser |
private final android.os.IBinder | mService |
private final android.os.Handler | mHandler |
private final com.android.internal.content.PackageMonitor | mPackageMonitor |
Methods Summary |
---|
private void | addListener(android.app.trust.ITrustListener listener)
for (int i = 0; i < mTrustListeners.size(); i++) {
if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
return;
}
}
mTrustListeners.add(listener);
updateTrustAll();
|
private boolean | aggregateIsTrustManaged(int userId)
if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
return false;
}
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo info = mActiveAgents.valueAt(i);
if (info.userId == userId) {
if (info.agent.isManagingTrust()) {
return true;
}
}
}
return false;
|
private boolean | aggregateIsTrusted(int userId)
if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
return false;
}
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo info = mActiveAgents.valueAt(i);
if (info.userId == userId) {
if (info.agent.isTrusted()) {
return true;
}
}
}
return false;
|
private void | dispatchDeviceLocked(int userId, boolean isLocked)
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo agent = mActiveAgents.valueAt(i);
if (agent.userId == userId) {
if (isLocked) {
agent.agent.onDeviceLocked();
} else{
agent.agent.onDeviceUnlocked();
}
}
}
|
private void | dispatchOnTrustChanged(boolean enabled, int userId, boolean initiatedByUser)
if (!enabled) initiatedByUser = false;
for (int i = 0; i < mTrustListeners.size(); i++) {
try {
mTrustListeners.get(i).onTrustChanged(enabled, userId, initiatedByUser);
} catch (DeadObjectException e) {
Slog.d(TAG, "Removing dead TrustListener.");
mTrustListeners.remove(i);
i--;
} catch (RemoteException e) {
Slog.e(TAG, "Exception while notifying TrustListener.", e);
}
}
|
private void | dispatchOnTrustManagedChanged(boolean managed, int userId)
for (int i = 0; i < mTrustListeners.size(); i++) {
try {
mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
} catch (DeadObjectException e) {
Slog.d(TAG, "Removing dead TrustListener.");
mTrustListeners.remove(i);
i--;
} catch (RemoteException e) {
Slog.e(TAG, "Exception while notifying TrustListener.", e);
}
}
|
private void | dispatchUnlockAttempt(boolean successful, int userId)
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo info = mActiveAgents.valueAt(i);
if (info.userId == userId) {
info.agent.onUnlockAttempt(successful);
}
}
if (successful) {
updateUserHasAuthenticated(userId);
}
|
private android.content.ComponentName | getComponentName(android.content.pm.ResolveInfo resolveInfo)
if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
|
private android.content.ComponentName | getSettingsComponentName(android.content.pm.PackageManager pm, android.content.pm.ResolveInfo resolveInfo)
if (resolveInfo == null || resolveInfo.serviceInfo == null
|| resolveInfo.serviceInfo.metaData == null) return null;
String cn = null;
XmlResourceParser parser = null;
Exception caughtException = null;
try {
parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
TrustAgentService.TRUST_AGENT_META_DATA);
if (parser == null) {
Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
return null;
}
Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
// Drain preamble.
}
String nodeName = parser.getName();
if (!"trust-agent".equals(nodeName)) {
Slog.w(TAG, "Meta-data does not start with trust-agent tag");
return null;
}
TypedArray sa = res
.obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
sa.recycle();
} catch (PackageManager.NameNotFoundException e) {
caughtException = e;
} catch (IOException e) {
caughtException = e;
} catch (XmlPullParserException e) {
caughtException = e;
} finally {
if (parser != null) parser.close();
}
if (caughtException != null) {
Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
return null;
}
if (cn == null) {
return null;
}
if (cn.indexOf('/") < 0) {
cn = resolveInfo.serviceInfo.packageName + "/" + cn;
}
return ComponentName.unflattenFromString(cn);
|
boolean | isDeviceLockedInner(int userId)
synchronized (mDeviceLockedForUser) {
return mDeviceLockedForUser.get(userId, true);
}
|
private void | maybeEnableFactoryTrustAgents(com.android.internal.widget.LockPatternUtils utils, int userId)
if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
return;
}
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
for (ResolveInfo resolveInfo : resolveInfos) {
ComponentName componentName = getComponentName(resolveInfo);
int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
+ "is not a system package.");
continue;
}
discoveredAgents.add(componentName);
}
List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
if (previouslyEnabledAgents != null) {
discoveredAgents.addAll(previouslyEnabledAgents);
}
utils.setEnabledTrustAgents(discoveredAgents, userId);
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
|
public void | onBootPhase(int phase)
if (isSafeMode()) {
// No trust agents in safe mode.
return;
}
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
mReceiver.register(mContext);
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
mTrustAgentsCanRun = true;
refreshAgentList(UserHandle.USER_ALL);
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER);
}
|
public void | onCleanupUser(int userId)
mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
|
public void | onStart()
publishBinderService(Context.TRUST_SERVICE, mService);
|
public void | onStartUser(int userId)
mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
|
public void | onSwitchUser(int userId)
mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
|
void | refreshAgentList(int userId)
if (DEBUG) Slog.d(TAG, "refreshAgentList()");
if (!mTrustAgentsCanRun) {
return;
}
if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
+ " must be USER_ALL or a specific user.", new Throwable("here"));
userId = UserHandle.USER_ALL;
}
PackageManager pm = mContext.getPackageManager();
List<UserInfo> userInfos;
if (userId == UserHandle.USER_ALL) {
userInfos = mUserManager.getUsers(true /* excludeDying */);
} else {
userInfos = new ArrayList<>();
userInfos.add(mUserManager.getUserInfo(userId));
}
LockPatternUtils lockPatternUtils = mLockPatternUtils;
ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
obsoleteAgents.addAll(mActiveAgents);
for (UserInfo userInfo : userInfos) {
if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
|| userInfo.guestToRemove) continue;
if (!userInfo.supportsSwitchTo()) continue;
if (!mActivityManager.isUserRunning(userInfo.id)) continue;
if (!lockPatternUtils.isSecure(userInfo.id)) continue;
if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
final boolean disableTrustAgents =
(disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
if (enabledAgents == null) {
continue;
}
List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
for (ResolveInfo resolveInfo : resolveInfos) {
ComponentName name = getComponentName(resolveInfo);
if (!enabledAgents.contains(name)) continue;
if (disableTrustAgents) {
List<PersistableBundle> config =
dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
// Disable agent if no features are enabled.
if (config == null || config.isEmpty()) continue;
}
AgentInfo agentInfo = new AgentInfo();
agentInfo.component = name;
agentInfo.userId = userInfo.id;
if (!mActiveAgents.contains(agentInfo)) {
agentInfo.label = resolveInfo.loadLabel(pm);
agentInfo.icon = resolveInfo.loadIcon(pm);
agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
agentInfo.agent = new TrustAgentWrapper(mContext, this,
new Intent().setComponent(name), userInfo.getUserHandle());
mActiveAgents.add(agentInfo);
} else {
obsoleteAgents.remove(agentInfo);
}
}
}
boolean trustMayHaveChanged = false;
for (int i = 0; i < obsoleteAgents.size(); i++) {
AgentInfo info = obsoleteAgents.valueAt(i);
if (userId == UserHandle.USER_ALL || userId == info.userId) {
if (info.agent.isManagingTrust()) {
trustMayHaveChanged = true;
}
info.agent.destroy();
mActiveAgents.remove(info);
}
}
if (trustMayHaveChanged) {
if (userId == UserHandle.USER_ALL) {
updateTrustAll();
} else {
updateTrust(userId, false /* initiatedByUser */);
}
}
|
private void | refreshDeviceLockedForUser(int userId)
if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
+ " must be USER_ALL or a specific user.", new Throwable("here"));
userId = UserHandle.USER_ALL;
}
List<UserInfo> userInfos;
if (userId == UserHandle.USER_ALL) {
userInfos = mUserManager.getUsers(true /* excludeDying */);
} else {
userInfos = new ArrayList<>();
userInfos.add(mUserManager.getUserInfo(userId));
}
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
for (int i = 0; i < userInfos.size(); i++) {
UserInfo info = userInfos.get(i);
if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
|| !info.supportsSwitchTo()) {
continue;
}
int id = info.id;
boolean secure = mLockPatternUtils.isSecure(id);
boolean trusted = aggregateIsTrusted(id);
boolean showingKeyguard = true;
if (mCurrentUser == id) {
try {
showingKeyguard = wm.isKeyguardLocked();
} catch (RemoteException e) {
}
}
boolean deviceLocked = secure && showingKeyguard && !trusted;
boolean changed;
synchronized (mDeviceLockedForUser) {
changed = isDeviceLockedInner(id) != deviceLocked;
mDeviceLockedForUser.put(id, deviceLocked);
}
if (changed) {
dispatchDeviceLocked(id, deviceLocked);
}
}
|
private void | removeAgentsOfPackage(java.lang.String packageName)
boolean trustMayHaveChanged = false;
for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
AgentInfo info = mActiveAgents.valueAt(i);
if (packageName.equals(info.component.getPackageName())) {
Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
if (info.agent.isManagingTrust()) {
trustMayHaveChanged = true;
}
info.agent.destroy();
mActiveAgents.removeAt(i);
}
}
if (trustMayHaveChanged) {
updateTrustAll();
}
|
private void | removeListener(android.app.trust.ITrustListener listener)
for (int i = 0; i < mTrustListeners.size(); i++) {
if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
mTrustListeners.remove(i);
return;
}
}
|
private void | requireCredentialEntry(int userId)
if (userId == UserHandle.USER_ALL) {
mUserHasAuthenticatedSinceBoot.clear();
refreshAgentList(UserHandle.USER_ALL);
} else {
mUserHasAuthenticatedSinceBoot.put(userId, false);
refreshAgentList(userId);
}
|
public void | resetAgent(android.content.ComponentName name, int userId)
boolean trustMayHaveChanged = false;
for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
AgentInfo info = mActiveAgents.valueAt(i);
if (name.equals(info.component) && userId == info.userId) {
Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
if (info.agent.isManagingTrust()) {
trustMayHaveChanged = true;
}
info.agent.destroy();
mActiveAgents.removeAt(i);
}
}
if (trustMayHaveChanged) {
updateTrust(userId, false);
}
refreshAgentList(userId);
|
private java.util.List | resolveAllowedTrustAgents(android.content.pm.PackageManager pm, int userId)
List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
0 /* flags */, userId);
ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
for (ResolveInfo resolveInfo : resolveInfos) {
if (resolveInfo.serviceInfo == null) continue;
if (resolveInfo.serviceInfo.applicationInfo == null) continue;
String packageName = resolveInfo.serviceInfo.packageName;
if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
!= PackageManager.PERMISSION_GRANTED) {
ComponentName name = getComponentName(resolveInfo);
Log.w(TAG, "Skipping agent " + name + " because package does not have"
+ " permission " + PERMISSION_PROVIDE_AGENT + ".");
continue;
}
allowedAgents.add(resolveInfo);
}
return allowedAgents;
|
private int | resolveProfileParent(int userId)
long identity = Binder.clearCallingIdentity();
try {
UserInfo parent = mUserManager.getProfileParent(userId);
if (parent != null) {
return parent.getUserHandle().getIdentifier();
}
return userId;
} finally {
Binder.restoreCallingIdentity(identity);
}
|
void | updateDevicePolicyFeatures()
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo info = mActiveAgents.valueAt(i);
if (info.agent.isConnected()) {
info.agent.updateDevicePolicyFeatures();
}
}
|
public void | updateTrust(int userId, boolean initiatedByUser)
dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
boolean trusted = aggregateIsTrusted(userId);
boolean changed;
synchronized (mUserIsTrusted) {
changed = mUserIsTrusted.get(userId) != trusted;
mUserIsTrusted.put(userId, trusted);
}
dispatchOnTrustChanged(trusted, userId, initiatedByUser);
if (changed) {
refreshDeviceLockedForUser(userId);
}
|
private void | updateTrustAll()
List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
for (UserInfo userInfo : userInfos) {
updateTrust(userInfo.id, false);
}
|
private void | updateUserHasAuthenticated(int userId)
if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
mUserHasAuthenticatedSinceBoot.put(userId, true);
refreshAgentList(userId);
}
|