Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af33258c authored by Billy Huang's avatar Billy Huang Committed by Automerger Merge Worker
Browse files

Merge "Add flag to subscribe trust manager to primary auth events" into main am: 499a786e

parents 31bbf075 499a786e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -92,3 +92,10 @@ flag {
    description: "Add a dump capability for attestation_verification service"
    bug: "335498868"
}

flag {
  name: "should_trust_manager_listen_for_primary_auth"
  namespace: "biometrics"
  description: "Causes TrustManagerService to listen for credential attempts and ignore reports from upstream"
  bug: "323086607"
}
+8 −2
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static android.security.Flags.reportPrimaryAuthAttempts;
import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;

import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -414,7 +416,9 @@ public class LockPatternUtils {
            return;
        }
        getDevicePolicyManager().reportFailedPasswordAttempt(userId);
        getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
        if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
            getTrustManager().reportUnlockAttempt(/* authenticated= */ false, userId);
        }
    }

    @UnsupportedAppUsage
@@ -423,7 +427,9 @@ public class LockPatternUtils {
            return;
        }
        getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
        getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
        if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
            getTrustManager().reportUnlockAttempt(/* authenticated= */ true, userId);
        }
    }

    public void reportPasswordLockout(int timeoutMs, int userId) {
+23 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.trust;

import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
import static android.service.trust.GrantTrustResult.STATUS_UNLOCKED_BY_GRANT;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;

@@ -84,6 +85,9 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.LockSettingsStateListener;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.servicewatcher.CurrentUserServiceSupplier;
import com.android.server.servicewatcher.ServiceWatcher;
@@ -159,6 +163,7 @@ public class TrustManagerService extends SystemService {

    /* package */ final TrustArchive mArchive = new TrustArchive();
    private final Context mContext;
    private final LockSettingsInternal mLockSettings;
    private final LockPatternUtils mLockPatternUtils;
    private final KeyStoreAuthorization mKeyStoreAuthorization;
    private final UserManager mUserManager;
@@ -250,6 +255,20 @@ public class TrustManagerService extends SystemService {

    private final StrongAuthTracker mStrongAuthTracker;

    // Used to subscribe to device credential auth attempts.
    private final LockSettingsStateListener mLockSettingsStateListener =
            new LockSettingsStateListener() {
                @Override
                public void onAuthenticationSucceeded(int userId) {
                    mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, 1, userId).sendToTarget();
                }

                @Override
                public void onAuthenticationFailed(int userId) {
                    mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, 0, userId).sendToTarget();
                }
            };

    private boolean mTrustAgentsCanRun = false;
    private int mCurrentUser = UserHandle.USER_SYSTEM;

@@ -294,6 +313,7 @@ public class TrustManagerService extends SystemService {
        mHandler = createHandler(injector.getLooper());
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        mLockSettings = LocalServices.getService(LockSettingsInternal.class);
        mLockPatternUtils = injector.getLockPatternUtils();
        mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
        mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
@@ -315,6 +335,9 @@ public class TrustManagerService extends SystemService {
            checkNewAgents();
            mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
            mReceiver.register(mContext);
            if (shouldTrustManagerListenForPrimaryAuth()) {
                mLockSettings.registerLockSettingsStateListener(mLockSettingsStateListener);
            }
            mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
            mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
            mFaceManager = mContext.getSystemService(FaceManager.class);
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ android_test {
        "mockingservicestests-utils-mockito",
        "mockito-target-extended-minus-junit4",
        "platform-compat-test-rules",
        "platform-parametric-runner-lib",
        "platform-test-annotations",
        "PlatformProperties",
        "service-blobstore",
+40 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.trust;

import static android.security.Flags.FLAG_SHOULD_TRUST_MANAGER_LISTEN_FOR_PRIMARY_AUTH;
import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
@@ -73,6 +75,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.security.KeyStoreAuthorization;
import android.service.trust.GrantTrustResult;
@@ -91,6 +95,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.StrongAuthFlags;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.LockSettingsStateListener;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -101,6 +106,7 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
@@ -112,7 +118,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

@RunWith(ParameterizedAndroidJunit4.class)
public class TrustManagerServiceTest {
    @Parameters(name = "{0}")
    public static List<FlagsParameterization> getParams() {
        return FlagsParameterization.allCombinationsOf(
                FLAG_SHOULD_TRUST_MANAGER_LISTEN_FOR_PRIMARY_AUTH);
    }

    @Rule
    public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
@@ -121,6 +136,9 @@ public class TrustManagerServiceTest {
            .mockStatic(WindowManagerGlobal.class)
            .build();

    @Rule
    public final SetFlagsRule mSetFlagsRule;

    @Rule
    public final MockContext mMockContext = new MockContext(
            ApplicationProvider.getApplicationContext());
@@ -162,6 +180,10 @@ public class TrustManagerServiceTest {
    private ITrustManager mTrustManager;
    private ActivityManagerInternal mPreviousActivityManagerInternal;

    public TrustManagerServiceTest(FlagsParameterization flags) {
        mSetFlagsRule = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT, flags);
    }

    @Before
    public void setUp() throws Exception {
        when(mActivityManager.isUserRunning(TEST_USER_ID)).thenReturn(true);
@@ -594,12 +616,28 @@ public class TrustManagerServiceTest {
    }

    private void attemptSuccessfulUnlock(int userId) throws RemoteException {
        if (shouldTrustManagerListenForPrimaryAuth()) {
            ArgumentCaptor<LockSettingsStateListener> captor =
                    ArgumentCaptor.forClass(LockSettingsStateListener.class);
            verify(mLockSettingsInternal).registerLockSettingsStateListener(captor.capture());
            LockSettingsStateListener listener = captor.getValue();
            listener.onAuthenticationSucceeded(userId);
        } else {
            mTrustManager.reportUnlockAttempt(/* successful= */ true, userId);
        }
    }

    private void attemptFailedUnlock(int userId) throws RemoteException {
        if (shouldTrustManagerListenForPrimaryAuth()) {
            ArgumentCaptor<LockSettingsStateListener> captor =
                    ArgumentCaptor.forClass(LockSettingsStateListener.class);
            verify(mLockSettingsInternal).registerLockSettingsStateListener(captor.capture());
            LockSettingsStateListener listener = captor.getValue();
            listener.onAuthenticationFailed(userId);
        } else {
            mTrustManager.reportUnlockAttempt(/* successful= */ false, userId);
        }
    }

    private void grantRenewableTrust(ITrustAgentServiceCallback callback) throws RemoteException {
        Log.i(TAG, "Granting trust");
Loading