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

Commit 7bd6f7bd authored by My Name's avatar My Name Committed by Hieu Dang
Browse files

Add test & fix bug for BluetoothOppServiceTest

Add test for BluetoothOppService#trimDatabase &
fixing b/262201478

Test: atest BluetoothInstrumentationTests
Bug: 237467631
Bug: 262201478
Tag: #refactor
Change-Id: I32a84781d8eb4e1893f627b583920b0ef346f9da
parent aea515f1
Loading
Loading
Loading
Loading
+11 −8
Original line number Original line Diff line number Diff line
@@ -55,6 +55,7 @@ import android.os.Process;
import android.sysprop.BluetoothProperties;
import android.sysprop.BluetoothProperties;
import android.util.Log;
import android.util.Log;


import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.BluetoothObexTransport;
import com.android.bluetooth.BluetoothObexTransport;
import com.android.bluetooth.IObexConnectionHandler;
import com.android.bluetooth.IObexConnectionHandler;
import com.android.bluetooth.ObexServerSockets;
import com.android.bluetooth.ObexServerSockets;
@@ -184,7 +185,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
                    + BluetoothShare.USER_CONFIRMATION + "="
                    + BluetoothShare.USER_CONFIRMATION + "="
                    + BluetoothShare.USER_CONFIRMATION_PENDING;
                    + BluetoothShare.USER_CONFIRMATION_PENDING;


    private static final String WHERE_INVISIBLE_UNCONFIRMED =
    @VisibleForTesting
    static final String WHERE_INVISIBLE_UNCONFIRMED =
            "(" + BluetoothShare.STATUS + " > " + BluetoothShare.STATUS_SUCCESS + " AND "
            "(" + BluetoothShare.STATUS + " > " + BluetoothShare.STATUS_SUCCESS + " AND "
                    + INVISIBLE + ") OR (" + WHERE_CONFIRM_PENDING_INBOUND + ")";
                    + INVISIBLE + ") OR (" + WHERE_CONFIRM_PENDING_INBOUND + ")";


@@ -1116,22 +1118,23 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
    }
    }


    // Run in a background thread at boot.
    // Run in a background thread at boot.
    private static void trimDatabase(ContentResolver contentResolver) {
    @VisibleForTesting
    static void trimDatabase(ContentResolver contentResolver) {
        if (contentResolver.acquireContentProviderClient(BluetoothShare.CONTENT_URI) == null) {
        if (contentResolver.acquireContentProviderClient(BluetoothShare.CONTENT_URI) == null) {
            Log.w(TAG, "ContentProvider doesn't exist");
            Log.w(TAG, "ContentProvider doesn't exist");
            return;
            return;
        }
        }


        // remove the invisible/unconfirmed inbound shares
        // remove the invisible/unconfirmed inbound shares
        int delNum = contentResolver.delete(BluetoothShare.CONTENT_URI, WHERE_INVISIBLE_UNCONFIRMED,
        int delNum = BluetoothMethodProxy.getInstance().contentResolverDelete(
                null);
                contentResolver, BluetoothShare.CONTENT_URI, WHERE_INVISIBLE_UNCONFIRMED, null);
        if (V) {
        if (V) {
            Log.v(TAG, "Deleted shares, number = " + delNum);
            Log.v(TAG, "Deleted shares, number = " + delNum);
        }
        }


        // Keep the latest inbound and successful shares.
        // Keep the latest inbound and successful shares.
        Cursor cursor =
        Cursor cursor = BluetoothMethodProxy.getInstance().contentResolverQuery(
                contentResolver.query(BluetoothShare.CONTENT_URI, new String[]{BluetoothShare._ID},
                contentResolver, BluetoothShare.CONTENT_URI, new String[]{BluetoothShare._ID},
                        WHERE_INBOUND_SUCCESS, null, BluetoothShare._ID); // sort by id
                        WHERE_INBOUND_SUCCESS, null, BluetoothShare._ID); // sort by id
        if (cursor == null) {
        if (cursor == null) {
            return;
            return;
@@ -1143,8 +1146,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
            if (cursor.moveToPosition(numToDelete)) {
            if (cursor.moveToPosition(numToDelete)) {
                int columnId = cursor.getColumnIndexOrThrow(BluetoothShare._ID);
                int columnId = cursor.getColumnIndexOrThrow(BluetoothShare._ID);
                long id = cursor.getLong(columnId);
                long id = cursor.getLong(columnId);
                delNum = contentResolver.delete(BluetoothShare.CONTENT_URI,
                delNum = BluetoothMethodProxy.getInstance().contentResolverDelete(contentResolver,
                        BluetoothShare._ID + " < " + id, null);
                        BluetoothShare.CONTENT_URI, BluetoothShare._ID + " < " + id, null);
                if (V) {
                if (V) {
                    Log.v(TAG, "Deleted old inbound success share: " + delNum);
                    Log.v(TAG, "Deleted old inbound success share: " + delNum);
                }
                }
+46 −6
Original line number Original line Diff line number Diff line
@@ -15,19 +15,26 @@
 */
 */
package com.android.bluetooth.opp;
package com.android.bluetooth.opp;


import static com.android.bluetooth.opp.BluetoothOppService.WHERE_INVISIBLE_UNCONFIRMED;

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


import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter;
import android.net.Uri;
import android.content.ContentResolver;
import android.database.MatrixCursor;


import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ServiceTestRule;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.runner.AndroidJUnit4;


import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.AdapterService;


@@ -43,18 +50,21 @@ import org.mockito.MockitoAnnotations;


@RunWith(AndroidJUnit4.class)
@RunWith(AndroidJUnit4.class)
public class BluetoothOppServiceTest {
public class BluetoothOppServiceTest {
    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
    @Rule

    public final ServiceTestRule mServiceRule = new ServiceTestRule();
    @Mock
    BluetoothMethodProxy mMethodProxy;
    private BluetoothOppService mService = null;
    private BluetoothOppService mService = null;
    private BluetoothAdapter mAdapter = null;
    private BluetoothAdapter mAdapter = null;

    @Mock
    @Mock private AdapterService mAdapterService;
    private AdapterService mAdapterService;


    @Before
    @Before
    public void setUp() throws Exception {
    public void setUp() throws Exception {
        Assume.assumeTrue("Ignore test when BluetoothOppService is not enabled",
        Assume.assumeTrue("Ignore test when BluetoothOppService is not enabled",
                BluetoothOppService.isEnabled());
                BluetoothOppService.isEnabled());
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        BluetoothMethodProxy.setInstanceForTesting(mMethodProxy);
        TestUtils.setAdapterService(mAdapterService);
        TestUtils.setAdapterService(mAdapterService);
        doReturn(true, false).when(mAdapterService).isStartedProfile(anyString());
        doReturn(true, false).when(mAdapterService).isStartedProfile(anyString());
        TestUtils.startService(mServiceRule, BluetoothOppService.class);
        TestUtils.startService(mServiceRule, BluetoothOppService.class);
@@ -67,6 +77,7 @@ public class BluetoothOppServiceTest {


    @After
    @After
    public void tearDown() throws Exception {
    public void tearDown() throws Exception {
        BluetoothMethodProxy.setInstanceForTesting(null);
        if (!BluetoothOppService.isEnabled()) {
        if (!BluetoothOppService.isEnabled()) {
            return;
            return;
        }
        }
@@ -119,4 +130,33 @@ public class BluetoothOppServiceTest {
        // should not throw
        // should not throw
        mService.dump(new StringBuilder());
        mService.dump(new StringBuilder());
    }
    }

    @Test
    public void trimDatabase_trimsOldOrInvisibleRecords() {
        ContentResolver contentResolver = InstrumentationRegistry
                .getInstrumentation().getTargetContext().getContentResolver();
        Assume.assumeTrue("Ignore test when there is no content provider",
                contentResolver.acquireContentProviderClient(BluetoothShare.CONTENT_URI) != null);

        doReturn(1 /* any int is Ok */).when(mMethodProxy).contentResolverDelete(
		eq(contentResolver), eq(BluetoothShare.CONTENT_URI), anyString(), any());

        MatrixCursor cursor = new MatrixCursor(new String[]{BluetoothShare._ID}, 500);
        for (long i = 0; i < Constants.MAX_RECORDS_IN_DATABASE + 20; i++) {
            cursor.addRow(new Object[]{i});
        }

        doReturn(cursor).when(mMethodProxy).contentResolverQuery(eq(contentResolver),
                eq(BluetoothShare.CONTENT_URI), any(), any(), any(), any());

        BluetoothOppService.trimDatabase(contentResolver);

        // check trimmed invisible records
        verify(mMethodProxy).contentResolverDelete(eq(contentResolver),
                eq(BluetoothShare.CONTENT_URI), eq(WHERE_INVISIBLE_UNCONFIRMED), any());

        // check trimmed old records
        verify(mMethodProxy).contentResolverDelete(eq(contentResolver),
                eq(BluetoothShare.CONTENT_URI), eq(BluetoothShare._ID + " < " + 20), any());
    }
}
}