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

Commit 49700107 authored by Jack He's avatar Jack He Committed by Kyunglyul Hyun
Browse files

GATT: Split native interface from GattService

This prepares GattService for mock based unit testing

Bug: 235781579
Test: atest BluetoothInstrumentationTests, flash and connect to BLE
devices
Tag: #stability

Change-Id: I2e9f0fabf8b7505ab83d42c0513fc6d675e15b03
parent 2d4560b7
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -2443,7 +2443,7 @@ static JNINativeMethod sScanMethods[] = {
     (void*)gattSetScanParametersNative},
};

// JNI functions defined in GattService class.
// JNI functions defined in GattNativeInterface class.
static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void*)classInitNative},
    {"initializeNative", "()V", (void*)initializeNative},
@@ -2528,7 +2528,8 @@ int register_com_android_bluetooth_gatt(JNIEnv* env) {
      env, "com/android/bluetooth/gatt/PeriodicScanManager",
      sPeriodicScanMethods, NELEM(sPeriodicScanMethods));
  return register_success &
         jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
                                  sMethods, NELEM(sMethods));
         jniRegisterNativeMethods(
             env, "com/android/bluetooth/gatt/GattNativeInterface", sMethods,
             NELEM(sMethods));
}
}  // namespace android
+635 −0

File added.

Preview size limit exceeded, changes collapsed.

+63 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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.bluetooth.gatt;

import android.util.Log;

import com.android.bluetooth.Utils;
/**
 * Factory class for object initialization to help with unit testing
 */
public class GattObjectsFactory {
    private static final String TAG = GattObjectsFactory.class.getSimpleName();
    private static GattObjectsFactory sInstance;
    private static final Object INSTANCE_LOCK = new Object();

    private GattObjectsFactory() {
    }

    /**
     * Get the singleton instance of object factory
     *
     * @return the singleton instance, guaranteed not null
     */
    public static GattObjectsFactory getInstance() {
        synchronized (INSTANCE_LOCK) {
            if (sInstance == null) {
                sInstance = new GattObjectsFactory();
            }
        }
        return sInstance;
    }

    /**
     * Allow unit tests to substitute GattObjectsFactory with a test instance
     *
     * @param objectsFactory a test instance of the GattObjectsFactory
     */
    static void setInstanceForTesting(GattObjectsFactory objectsFactory) {
        Utils.enforceInstrumentationTestMode();
        synchronized (INSTANCE_LOCK) {
            Log.d(TAG, "setInstanceForTesting(), set to " + objectsFactory);
            sInstance = objectsFactory;
        }
    }

    public GattNativeInterface getNativeInterface() {
        return GattNativeInterface.getInstance();
    }
}
+53 −149

File changed.

Preview size limit exceeded, changes collapsed.

+22 −1
Original line number Diff line number Diff line
@@ -2,6 +2,10 @@ package com.android.bluetooth.gatt;

import static org.mockito.Mockito.*;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.content.Context;

import androidx.test.InstrumentationRegistry;
@@ -22,6 +26,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Test cases for {@link GattService}.
@@ -30,12 +38,17 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class GattServiceTest {
    private static final int TIMES_UP_AND_DOWN = 3;
    private static final int TIMEOUT_MS = 5_000;
    private Context mTargetContext;
    private GattService mService;

    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();

    private BluetoothAdapter mAdapter;
    @Mock private AdapterService mAdapterService;
    @Mock private GattObjectsFactory mFactory;
    @Mock private GattNativeInterface mNativeInterface;
    private BluetoothDevice mCurrentDevice;

    @Before
    public void setUp() throws Exception {
@@ -44,6 +57,12 @@ public class GattServiceTest {
        MockitoAnnotations.initMocks(this);
        TestUtils.setAdapterService(mAdapterService);
        doReturn(true).when(mAdapterService).isStartedProfile(anyString());

        GattObjectsFactory.setInstanceForTesting(mFactory);
        doReturn(mNativeInterface).when(mFactory).getNativeInterface();

        mAdapter = BluetoothAdapter.getDefaultAdapter();

        TestUtils.startService(mServiceRule, GattService.class);
        mService = GattService.getGattService();
        Assert.assertNotNull(mService);
@@ -59,11 +78,13 @@ public class GattServiceTest {
        mService = GattService.getGattService();
        Assert.assertNull(mService);
        TestUtils.clearAdapterService(mAdapterService);
        GattObjectsFactory.setInstanceForTesting(null);
    }

    @Test
    public void testInitialize() {
        Assert.assertNotNull(GattService.getGattService());
        Assert.assertEquals(mService, GattService.getGattService());
        verify(mNativeInterface).init(eq(mService));
    }

    @Test