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

Commit 4e401703 authored by Chun-Wei Wang's avatar Chun-Wei Wang Committed by Gerrit Code Review
Browse files

Merge "Add a method to write password data" into main

parents b983c5bc c07b99a2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -109,4 +109,5 @@ interface ILockSettings {
    boolean isWeakEscrowTokenActive(long handle, int userId);
    boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId);
    void unlockUserKeyIfUnsecured(int userId);
    boolean writeRepairModeCredential(int userId);
}
+15 −0
Original line number Diff line number Diff line
@@ -448,6 +448,21 @@ public class LockPatternUtils {
                null /* componentName */, userId);
    }

    /**
     * Save the current password data to the repair mode file.
     *
     * @return true if success or false otherwise.
     */
    public boolean writeRepairModeCredential(int userId) {
        throwIfCalledOnMainThread();
        try {
            return getLockSettings().writeRepairModeCredential(userId);
        } catch (RemoteException re) {
            Log.e(TAG, "Failed to write repair mode credential", re);
            return false;
        }
    }

    /**
     * Check to see if a credential matches the saved one.
     * If credential matches, return an opaque attestation that the challenge was verified.
+35 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import org.mockito.ArgumentCaptor;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -316,6 +317,40 @@ public class LockPatternUtilsTest {
        assertNotEquals(UserHandle.USER_CURRENT_OR_SELF, LockPatternUtils.USER_REPAIR_MODE);
    }

    @Test
    public void testWriteRepairModeCredential_mainThread() {
        createTestLockSettings();
        var context = InstrumentationRegistry.getTargetContext();

        var future = new CompletableFuture<Exception>();
        context.getMainThreadHandler().post(() -> {
            try {
                mLockPatternUtils.writeRepairModeCredential(USER_ID);
                future.complete(null);
            } catch (Exception e) {
                future.complete(e);
            }
        });

        var e = future.join();
        assertThat(e).isNotNull();
        assertThat(e.getMessage()).contains("should not be called from the main thread");
    }

    @Test
    public void testWriteRepairModeCredential() throws Exception {
        var ils = createTestLockSettings();

        when(ils.writeRepairModeCredential(USER_ID)).thenReturn(false);
        assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isFalse();

        when(ils.writeRepairModeCredential(USER_ID)).thenReturn(true);
        assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isTrue();

        when(ils.writeRepairModeCredential(USER_ID)).thenThrow(new RemoteException());
        assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isFalse();
    }

    private TestStrongAuthTracker createStrongAuthTracker() {
        final Context context = new ContextWrapper(InstrumentationRegistry.getTargetContext());
        return new TestStrongAuthTracker(context, Looper.getMainLooper());
+14 −0
Original line number Diff line number Diff line
@@ -1773,6 +1773,20 @@ public class LockSettingsService extends ILockSettings.Stub {
        }
    }

    @Override
    public boolean writeRepairModeCredential(int userId) {
        checkWritePermission();
        final long identity = Binder.clearCallingIdentity();
        try {
            synchronized (mSpManager) {
                long protectorId = getCurrentLskfBasedProtectorId(userId);
                return mSpManager.writeRepairModeCredentialLocked(protectorId, userId);
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
     * @param savedCredential if the user is a profile with
     * {@link UserManager#isCredentialSharableWithParent()} with unified challenge and
+23 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server.locksettings;
import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE;
import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;

@@ -199,6 +201,27 @@ public class LockscreenRepairModeTest extends BaseLockSettingsServiceTests {
                        .getResponseCode());
    }

    @Test
    public void writeRepairModeCredential_noLock() {
        assertThat(mService.writeRepairModeCredential(PRIMARY_USER_ID)).isFalse();
    }

    @Test
    public void writeRepairModeCredential_hasLock() {
        mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
        assertThat(mService.writeRepairModeCredential(PRIMARY_USER_ID)).isTrue();
    }

    @Test
    public void writeRepairModeCredential_verifyRepairModeUser() {
        mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
        mService.writeRepairModeCredential(PRIMARY_USER_ID);
        setRepairModeActive(true);

        var response = mService.verifyCredential(newPin("1234"), USER_REPAIR_MODE, 0);
        assertThat(response.isMatched()).isTrue();
    }

    private void setRepairModeActive(boolean active) {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.REPAIR_MODE_ACTIVE, active ? 1 : 0);