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

Commit 8ea171aa authored by William Escande's avatar William Escande Committed by Gerrit Code Review
Browse files

Merge changes Ib0eedf40,Iec56b7ef

* changes:
  Delete separate method to construct ManagerService
  BluetoothManagerService: Setup with custom Looper
parents 38ae3932 a640bc41
Loading
Loading
Loading
Loading
+24 −33
Original line number Original line Diff line number Diff line
@@ -67,7 +67,6 @@ import android.database.ContentObserver;
import android.os.Binder;
import android.os.Binder;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
@@ -142,23 +141,23 @@ class BluetoothManagerService {
    // Delay for retrying enable and disable in msec
    // Delay for retrying enable and disable in msec
    private static final int ENABLE_DISABLE_DELAY_MS = 300;
    private static final int ENABLE_DISABLE_DELAY_MS = 300;


    private static final int MESSAGE_ENABLE = 1;
    @VisibleForTesting static final int MESSAGE_ENABLE = 1;
    @VisibleForTesting static final int MESSAGE_DISABLE = 2;
    @VisibleForTesting static final int MESSAGE_DISABLE = 2;
    private static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3;
    @VisibleForTesting static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3;
    private static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4;
    @VisibleForTesting static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4;
    private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
    @VisibleForTesting static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
    private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
    @VisibleForTesting static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
    private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
    @VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
    private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
    @VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
    private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
    @VisibleForTesting static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
    private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
    @VisibleForTesting static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
    private static final int MESSAGE_TIMEOUT_BIND = 100;
    @VisibleForTesting static final int MESSAGE_TIMEOUT_BIND = 100;
    private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
    @VisibleForTesting static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
    private static final int MESSAGE_USER_SWITCHED = 300;
    @VisibleForTesting static final int MESSAGE_USER_SWITCHED = 300;
    private static final int MESSAGE_USER_UNLOCKED = 301;
    @VisibleForTesting static final int MESSAGE_USER_UNLOCKED = 301;
    private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
    @VisibleForTesting static final int MESSAGE_ADD_PROXY_DELAYED = 400;
    private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
    @VisibleForTesting static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
    private static final int MESSAGE_RESTORE_USER_SETTING = 500;
    @VisibleForTesting static final int MESSAGE_RESTORE_USER_SETTING = 500;


    private static final int RESTORE_SETTING_TO_ON = 1;
    private static final int RESTORE_SETTING_TO_ON = 1;
    private static final int RESTORE_SETTING_TO_OFF = 0;
    private static final int RESTORE_SETTING_TO_OFF = 0;
@@ -284,9 +283,7 @@ class BluetoothManagerService {


    private final BluetoothAdapterState mState = new BluetoothAdapterState();
    private final BluetoothAdapterState mState = new BluetoothAdapterState();


    private final HandlerThread mBluetoothHandlerThread =
    private final BluetoothHandler mHandler;
            BluetoothServerProxy.getInstance().createHandlerThread("BluetoothManagerService");
    @VisibleForTesting private final BluetoothHandler mHandler;
    private int mErrorRecoveryRetryCounter = 0;
    private int mErrorRecoveryRetryCounter = 0;


    private final boolean mIsHearingAidProfileSupported;
    private final boolean mIsHearingAidProfileSupported;
@@ -653,19 +650,17 @@ class BluetoothManagerService {
                }
                }
            };
            };


    BluetoothManagerService(Context context) {
    BluetoothManagerService(@NonNull Context context, @NonNull Looper looper) {
        mContext = context;
        mContext = requireNonNull(context, "Context cannot be null");
        requireNonNull(looper, "Looper cannot be null");

        mUserManager =
        mUserManager =
                requireNonNull(
                requireNonNull(
                        mContext.getSystemService(UserManager.class),
                        mContext.getSystemService(UserManager.class),
                        "UserManager system service cannot be null");
                        "UserManager system service cannot be null");


        mBinder = new BluetoothServiceBinder(this, mContext, mUserManager);
        mBinder = new BluetoothServiceBinder(this, mContext, mUserManager);
        mBluetoothHandlerThread.start();
        mHandler = new BluetoothHandler(looper);
        mHandler =
                BluetoothServerProxy.getInstance()
                        .newBluetoothHandler(
                                new BluetoothHandler(mBluetoothHandlerThread.getLooper()));


        mContentResolver = mContext.getContentResolver();
        mContentResolver = mContext.getContentResolver();


@@ -740,15 +735,11 @@ class BluetoothManagerService {
                || airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {
                || airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {
            mBluetoothAirplaneModeListener =
            mBluetoothAirplaneModeListener =
                    new BluetoothAirplaneModeListener(
                    new BluetoothAirplaneModeListener(
                            this,
                            this, looper, mContext, mBluetoothNotificationManager);
                            mBluetoothHandlerThread.getLooper(),
                            mContext,
                            mBluetoothNotificationManager);
        }
        }


        mBluetoothSatelliteModeListener =
        mBluetoothSatelliteModeListener =
                new BluetoothSatelliteModeListener(
                new BluetoothSatelliteModeListener(this, looper, mContext);
                        this, mBluetoothHandlerThread.getLooper(), mContext);
    }
    }


    IBluetoothManager.Stub getBinder() {
    IBluetoothManager.Stub getBinder() {
+8 −46
Original line number Original line Diff line number Diff line
@@ -16,17 +16,15 @@


package com.android.server.bluetooth;
package com.android.server.bluetooth;


import android.annotation.NonNull;
import android.content.ContentResolver;
import android.content.ContentResolver;
import android.os.HandlerThread;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;


/**
/** Proxy class for method calls to help with unit testing */
 * Proxy class for method calls to help with unit testing
class BluetoothServerProxy {
 */
public class BluetoothServerProxy {
    private static final String TAG = BluetoothServerProxy.class.getSimpleName();
    private static final String TAG = BluetoothServerProxy.class.getSimpleName();
    private static final Object INSTANCE_LOCK = new Object();
    private static final Object INSTANCE_LOCK = new Object();
    private static BluetoothServerProxy sInstance;
    private static BluetoothServerProxy sInstance;
@@ -39,7 +37,7 @@ public class BluetoothServerProxy {
     *
     *
     * @return the singleton instance, guaranteed not null
     * @return the singleton instance, guaranteed not null
     */
     */
    public static BluetoothServerProxy getInstance() {
    static @NonNull BluetoothServerProxy getInstance() {
        synchronized (INSTANCE_LOCK) {
        synchronized (INSTANCE_LOCK) {
            if (sInstance == null) {
            if (sInstance == null) {
                sInstance = new BluetoothServerProxy();
                sInstance = new BluetoothServerProxy();
@@ -48,46 +46,16 @@ public class BluetoothServerProxy {
        return sInstance;
        return sInstance;
    }
    }


    /**
    /** Allow unit tests to substitute proxy with a test instance */
     * Allow unit tests to substitute BluetoothPbapMethodCallProxy with a test instance
     *
     * @param proxy a test instance of the BluetoothPbapMethodCallProxy
     */
    @VisibleForTesting
    @VisibleForTesting
    public static void setInstanceForTesting(BluetoothServerProxy proxy) {
    static void setInstanceForTesting(BluetoothServerProxy proxy) {
        synchronized (INSTANCE_LOCK) {
        synchronized (INSTANCE_LOCK) {
            Log.d(TAG, "setInstanceForTesting(), set to " + proxy);
            Log.d(TAG, "setInstanceForTesting(), set to " + proxy);
            sInstance = proxy;
            sInstance = proxy;
        }
        }
    }
    }


    /**
    String settingsSecureGetString(ContentResolver contentResolver, String name) {
     * Proxies {@link com.android.server.bluetooth.BluetoothManagerService.BluetoothHandler}.
     */
    public BluetoothManagerService.BluetoothHandler createBluetoothHandler(
            BluetoothManagerService.BluetoothHandler bluetoothHandler) {
        return bluetoothHandler;
    }

    /**
     * Proxies {@link com.android.server.bluetooth.BluetoothManagerService.BluetoothHandler}.
     */
    public BluetoothManagerService.BluetoothHandler newBluetoothHandler(
            BluetoothManagerService.BluetoothHandler bluetoothHandler) {
        return bluetoothHandler;
    }

    /**
     * Proxies {@link HandlerThread(String)}.
     */
    public HandlerThread createHandlerThread(String name) {
        return new HandlerThread(name);
    }

    /**
     * Proxies {@link android.provider.Settings.Secure.getString}.
     */
    public String settingsSecureGetString(ContentResolver contentResolver, String name) {
        return Settings.Secure.getString(contentResolver, name);
        return Settings.Secure.getString(contentResolver, name);
    }
    }


@@ -95,13 +63,7 @@ public class BluetoothServerProxy {
        return Settings.Global.getInt(resolver, Settings.Global.BLUETOOTH_ON, defaultValue);
        return Settings.Global.getInt(resolver, Settings.Global.BLUETOOTH_ON, defaultValue);
    }
    }


    /**
    boolean handlerSendWhatMessage(BluetoothManagerService.BluetoothHandler handler, int what) {
     * Proxies
     * {@link com.android.server.bluetooth.BluetoothManagerService.BluetoothHandler.sendMessage}.
     */
    public boolean handlerSendWhatMessage(
            com.android.server.bluetooth.BluetoothManagerService.BluetoothHandler handler,
            int what) {
        return handler.sendMessage(handler.obtainMessage(what));
        return handler.sendMessage(handler.obtainMessage(what));
    }
    }
}
}
+9 −1
Original line number Original line Diff line number Diff line
@@ -17,14 +17,22 @@ package com.android.server.bluetooth


import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.content.Context
import android.os.HandlerThread
import android.os.UserManager
import android.os.UserManager
import com.android.server.SystemService
import com.android.server.SystemService
import com.android.server.SystemService.TargetUser
import com.android.server.SystemService.TargetUser


class BluetoothService(context: Context) : SystemService(context) {
class BluetoothService(context: Context) : SystemService(context) {
    private val mBluetoothManagerService = BluetoothManagerService(context)
    private val mHandlerThread: HandlerThread
    private val mBluetoothManagerService: BluetoothManagerService
    private var mInitialized = false
    private var mInitialized = false


    init {
        mHandlerThread = HandlerThread("BluetoothManagerService")
        mHandlerThread.start()
        mBluetoothManagerService = BluetoothManagerService(context, mHandlerThread.getLooper())
    }

    private fun initialize() {
    private fun initialize() {
        if (!mInitialized) {
        if (!mInitialized) {
            mBluetoothManagerService.handleOnBootPhase()
            mBluetoothManagerService.handleOnBootPhase()
+22 −28
Original line number Original line Diff line number Diff line
@@ -29,9 +29,9 @@ import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.Intent;
import android.os.HandlerThread;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.provider.Settings;


import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -50,13 +50,22 @@ public class BluetoothManagerServiceTest {
    BluetoothManagerService mManagerService;
    BluetoothManagerService mManagerService;
    Context mContext;
    Context mContext;
    @Mock BluetoothServerProxy mBluetoothServerProxy;
    @Mock BluetoothServerProxy mBluetoothServerProxy;
    @Mock BluetoothManagerService.BluetoothHandler mHandler;
    @Mock UserManager mUserManager;
    @Mock UserManager mUserManager;
    HandlerThread mHandlerThread;

    TestLooper mLooper;


    @Before
    @Before
    public void setUp() throws Exception {
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);

        // Mock these functions so security errors won't throw
        doReturn("name")
                .when(mBluetoothServerProxy)
                .settingsSecureGetString(any(), eq(Settings.Secure.BLUETOOTH_NAME));
        doReturn("00:11:22:33:44:55")
                .when(mBluetoothServerProxy)
                .settingsSecureGetString(any(), eq(Settings.Secure.BLUETOOTH_ADDRESS));

        mContext =
        mContext =
                spy(
                spy(
                        new ContextWrapper(
                        new ContextWrapper(
@@ -64,34 +73,19 @@ public class BluetoothManagerServiceTest {


        doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
        doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);


        mHandlerThread = new HandlerThread("BluetoothManagerServiceTest");

        mManagerService = createBluetoothManagerService();
    }

    @After
    public void tearDown() {
        mHandlerThread.quitSafely();
    }

    private BluetoothManagerService createBluetoothManagerService() {
        doReturn(mock(Intent.class))
        doReturn(mock(Intent.class))
                .when(mContext)
                .when(mContext)
                .registerReceiverForAllUsers(any(), any(), eq(null), eq(null));
                .registerReceiverForAllUsers(any(), any(), eq(null), eq(null));

        BluetoothServerProxy.setInstanceForTesting(mBluetoothServerProxy);
        BluetoothServerProxy.setInstanceForTesting(mBluetoothServerProxy);
        // Mock the handler to avoid handle message & to terminate the thread after
        // test
        doReturn(mHandlerThread).when(mBluetoothServerProxy).createHandlerThread(any());
        doReturn(mHandler).when(mBluetoothServerProxy).newBluetoothHandler(any());


        // Mock these functions so security errors won't throw
        mLooper = new TestLooper();
        doReturn("name")

                .when(mBluetoothServerProxy)
        mManagerService = new BluetoothManagerService(mContext, mLooper.getLooper());
                .settingsSecureGetString(any(), eq(Settings.Secure.BLUETOOTH_NAME));
    }
        doReturn("00:11:22:33:44:55")

                .when(mBluetoothServerProxy)
    @After
                .settingsSecureGetString(any(), eq(Settings.Secure.BLUETOOTH_ADDRESS));
    public void tearDown() {
        return new BluetoothManagerService(mContext);
    }
    }


    @Test
    @Test
@@ -110,12 +104,12 @@ public class BluetoothManagerServiceTest {
        // test run on user -1, should not turning Bluetooth off
        // test run on user -1, should not turning Bluetooth off
        mManagerService.onUserRestrictionsChanged(UserHandle.CURRENT);
        mManagerService.onUserRestrictionsChanged(UserHandle.CURRENT);
        verify(mBluetoothServerProxy, timeout(sTimeout).times(0))
        verify(mBluetoothServerProxy, timeout(sTimeout).times(0))
                .handlerSendWhatMessage(mHandler, BluetoothManagerService.MESSAGE_DISABLE);
                .handlerSendWhatMessage(any(), eq(BluetoothManagerService.MESSAGE_DISABLE));


        // called from SYSTEM user, should try to toggle Bluetooth off
        // called from SYSTEM user, should try to toggle Bluetooth off
        mManagerService.onUserRestrictionsChanged(UserHandle.SYSTEM);
        mManagerService.onUserRestrictionsChanged(UserHandle.SYSTEM);
        verify(mBluetoothServerProxy, timeout(sTimeout))
        verify(mBluetoothServerProxy, timeout(sTimeout))
                .handlerSendWhatMessage(mHandler, BluetoothManagerService.MESSAGE_DISABLE);
                .handlerSendWhatMessage(any(), eq(BluetoothManagerService.MESSAGE_DISABLE));
    }
    }


    @Test
    @Test