From a7da0e26a5000b2de85866d8d0cd8da1021a8948 Mon Sep 17 00:00:00 2001 From: Dave McCloskey Date: Fri, 14 Jan 2022 16:37:58 -0800 Subject: [PATCH] Changes to support adding CTS Test TrustTestCases. Bug: 213631672 Test: atest TrustTestCases Change-Id: I43bffe76cca38171f19538740a25eb5d3cb09c54 --- core/api/test-current.txt | 22 +++++- .../java/android/app/trust/ITrustManager.aidl | 2 + core/java/android/app/trust/TrustManager.java | 73 +++++++++++++++++-- .../service/trust/TrustAgentService.java | 4 +- core/res/AndroidManifest.xml | 2 +- .../server/trust/TrustManagerService.java | 32 +++++++- 6 files changed, 124 insertions(+), 11 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index ff26ae8d09fcc..1ebf9192bc99e 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2,6 +2,7 @@ package android { public static final class Manifest.permission { + field public static final String ACCESS_KEYGUARD_SECURE_STORAGE = "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"; field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; @@ -280,8 +281,8 @@ package android.app { } public class KeyguardManager { - method @RequiresPermission(anyOf={android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS, "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"}) public boolean checkLock(int, @Nullable byte[]); - method @RequiresPermission(anyOf={android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS, "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"}) public boolean setLock(int, @Nullable byte[], int, @Nullable byte[]); + method @RequiresPermission(anyOf={android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS, android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE}) public boolean checkLock(int, @Nullable byte[]); + method @RequiresPermission(anyOf={android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS, android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE}) public boolean setLock(int, @Nullable byte[], int, @Nullable byte[]); } public class LocaleManager { @@ -575,6 +576,15 @@ package android.app.prediction { } +package android.app.trust { + + public class TrustManager { + method @RequiresPermission(android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE) public void enableTrustAgentForUserForTest(@NonNull android.content.ComponentName, int); + method @RequiresPermission(android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE) public void reportUserRequestedUnlock(int); + } + +} + package android.app.usage { public class NetworkStatsManager { @@ -2376,6 +2386,14 @@ package android.service.quicksettings { } +package android.service.trust { + + public class TrustAgentService extends android.app.Service { + method public void onUserRequestedUnlock(); + } + +} + package android.service.voice { public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector { diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl index edabccf23c2cb..7956a35c7b3d1 100644 --- a/core/java/android/app/trust/ITrustManager.aidl +++ b/core/java/android/app/trust/ITrustManager.aidl @@ -17,6 +17,7 @@ package android.app.trust; import android.app.trust.ITrustListener; +import android.content.ComponentName; import android.hardware.biometrics.BiometricSourceType; /** @@ -29,6 +30,7 @@ interface ITrustManager { void reportUserRequestedUnlock(int userId); void reportUnlockLockout(int timeoutMs, int userId); void reportEnabledTrustAgentsChanged(int userId); + void enableTrustAgentForUserForTest(in ComponentName componentName, int userId); void registerTrustListener(in ITrustListener trustListener); void unregisterTrustListener(in ITrustListener trustListener); void reportKeyguardShowingChanged(); diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java index 70b7de0767e47..fba2d3e037692 100644 --- a/core/java/android/app/trust/TrustManager.java +++ b/core/java/android/app/trust/TrustManager.java @@ -16,10 +16,14 @@ package android.app.trust; -import android.Manifest; +import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; + +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemService; +import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.content.ComponentName; import android.content.Context; import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; @@ -33,9 +37,17 @@ import java.util.ArrayList; import java.util.List; /** - * See {@link com.android.server.trust.TrustManagerService} + * Interface to the system service managing trust. + * + *

This class is for internal use only. This class is marked {@code @TestApi} to + * enable testing the trust system including {@link android.service.trust.TrustAgentService}. + * Methods which are currently not used in tests are marked @hide. + * + * @see com.android.server.trust.TrustManagerService + * * @hide */ +@TestApi @SystemService(Context.TRUST_SERVICE) public class TrustManager { @@ -51,7 +63,8 @@ public class TrustManager { private final ITrustManager mService; private final ArrayMap mTrustListeners; - public TrustManager(IBinder b) { + /** @hide */ + public TrustManager(@NonNull IBinder b) { mService = ITrustManager.Stub.asInterface(b); mTrustListeners = new ArrayMap(); } @@ -62,8 +75,10 @@ public class TrustManager { * * @param userId The id for the user to be locked/unlocked. * @param locked The value for that user's locked state. + * + * @hide */ - @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE) + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void setDeviceLockedForUser(int userId, boolean locked) { try { mService.setDeviceLockedForUser(userId, locked); @@ -78,8 +93,11 @@ public class TrustManager { * @param successful if true, the unlock attempt was successful. * * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. + * + * @hide */ @UnsupportedAppUsage + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void reportUnlockAttempt(boolean successful, int userId) { try { mService.reportUnlockAttempt(successful, userId); @@ -93,6 +111,7 @@ public class TrustManager { * * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. */ + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void reportUserRequestedUnlock(int userId) { try { mService.reportUserRequestedUnlock(userId); @@ -112,7 +131,10 @@ public class TrustManager { * attempt to unlock the device again. * * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. + * + * @hide */ + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void reportUnlockLockout(int timeoutMs, int userId) { try { mService.reportUnlockLockout(timeoutMs, userId); @@ -125,7 +147,10 @@ public class TrustManager { * Reports that the list of enabled trust agents changed for user {@param userId}. * * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. + * + * @hide */ + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void reportEnabledTrustAgentsChanged(int userId) { try { mService.reportEnabledTrustAgentsChanged(userId); @@ -134,11 +159,34 @@ public class TrustManager { } } + /** + * Enables a trust agent. + * + *

The agent is specified by {@code componentName} and must be a subclass of + * {@link android.service.trust.TrustAgentService} and otherwise meet the requirements + * to be a trust agent. + * + *

This method can only be used in tests. + * + * @param componentName the trust agent to enable + */ + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) + public void enableTrustAgentForUserForTest(@NonNull ComponentName componentName, int userId) { + try { + mService.enableTrustAgentForUserForTest(componentName, userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Reports that the visibility of the keyguard has changed. * * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. + * + * @hide */ + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void reportKeyguardShowingChanged() { try { mService.reportKeyguardShowingChanged(); @@ -151,7 +199,10 @@ public class TrustManager { * Registers a listener for trust events. * * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission. + * + * @hide */ + @RequiresPermission(android.Manifest.permission.TRUST_LISTENER) public void registerTrustListener(final TrustListener trustListener) { try { ITrustListener.Stub iTrustListener = new ITrustListener.Stub() { @@ -192,7 +243,10 @@ public class TrustManager { * Unregisters a listener for trust events. * * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission. + * + * @hide */ + @RequiresPermission(android.Manifest.permission.TRUST_LISTENER) public void unregisterTrustListener(final TrustListener trustListener) { ITrustListener iTrustListener = mTrustListeners.remove(trustListener); if (iTrustListener != null) { @@ -207,6 +261,8 @@ public class TrustManager { /** * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}. + * + * @hide */ @RequiresPermission(android.Manifest.permission.TRUST_LISTENER) public boolean isTrustUsuallyManaged(int userId) { @@ -223,8 +279,10 @@ public class TrustManager { * can be skipped. * * @param userId + * + * @hide */ - @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE) + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void unlockedByBiometricForUser(int userId, BiometricSourceType source) { try { mService.unlockedByBiometricForUser(userId, source); @@ -235,8 +293,10 @@ public class TrustManager { /** * Clears authentication by the specified biometric type for all users. + * + * @hide */ - @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE) + @RequiresPermission(ACCESS_KEYGUARD_SECURE_STORAGE) public void clearAllBiometricRecognized(BiometricSourceType source, int unlockedUser) { try { mService.clearAllBiometricRecognized(source, unlockedUser); @@ -264,6 +324,7 @@ public class TrustManager { } }; + /** @hide */ public interface TrustListener { /** diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java index fba61cfd801ec..5bd423599f5d1 100644 --- a/core/java/android/service/trust/TrustAgentService.java +++ b/core/java/android/service/trust/TrustAgentService.java @@ -21,6 +21,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SdkConstant; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.app.Service; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; @@ -310,9 +311,10 @@ public class TrustAgentService extends Service { * * @see #FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE * - * TODO(b/213631672): Add CTS tests + * TODO(b/213631672): Remove @hide and @TestApi * @hide */ + @TestApi public void onUserRequestedUnlock() { } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 3a842ee6e7f3f..33bc90e078b81 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -5316,7 +5316,7 @@ android:protectionLevel="signature|setup|role" /> + @hide @TestApi --> diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 9bed24d05f3d8..52f7d101ce993 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -122,7 +122,8 @@ public class TrustManagerService extends SystemService { private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13; private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14; private static final int MSG_SCHEDULE_TRUST_TIMEOUT = 15; - public static final int MSG_USER_REQUESTED_UNLOCK = 16; + private static final int MSG_USER_REQUESTED_UNLOCK = 16; + private static final int MSG_ENABLE_TRUST_AGENT = 17; private static final String REFRESH_DEVICE_LOCKED_EXCEPT_USER = "except"; @@ -631,6 +632,24 @@ public class TrustManagerService extends SystemService { } } + + /** + * Uses {@link LockPatternUtils} to enable the setting for trust agent in the specified + * component name. This should only be used for testing. + */ + private void enableTrustAgentForUserForTest(@NonNull ComponentName componentName, int userId) { + Log.i(TAG, + "Enabling trust agent " + componentName.flattenToString() + " for user " + userId); + List agents = + new ArrayList<>(mLockPatternUtils.getEnabledTrustAgents(userId)); + if (!agents.contains(componentName)) { + agents.add(componentName); + } + // Even if the agent was already there, we still call setEnabledTrustAgents to trigger a + // refresh of installed agents. + mLockPatternUtils.setEnabledTrustAgents(agents, userId); + } + boolean isDeviceLockedInner(int userId) { synchronized (mDeviceLockedForUser) { return mDeviceLockedForUser.get(userId, true); @@ -929,6 +948,7 @@ public class TrustManagerService extends SystemService { continue; } allowedAgents.add(resolveInfo); + if (DEBUG) Slog.d(TAG, "Adding agent " + getComponentName(resolveInfo)); } return allowedAgents; } @@ -1157,6 +1177,13 @@ public class TrustManagerService extends SystemService { mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED); } + @Override + public void enableTrustAgentForUserForTest(ComponentName componentName, int userId) + throws RemoteException { + enforceReportPermission(); + mHandler.obtainMessage(MSG_ENABLE_TRUST_AGENT, userId, 0, componentName).sendToTarget(); + } + @Override public void reportKeyguardShowingChanged() throws RemoteException { enforceReportPermission(); @@ -1433,6 +1460,9 @@ public class TrustManagerService extends SystemService { // This is also called when the security mode of a user changes. refreshDeviceLockedForUser(UserHandle.USER_ALL); break; + case MSG_ENABLE_TRUST_AGENT: + enableTrustAgentForUserForTest((ComponentName) msg.obj, msg.arg1); + break; case MSG_KEYGUARD_SHOWING_CHANGED: refreshDeviceLockedForUser(mCurrentUser); break;