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

Commit c6e7d008 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Wipe the data in IpMemoryStore database upon network factory reset." into qt-dev

parents face4167 f959756f
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -410,6 +410,7 @@ public class IpMemoryStoreDatabase {
    private static final String[] DATA_COLUMN = new String[] {
            PrivateDataContract.COLNAME_DATA
    };

    @Nullable
    static byte[] retrieveBlob(@NonNull final SQLiteDatabase db, @NonNull final String key,
            @NonNull final String clientId, @NonNull final String name) {
@@ -431,6 +432,57 @@ public class IpMemoryStoreDatabase {
        return result;
    }

    /**
     * Wipe all data in tables when network factory reset occurs.
     */
    static void wipeDataUponNetworkReset(@NonNull final SQLiteDatabase db) {
        for (int remainingRetries = 3; remainingRetries > 0; --remainingRetries) {
            db.beginTransaction();
            try {
                db.delete(NetworkAttributesContract.TABLENAME, null, null);
                db.delete(PrivateDataContract.TABLENAME, null, null);
                final Cursor cursorNetworkAttributes = db.query(
                        // table name
                        NetworkAttributesContract.TABLENAME,
                        // column name
                        new String[] { NetworkAttributesContract.COLNAME_L2KEY },
                        null, // selection
                        null, // selectionArgs
                        null, // groupBy
                        null, // having
                        null, // orderBy
                        "1"); // limit
                if (0 != cursorNetworkAttributes.getCount()) {
                    cursorNetworkAttributes.close();
                    continue;
                }
                cursorNetworkAttributes.close();
                final Cursor cursorPrivateData = db.query(
                        // table name
                        PrivateDataContract.TABLENAME,
                        // column name
                        new String[] { PrivateDataContract.COLNAME_L2KEY },
                        null, // selection
                        null, // selectionArgs
                        null, // groupBy
                        null, // having
                        null, // orderBy
                        "1"); // limit
                if (0 != cursorPrivateData.getCount()) {
                    cursorPrivateData.close();
                    continue;
                }
                cursorPrivateData.close();
                db.setTransactionSuccessful();
                return;
            } catch (SQLiteException e) {
                Log.e(TAG, "Could not wipe the data in database", e);
            } finally {
                db.endTransaction();
            }
        }
    }

    /**
     * The following is a horrible hack that is necessary because the Android SQLite API does not
     * have a way to query a binary blob. This, almost certainly, is an overlook.
+4 −0
Original line number Diff line number Diff line
@@ -410,8 +410,12 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub {
        });
    }

    /**
     * Wipe the data in IpMemoryStore database upon network factory reset.
     */
    @Override
    public void factoryReset() {
        mExecutor.execute(() -> IpMemoryStoreDatabase.wipeDataUponNetworkReset(mDb));
    }

    /** Get db size threshold. */
+100 −28
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@@ -77,7 +78,11 @@ public class IpMemoryStoreServiceTest {
    private static final int DEFAULT_TIMEOUT_MS = 5000;
    private static final int LONG_TIMEOUT_MS = 30000;
    private static final int FAKE_KEY_COUNT = 20;
    private static final long LEASE_EXPIRY_NULL = -1L;
    private static final int MTU_NULL = -1;
    private static final String[] FAKE_KEYS;
    private static final byte[] TEST_BLOB_DATA = new byte[] { -3, 6, 8, -9, 12,
            -128, 0, 89, 112, 91, -34 };
    static {
        FAKE_KEYS = new String[FAKE_KEY_COUNT];
        for (int i = 0; i < FAKE_KEYS.length; ++i) {
@@ -124,6 +129,29 @@ public class IpMemoryStoreServiceTest {
        mDbFile.delete();
    }

    /** Helper method to build test network attributes */
    private static NetworkAttributes.Builder buildTestNetworkAttributes(
            final Inet4Address ipAddress, final long expiry, final String hint,
            final List<InetAddress> dnsServers, final int mtu) {
        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
        if (null != ipAddress) {
            na.setAssignedV4Address(ipAddress);
        }
        if (LEASE_EXPIRY_NULL != expiry) {
            na.setAssignedV4AddressExpiry(expiry);
        }
        if (null != hint) {
            na.setGroupHint(hint);
        }
        if (null != dnsServers) {
            na.setDnsAddresses(dnsServers);
        }
        if (MTU_NULL != mtu) {
            na.setMtu(mtu);
        }
        return na;
    }

    /** Helper method to make a vanilla IOnStatusListener */
    private IOnStatusListener onStatus(Consumer<Status> functor) {
        return new IOnStatusListener() {
@@ -265,7 +293,7 @@ public class IpMemoryStoreServiceTest {
        }
    }

    // Helper methods to factorize more boilerplate
    // Helper method to store network attributes to database
    private void storeAttributes(final String l2Key, final NetworkAttributes na) {
        storeAttributes("Did not complete storing attributes", l2Key, na);
    }
@@ -278,15 +306,28 @@ public class IpMemoryStoreServiceTest {
                })));
    }

    // Helper method to store blob data to database
    private void storeBlobOrFail(final String l2Key, final Blob b, final byte[] data) {
        storeBlobOrFail("Did not complete storing private data", l2Key, b, data);
    }
    private void storeBlobOrFail(final String timeoutMessage, final String l2Key, final Blob b,
            final byte[] data) {
        b.data = data;
        doLatched(timeoutMessage, latch -> mService.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME,
                b, onStatus(status -> {
                    assertTrue("Store status not successful : " + status.resultCode,
                            status.isSuccess());
                    latch.countDown();
                })));
    }

    /** Insert large data that db size will be over threshold for maintenance test usage. */
    private void insertFakeDataAndOverThreshold() {
        try {
            final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
            na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
            na.setGroupHint("hint1");
            na.setMtu(219);
            na.setDnsAddresses(Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")));
            final byte[] data = new byte[]{-3, 6, 8, -9, 12, -128, 0, 89, 112, 91, -34};
            final NetworkAttributes.Builder na = buildTestNetworkAttributes(
                    (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
                    "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
                    219);
            final long time = System.currentTimeMillis() - 1;
            for (int i = 0; i < 1000; i++) {
                int errorCode = IpMemoryStoreDatabase.storeNetworkAttributes(
@@ -298,7 +339,8 @@ public class IpMemoryStoreServiceTest {
                assertEquals(errorCode, Status.SUCCESS);

                errorCode = IpMemoryStoreDatabase.storeBlob(
                        mService.mDb, "fakeKey" + i, TEST_CLIENT_ID, TEST_DATA_NAME, data);
                        mService.mDb, "fakeKey" + i, TEST_CLIENT_ID, TEST_DATA_NAME,
                        TEST_BLOB_DATA);
                assertEquals(errorCode, Status.SUCCESS);
            }

@@ -320,12 +362,10 @@ public class IpMemoryStoreServiceTest {

    @Test
    public void testNetworkAttributes() throws UnknownHostException {
        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
        na.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000);
        na.setGroupHint("hint1");
        na.setMtu(219);
        final String l2Key = FAKE_KEYS[0];
        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
        NetworkAttributes attributes = na.build();
        storeAttributes(l2Key, attributes);

@@ -420,16 +460,9 @@ public class IpMemoryStoreServiceTest {

    @Test
    public void testPrivateData() {
        final Blob b = new Blob();
        b.data = new byte[] { -3, 6, 8, -9, 12, -128, 0, 89, 112, 91, -34 };
        final String l2Key = FAKE_KEYS[0];
        doLatched("Did not complete storing private data", latch ->
                mService.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b,
                        onStatus(status -> {
                            assertTrue("Store status not successful : " + status.resultCode,
                                    status.isSuccess());
                            latch.countDown();
                        })));
        final Blob b = new Blob();
        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);

        doLatched("Did not complete retrieving private data", latch ->
                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
@@ -564,11 +597,10 @@ public class IpMemoryStoreServiceTest {

    @Test
    public void testIsSameNetwork() throws UnknownHostException {
        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
        na.setGroupHint("hint1");
        na.setMtu(219);
        na.setDnsAddresses(Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")));
        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
                (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
                "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
                219);

        storeAttributes(FAKE_KEYS[0], na.build());
        // 0 and 1 have identical attributes
@@ -601,7 +633,6 @@ public class IpMemoryStoreServiceTest {
                })));
    }


    @Test
    public void testFullMaintenance() {
        insertFakeDataAndOverThreshold();
@@ -660,4 +691,45 @@ public class IpMemoryStoreServiceTest {
        // still be over the threshold.
        assertTrue(mService.isDbSizeOverThreshold());
    }

    @Test
    public void testFactoryReset() throws UnknownHostException {
        final String l2Key = FAKE_KEYS[0];

        // store network attributes
        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
        storeAttributes(l2Key, na.build());

        // store private data blob
        final Blob b = new Blob();
        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);

        // wipe all data in Database
        mService.factoryReset();

        // retrieved network attributes should be null
        doLatched("Did not complete retrieving attributes", latch ->
                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
                        (status, key, attr) -> {
                            assertTrue("Retrieve network attributes not successful : "
                                    + status.resultCode, status.isSuccess());
                            assertEquals(l2Key, key);
                            assertNull(attr);
                            latch.countDown();
                        })));

        // retrieved private data blob should be null
        doLatched("Did not complete retrieving private data", latch ->
                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
                        (status, key, name, data) -> {
                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
                                    status.isSuccess());
                            assertEquals(l2Key, key);
                            assertEquals(name, TEST_DATA_NAME);
                            assertNull(data);
                            latch.countDown();
                        })));
    }
}