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

Commit df165e3e authored by Eric Biggers's avatar Eric Biggers Committed by Android (Google) Code Review
Browse files

Merge "Test both AIDL and HIDL Weaver interfaces in locksettings unit tests" into main

parents 9631cf90 e31ca56a
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -568,7 +568,9 @@ class SyntheticPasswordManager {
        }
    }

    private @Nullable IWeaver getWeaverAidlService() {
    @VisibleForTesting
    @Nullable
    protected IWeaver getWeaverAidlService() {
        final IWeaver aidlWeaver;
        try {
            aidlWeaver =
+28 −4
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@
 */
package com.android.server.locksettings;

import static org.junit.Assert.assertNull;

import android.content.Context;
import android.hardware.weaver.V1_0.IWeaver;
import android.hardware.weaver.IWeaver;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.ArrayMap;
@@ -35,6 +37,8 @@ public class MockSyntheticPasswordManager extends SyntheticPasswordManager {

    private FakeGateKeeperService mGateKeeper;
    private MockWeaverService mWeaverService;
    private IWeaver mWeaverAidl;
    private android.hardware.weaver.V1_0.IWeaver mWeaverHidl;

    public MockSyntheticPasswordManager(Context context, LockSettingsStorage storage,
            FakeGateKeeperService gatekeeper, UserManager userManager,
@@ -112,13 +116,33 @@ public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
        }
    }

    /** Enables MockWeaverService. */
    public void enableWeaver() {
        enableWeaverAidl();
    }

    /** Enables MockWeaverService with the current (AIDL) interface. */
    public void enableWeaverAidl() {
        assertNull(mWeaverService);
        mWeaverService = new MockWeaverService();
        mWeaverAidl = mWeaverService;
    }

    @Override
    protected IWeaver getWeaverHidlService() throws RemoteException {
        return mWeaverService;
    protected IWeaver getWeaverAidlService() {
        return mWeaverAidl;
    }

    public void enableWeaver() {
    /** Enables MockWeaverService with the old (HIDL) interface. */
    public void enableWeaverHidl() {
        assertNull(mWeaverService);
        mWeaverService = new MockWeaverService();
        mWeaverHidl = mWeaverService.asHidl();
    }

    @Override
    protected android.hardware.weaver.V1_0.IWeaver getWeaverHidlService() throws RemoteException {
        return mWeaverHidl;
    }

    public int getSumOfWeaverFailureCounters() {
+103 −21
Original line number Diff line number Diff line
package com.android.server.locksettings;

import android.hardware.weaver.V1_0.IWeaver;
import android.hardware.weaver.V1_0.WeaverConfig;
import android.hardware.weaver.V1_0.WeaverReadResponse;
import android.hardware.weaver.V1_0.WeaverStatus;
import static org.mockito.Mockito.mock;

import android.hardware.weaver.IWeaver;
import android.hardware.weaver.WeaverConfig;
import android.hardware.weaver.WeaverReadResponse;
import android.hardware.weaver.WeaverReadStatus;
import android.os.IBinder;
import android.os.RemoteException;

import java.util.ArrayList;
import java.util.Arrays;

public class MockWeaverService extends IWeaver.Stub {
public class MockWeaverService implements IWeaver {

    private static final int MAX_SLOTS = 8;
    private static final int KEY_LENGTH = 256 / 8;
    private static final int VALUE_LENGTH = 256 / 8;

    private static class WeaverSlot {
        public ArrayList<Byte> key;
        public ArrayList<Byte> value;
        public byte[] key;
        public byte[] value;
        public int failureCounter;
    }

@@ -30,46 +33,125 @@ public class MockWeaverService extends IWeaver.Stub {
    }

    @Override
    public void getConfig(getConfigCallback cb) throws RemoteException {
    public WeaverConfig getConfig() throws RemoteException {
        WeaverConfig config = new WeaverConfig();
        config.keySize = KEY_LENGTH;
        config.valueSize = VALUE_LENGTH;
        config.slots = MAX_SLOTS;
        cb.onValues(WeaverStatus.OK, config);
        return config;
    }

    @Override
    public int write(int slotId, ArrayList<Byte> key, ArrayList<Byte> value)
            throws RemoteException {
    public void write(int slotId, byte[] key, byte[] value) throws RemoteException {
        if (slotId < 0 || slotId >= MAX_SLOTS) {
            throw new RuntimeException("Invalid slot id");
        }
        WeaverSlot slot = mSlots[slotId];
        slot.key = (ArrayList<Byte>) key.clone();
        slot.value = (ArrayList<Byte>) value.clone();
        slot.key = key.clone();
        slot.value = value.clone();
        slot.failureCounter = 0;
        return WeaverStatus.OK;
    }

    @Override
    public void read(int slotId, ArrayList<Byte> key, readCallback cb) throws RemoteException {
    public WeaverReadResponse read(int slotId, byte[] key) throws RemoteException {
        if (slotId < 0 || slotId >= MAX_SLOTS) {
            throw new RuntimeException("Invalid slot id");
        }

        WeaverReadResponse response = new WeaverReadResponse();
        WeaverSlot slot = mSlots[slotId];
        if (key.equals(slot.key)) {
            response.value.addAll(slot.value);
            cb.onValues(WeaverStatus.OK, response);
        WeaverReadResponse response = new WeaverReadResponse();
        if (Arrays.equals(key, slot.key)) {
            response.value = slot.value.clone();
            response.status = WeaverReadStatus.OK;
            slot.failureCounter = 0;
        } else {
            cb.onValues(WeaverStatus.FAILED, response);
            response.status = WeaverReadStatus.INCORRECT_KEY;
            slot.failureCounter++;
        }
        return response;
    }

    @Override
    public String getInterfaceHash() {
        throw new UnsupportedOperationException();
    }

    @Override
    public int getInterfaceVersion() {
        return 2;
    }

    @Override
    public IBinder asBinder() {
        return mock(IBinder.class);
    }

    public int getSumOfFailureCounters() {
        return Arrays.stream(mSlots).mapToInt(slot -> slot.failureCounter).sum();
    }

    /** Returns an adapter object that implements the old (HIDL) Weaver interface. */
    public android.hardware.weaver.V1_0.IWeaver.Stub asHidl() {
        return new MockWeaverServiceHidlAdapter();
    }

    private class MockWeaverServiceHidlAdapter extends android.hardware.weaver.V1_0.IWeaver.Stub {

        @Override
        public void getConfig(getConfigCallback cb) throws RemoteException {
            WeaverConfig aidlConfig = MockWeaverService.this.getConfig();
            android.hardware.weaver.V1_0.WeaverConfig hidlConfig =
                    new android.hardware.weaver.V1_0.WeaverConfig();
            hidlConfig.keySize = aidlConfig.keySize;
            hidlConfig.valueSize = aidlConfig.valueSize;
            hidlConfig.slots = aidlConfig.slots;
            cb.onValues(android.hardware.weaver.V1_0.WeaverStatus.OK, hidlConfig);
        }

        @SuppressWarnings("NonApiType")
        @Override
        public int write(int slotId, ArrayList<Byte> key, ArrayList<Byte> value)
                throws RemoteException {
            MockWeaverService.this.write(slotId, fromByteArrayList(key), fromByteArrayList(value));
            return android.hardware.weaver.V1_0.WeaverStatus.OK;
        }

        @SuppressWarnings("NonApiType")
        @Override
        public void read(int slotId, ArrayList<Byte> key, readCallback cb) throws RemoteException {
            WeaverReadResponse aidlResponse =
                    MockWeaverService.this.read(slotId, fromByteArrayList(key));
            android.hardware.weaver.V1_0.WeaverReadResponse hidlResponse =
                    new android.hardware.weaver.V1_0.WeaverReadResponse();
            int hidlStatus = switch (aidlResponse.status) {
                case WeaverReadStatus.OK -> android.hardware.weaver.V1_0.WeaverStatus.OK;
                case WeaverReadStatus.INCORRECT_KEY ->
                        android.hardware.weaver.V1_0.WeaverReadStatus.INCORRECT_KEY;
                case WeaverReadStatus.THROTTLE ->
                        android.hardware.weaver.V1_0.WeaverReadStatus.THROTTLE;
                default -> android.hardware.weaver.V1_0.WeaverStatus.FAILED;
            };
            if (aidlResponse.value != null) {
                hidlResponse.value = toByteArrayList(aidlResponse.value);
            }
            cb.onValues(hidlStatus, hidlResponse);
        }

        @SuppressWarnings("NonApiType")
        private static ArrayList<Byte> toByteArrayList(byte[] data) {
            ArrayList<Byte> result = new ArrayList<Byte>(data.length);
            for (int i = 0; i < data.length; i++) {
                result.add(data[i]);
            }
            return result;
        }

        @SuppressWarnings("NonApiType")
        private static byte[] fromByteArrayList(ArrayList<Byte> data) {
            byte[] result = new byte[data.size()];
            for (int i = 0; i < data.size(); i++) {
                result[i] = data.get(i);
            }
            return result;
        }
    }
}
+35 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.locksettings;

import android.platform.test.annotations.Presubmit;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.runner.RunWith;

@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
public class WeaverAidlBasedSyntheticPasswordTests extends WeaverBasedSyntheticPasswordTests {

    @Before
    public void setup() {
        mSpManager.enableWeaverAidl();
    }
}
+1 −16
Original line number Diff line number Diff line
@@ -6,28 +6,13 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import android.platform.test.annotations.Presubmit;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.server.locksettings.LockSettingsStorage.PersistentData;

import com.google.android.collect.Sets;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
public class WeaverBasedSyntheticPasswordTests extends SyntheticPasswordTests {

    @Before
    public void enableWeaver() throws Exception {
        mSpManager.enableWeaver();
    }
public abstract class WeaverBasedSyntheticPasswordTests extends SyntheticPasswordTests {

    // Tests that if the device is not yet provisioned and the FRP credential uses Weaver, then the
    // Weaver slot of the FRP credential is not reused.  Assumes that Weaver slots are allocated
Loading