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

Commit 038578d8 authored by William Escande's avatar William Escande Committed by Automerger Merge Worker
Browse files

Merge changes I0c0d277f,I36d5380b,Idb0728ed into main am: cac15675 am: d592e57b

parents f07250ab d592e57b
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ import android.util.Log;
import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.flags.Flags;

import com.google.common.annotations.VisibleForTesting;

@@ -234,7 +233,7 @@ class BluetoothOppNotification {
                        case NOTIFY:
                            synchronized (BluetoothOppNotification.this) {
                                if (mPendingUpdate > 0 && mUpdateNotificationThread == null) {
                                    Log.v(TAG, "new notify threadi!");
                                    Log.v(TAG, "new notify thread!");
                                    mUpdateNotificationThread = new NotificationUpdateThread();
                                    mUpdateNotificationThread.start();
                                    Log.v(TAG, "send delay message");
+12 −28
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ import android.database.Cursor;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
@@ -135,7 +134,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
    private BluetoothShareContentObserver mObserver;

    /** Class to handle Notification Manager updates */
    @VisibleForTesting BluetoothOppNotification mNotifier;
    @VisibleForTesting final BluetoothOppNotification mNotifier;

    private boolean mPendingUpdate;

@@ -236,28 +235,6 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
                    BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN,
                    0);
        }
    }

    public static boolean isEnabled() {
        return BluetoothProperties.isProfileOppEnabled().orElse(false);
    }

    @Override
    protected IProfileServiceBinder initBinder() {
        return new OppBinder();
    }

    private static class OppBinder extends Binder implements IProfileServiceBinder {

        OppBinder() {}

        @Override
        public void cleanup() {}
    }

    @Override
    public void start() {
        Log.v(TAG, "start()");

        setComponentAvailable(OPP_PROVIDER, true);
        setComponentAvailable(INCOMING_FILE_CONFIRM_ACTIVITY, true);
@@ -282,6 +259,15 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
        setBluetoothOppService(this);
    }

    public static boolean isEnabled() {
        return BluetoothProperties.isProfileOppEnabled().orElse(false);
    }

    @Override
    protected IProfileServiceBinder initBinder() {
        return null;
    }

    @Override
    public void stop() {
        if (sBluetoothOppService == null) {
@@ -457,7 +443,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
                                                BluetoothStatsLog
                                                        .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
                                                7);
                                        Log.e(TAG, "close tranport error");
                                        Log.e(TAG, "close transport error");
                                    }
                                } else {
                                    Log.i(TAG, "OPP busy! Retry after 1 second");
@@ -623,10 +609,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
            }
        }

        if (mNotifier != null) {
        mNotifier.cancelOppNotifications();
    }
    }

    /* suppose we auto accept an incoming OPUSH connection */
    private void createServerSession(ObexTransport transport) {
+4 −26
Original line number Diff line number Diff line
@@ -22,41 +22,19 @@ import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
import android.util.Log;

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

/** Provides Bluetooth Pan native interface for the Pan service */
public class PanNativeInterface {
    private static final String TAG = PanNativeInterface.class.getSimpleName();
    private PanService mPanService;

    @GuardedBy("INSTANCE_LOCK")
    private static PanNativeInterface sInstance;
    private final PanService mPanService;

    private static final Object INSTANCE_LOCK = new Object();

    private PanNativeInterface() {}

    /** Get singleton instance. */
    public static PanNativeInterface getInstance() {
        synchronized (INSTANCE_LOCK) {
            if (sInstance == null) {
                sInstance = new PanNativeInterface();
            }
            return sInstance;
        }
    }

    /** Set singleton instance. */
    @VisibleForTesting
    public static void setInstance(PanNativeInterface instance) {
        synchronized (INSTANCE_LOCK) {
            sInstance = instance;
        }
    PanNativeInterface(PanService panService) {
        mPanService = panService;
    }

    void init(PanService panService) {
        mPanService = panService;
    void init() {
        initializeNative();
    }

+79 −97
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@ package com.android.bluetooth.pan;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
import static android.Manifest.permission.TETHER_PRIVILEGED;
import static android.bluetooth.BluetoothUtils.logRemoteException;

import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNullElseGet;

import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothDevice;
@@ -29,7 +33,6 @@ import android.bluetooth.BluetoothProfile;
import android.bluetooth.IBluetoothPan;
import android.bluetooth.IBluetoothPanCallback;
import android.content.AttributionSource;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources.NotFoundException;
import android.net.TetheringInterface;
@@ -57,53 +60,49 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/** Provides Bluetooth Pan Device profile, as a service in the Bluetooth application. */
public class PanService extends ProfileService {
    private static final String TAG = PanService.class.getSimpleName();

    private static PanService sPanService;

    private static final int BLUETOOTH_MAX_PAN_CONNECTIONS = 5;

    @VisibleForTesting ConcurrentHashMap<BluetoothDevice, BluetoothPanDevice> mPanDevices;

    private int mMaxPanDevices;
    private String mPanIfName;
    @VisibleForTesting boolean mIsTethering = false;
    private HashMap<String, IBluetoothPanCallback> mBluetoothTetheringCallbacks;

    private TetheringManager mTetheringManager;
    private DatabaseManager mDatabaseManager;
    @VisibleForTesting UserManager mUserManager;

    private static final int MESSAGE_CONNECT = 1;
    private static final int MESSAGE_DISCONNECT = 2;
    private static final int MESSAGE_CONNECT_STATE_CHANGED = 11;
    private boolean mTetherOn = false;

    private BluetoothTetheringNetworkFactory mNetworkFactory;
    private boolean mStarted = false;
    @VisibleForTesting
    final ConcurrentHashMap<BluetoothDevice, BluetoothPanDevice> mPanDevices =
            new ConcurrentHashMap<>();

    private AdapterService mAdapterService;
    private final Map<String, IBluetoothPanCallback> mBluetoothTetheringCallbacks = new HashMap<>();
    private final AdapterService mAdapterService;
    private final PanNativeInterface mNativeInterface;
    private final DatabaseManager mDatabaseManager;
    private final TetheringManager mTetheringManager;
    private final UserManager mUserManager;
    private final int mMaxPanDevices;

    @VisibleForTesting PanNativeInterface mNativeInterface;
    private String mPanIfName;
    @VisibleForTesting boolean mIsTethering = false;
    private boolean mTetherOn = false;
    private BluetoothTetheringNetworkFactory mNetworkFactory;

    TetheringManager.TetheringEventCallback mTetheringCallback =
    final TetheringManager.TetheringEventCallback mTetheringCallback =
            new TetheringManager.TetheringEventCallback() {
                @Override
                public void onError(TetheringInterface iface, int error) {
                    if (mIsTethering && iface.getType() == TetheringManager.TETHERING_BLUETOOTH) {
                        // tethering is fail because of @TetheringIfaceError error.
                        // Tethering fail because of @TetheringIfaceError error.
                        Log.e(TAG, "Error setting up tether interface: " + error);
                        for (Map.Entry device : mPanDevices.entrySet()) {
                        for (BluetoothDevice device : mPanDevices.keySet()) {
                            mNativeInterface.disconnect(
                                    Flags.panUseIdentityAddress()
                                            ? Utils.getByteBrEdrAddress(
                                                    (BluetoothDevice) device.getKey())
                                            : Utils.getByteAddress(
                                                    (BluetoothDevice) device.getKey()));
                                            ? Utils.getByteBrEdrAddress(mAdapterService, device)
                                            : Utils.getByteAddress(device));
                        }
                        mPanDevices.clear();
                        mIsTethering = false;
@@ -111,8 +110,35 @@ public class PanService extends ProfileService {
                }
            };

    public PanService(Context ctx) {
        super(ctx);
    public PanService(AdapterService adapterService) {
        this(adapterService, null);
    }

    @VisibleForTesting
    PanService(AdapterService adapterService, PanNativeInterface nativeInterface) {
        super(requireNonNull(adapterService));
        mAdapterService = adapterService;
        mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
        mNativeInterface =
                requireNonNullElseGet(nativeInterface, () -> new PanNativeInterface(this));
        mUserManager = requireNonNull(getSystemService(UserManager.class));
        mTetheringManager = requireNonNull(getSystemService(TetheringManager.class));

        int maxPanDevice;
        try {
            maxPanDevice =
                    getResources()
                            .getInteger(com.android.bluetooth.R.integer.config_max_pan_devices);
        } catch (NotFoundException e) {
            maxPanDevice = BLUETOOTH_MAX_PAN_CONNECTIONS;
        }
        mMaxPanDevices = maxPanDevice;

        mNativeInterface.init();

        mTetheringManager.registerTetheringEventCallback(
                new HandlerExecutor(new Handler(Looper.getMainLooper())), mTetheringCallback);
        setPanService(this);
    }

    public static boolean isEnabled() {
@@ -142,51 +168,9 @@ public class PanService extends ProfileService {
        sPanService = instance;
    }

    @Override
    public void start() {
        mAdapterService =
                Objects.requireNonNull(
                        AdapterService.getAdapterService(),
                        "AdapterService cannot be null when PanService starts");
        mDatabaseManager =
                Objects.requireNonNull(
                        AdapterService.getAdapterService().getDatabase(),
                        "DatabaseManager cannot be null when PanService starts");
        mNativeInterface =
                Objects.requireNonNull(
                        PanNativeInterface.getInstance(),
                        "PanNativeInterface cannot be null when PanService starts");

        mBluetoothTetheringCallbacks = new HashMap<>();
        mPanDevices = new ConcurrentHashMap<BluetoothDevice, BluetoothPanDevice>();
        try {
            mMaxPanDevices =
                    getResources()
                            .getInteger(com.android.bluetooth.R.integer.config_max_pan_devices);
        } catch (NotFoundException e) {
            mMaxPanDevices = BLUETOOTH_MAX_PAN_CONNECTIONS;
        }
        mNativeInterface.init(this);

        mUserManager = getSystemService(UserManager.class);

        mTetheringManager = getSystemService(TetheringManager.class);
        mTetheringManager.registerTetheringEventCallback(
                new HandlerExecutor(new Handler(Looper.getMainLooper())), mTetheringCallback);
        setPanService(this);
        mStarted = true;
    }

    @Override
    public void stop() {
        if (!mStarted) {
            Log.w(TAG, "stop() called before start()");
            return;
        }
        if (mTetheringManager != null) {
        mTetheringManager.unregisterTetheringEventCallback(mTetheringCallback);
            mTetheringManager = null;
        }
        mNativeInterface.cleanup();
        mHandler.removeCallbacksAndMessages(null);
    }
@@ -196,9 +180,6 @@ public class PanService extends ProfileService {
        // TODO(b/72948646): this should be moved to stop()
        setPanService(null);

        mUserManager = null;

        if (mPanDevices != null) {
        int[] desiredStates = {
            BluetoothProfile.STATE_CONNECTING,
            BluetoothProfile.STATE_CONNECTED,
@@ -219,7 +200,6 @@ public class PanService extends ProfileService {
        }
        mPanDevices.clear();
    }
    }

    private final Handler mHandler =
            new Handler(Looper.getMainLooper()) {
@@ -230,7 +210,8 @@ public class PanService extends ProfileService {
                            BluetoothDevice connectDevice = (BluetoothDevice) msg.obj;
                            if (!mNativeInterface.connect(
                                    Flags.identityAddressNullIfNotKnown()
                                            ? Utils.getByteBrEdrAddress(connectDevice)
                                            ? Utils.getByteBrEdrAddress(
                                                    mAdapterService, connectDevice)
                                            : mAdapterService.getByteIdentityAddress(
                                                    connectDevice))) {
                                handlePanDeviceStateChange(
@@ -251,7 +232,8 @@ public class PanService extends ProfileService {
                            BluetoothDevice disconnectDevice = (BluetoothDevice) msg.obj;
                            if (!mNativeInterface.disconnect(
                                    Flags.identityAddressNullIfNotKnown()
                                            ? Utils.getByteBrEdrAddress(disconnectDevice)
                                            ? Utils.getByteBrEdrAddress(
                                                    mAdapterService, disconnectDevice)
                                            : mAdapterService.getByteIdentityAddress(
                                                    disconnectDevice))) {
                                handlePanDeviceStateChange(
@@ -663,7 +645,7 @@ public class PanService extends ProfileService {
                    mPanDevices.remove(device);
                    mNativeInterface.disconnect(
                            Flags.panUseIdentityAddress()
                                    ? Utils.getByteBrEdrAddress(device)
                                    ? Utils.getByteBrEdrAddress(mAdapterService, device)
                                    : Utils.getByteAddress(device));
                    return;
                }
@@ -675,7 +657,7 @@ public class PanService extends ProfileService {
                            cb.onAvailable(iface);
                        }
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                        logRemoteException(TAG, e);
                    }
                }
            } else if (state == BluetoothProfile.STATE_DISCONNECTED) {
@@ -690,12 +672,12 @@ public class PanService extends ProfileService {
                            cb.onUnavailable();
                        }
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                        logRemoteException(TAG, e);
                    }
                    mIsTethering = false;
                }
            }
        } else if (mStarted) {
        } else {
            // PANU Role = reverse Tether
            Log.d(
                    TAG,
+24 −49
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.bluetooth.sap;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;

import static java.util.Objects.requireNonNull;

import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
@@ -60,15 +62,10 @@ import java.util.Collections;
import java.util.List;

public class SapService extends ProfileService implements AdapterService.BluetoothStateCallback {
    private static final String TAG = "SapService";

    private static final String SDP_SAP_SERVICE_NAME = "SIM Access";
    private static final int SDP_SAP_VERSION = 0x0102;
    private static final String TAG = "SapService";

    /**
     * To log debug/verbose in SAP, use the command "setprop log.tag.SapService DEBUG" or "setprop
     * log.tag.SapService VERBOSE" and then "adb root" + "adb shell "stop; start""
     */

    /* Message ID's */
    private static final int START_LISTENER = 1;
@@ -100,8 +97,9 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
            "com.android.bluetooth.sap.USER_CONFIRM_TIMEOUT";
    private static final int USER_CONFIRM_TIMEOUT_VALUE = 25000;

    private final AdapterService mAdapterService;

    private PowerManager.WakeLock mWakeLock = null;
    private AdapterService mAdapterService;
    private SocketAcceptThread mAcceptThread = null;
    private BluetoothServerSocket mServerSocket = null;
    private int mSdpHandle = -1;
@@ -113,9 +111,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
    private SapServer mSapServer = null;
    private AlarmManager mAlarmManager = null;
    private boolean mRemoveTimeoutMsg = false;

    private boolean mIsWaitingAuthorization = false;
    private boolean mIsRegistered = false;

    private static SapService sSapService;

@@ -123,9 +119,22 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
        BluetoothUuid.SAP,
    };

    public SapService(Context ctx) {
        super(ctx);
    public SapService(AdapterService adapterService) {
        super(requireNonNull(adapterService));
        mAdapterService = adapterService;
        BluetoothSap.invalidateBluetoothGetConnectionStateCache();

        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
        filter.addAction(USER_CONFIRM_TIMEOUT_ACTION);

        registerReceiver(mSapReceiver, filter);

        mAdapterService.registerBluetoothStateCallback(getMainExecutor(), this);
        // start RFCOMM listener
        mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER));
        setSapService(this);
    }

    public static boolean isEnabled() {
@@ -148,7 +157,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo

    private void removeSdpRecord() {
        SdpManagerNativeInterface nativeInterface = SdpManagerNativeInterface.getInstance();
        if (mAdapterService != null && mSdpHandle >= 0 && nativeInterface.isAvailable()) {
        if (mSdpHandle >= 0 && nativeInterface.isAvailable()) {
            Log.v(TAG, "Removing SDP record handle: " + mSdpHandle);
            nativeInterface.removeSdpRecord(mSdpHandle);
            mSdpHandle = -1;
@@ -203,9 +212,6 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo

            if (!initSocketOK) {
                // Need to break out of this loop if BT is being turned off.
                if (mAdapterService == null) {
                    break;
                }
                int state = mAdapterService.getState();
                if ((state != BluetoothAdapter.STATE_TURNING_ON)
                        && (state != BluetoothAdapter.STATE_ON)) {
@@ -636,7 +642,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
        Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
        enforceCallingOrSelfPermission(
                BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
        AdapterService.getAdapterService()
        mAdapterService
                .getDatabase()
                .setProfileConnectionPolicy(device, BluetoothProfile.SAP, connectionPolicy);
        if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
@@ -659,7 +665,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
    public int getConnectionPolicy(BluetoothDevice device) {
        enforceCallingOrSelfPermission(
                BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
        return AdapterService.getAdapterService()
        return mAdapterService
                .getDatabase()
                .getProfileConnectionPolicy(device, BluetoothProfile.SAP);
    }
@@ -669,42 +675,11 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
        return new SapBinder(this);
    }

    @Override
    public void start() {
        Log.v(TAG, "start()");
        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
        filter.addAction(USER_CONFIRM_TIMEOUT_ACTION);

        try {
            registerReceiver(mSapReceiver, filter);
            mIsRegistered = true;
        } catch (Exception e) {
            Log.w(TAG, "Unable to register sap receiver", e);
        }
        mInterrupted = false;
        mAdapterService = AdapterService.getAdapterService();
        mAdapterService.registerBluetoothStateCallback(getMainExecutor(), this);
        // start RFCOMM listener
        mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER));
        setSapService(this);
    }

    @Override
    public void stop() {
        Log.v(TAG, "stop()");
        if (!mIsRegistered) {
            Log.i(TAG, "Avoid unregister when receiver it is not registered");
            return;
        }
        setSapService(null);
        try {
            mIsRegistered = false;
        unregisterReceiver(mSapReceiver);
        } catch (Exception e) {
            Log.w(TAG, "Unable to unregister sap receiver", e);
        }
        mAdapterService.unregisterBluetoothStateCallback(this);
        setState(BluetoothSap.STATE_DISCONNECTED, BluetoothSap.RESULT_CANCELED);
        sendShutdownMessage();
Loading