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

Commit a1c2aa63 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8656595 from 12d65cd0 to tm-qpr1-release

Change-Id: I43c95c6217ef081bc15e71643de434d75fbac486
parents 968863e4 12d65cd0
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -519,12 +519,9 @@
                <action android:name="android.bluetooth.IBluetoothPbapClient"/>
            </intent-filter>
        </service>
        <!--  Note: This service doesn't get started, it just indicates to the Authentication
              framework that we can create accounts of a specific type. As such, its safe to
              have as enabled on all targets and not just the ones that use PBAP Client  -->
        <service android:process="@string/process"
             android:name="com.android.bluetooth.pbapclient.AuthenticationService"
             android:enabled="true"
             android:enabled="false"
             android:exported="true">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
+86 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.provider.CallLog;
import android.sysprop.BluetoothProperties;
import android.util.Log;
@@ -60,6 +61,12 @@ public class PbapClientService extends ProfileService {
    private static final String TAG = "PbapClientService";
    private static final String SERVICE_NAME = "Phonebook Access PCE";

    /**
     * The component names for the owned authenticator service
     */
    private static final String AUTHENTICATOR_SERVICE =
            AuthenticationService.class.getCanonicalName();

    // MAXIMUM_DEVICES set to 10 to prevent an excessive number of simultaneous devices.
    private static final int MAXIMUM_DEVICES = 10;
    private Map<BluetoothDevice, PbapClientStateMachine> mPbapClientStateMachineMap =
@@ -70,6 +77,40 @@ public class PbapClientService extends ProfileService {

    private DatabaseManager mDatabaseManager;

    /**
     * There's an ~1-2 second latency between when our Authentication service is set as available to
     * the system and when the Authentication/Account framework code will recognize it and allow us
     * to alter accounts. In lieu of the Accounts team dealing with this race condition, we're going
     * to periodically poll over 3 seconds until our accounts are visible, remove old accounts, and
     * then notify device state machines that they can create accounts and download contacts.
     */
    // TODO(233361365): Remove this pattern when the framework solves their race condition
    private static final int ACCOUNT_VISIBILITY_CHECK_MS = 500;
    private static final int ACCOUNT_VISIBILITY_CHECK_TRIES_MAX = 6;
    private int mAccountVisibilityCheckTries = 0;
    private final Handler mAuthServiceHandler = new Handler();
    private final Runnable mCheckAuthService = new Runnable() {
        @Override
        public void run() {
            // If our accounts are finally visible to use, clean up old ones and tell devices they
            // can issue downloads if they're ready. Otherwise, wait and try again.
            if (isAuthenticationServiceReady()) {
                Log.i(TAG, "Service ready! Clean up old accounts and try contacts downloads");
                removeUncleanAccounts();
                for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) {
                    stateMachine.tryDownloadIfConnected();
                }
            } else if (mAccountVisibilityCheckTries < ACCOUNT_VISIBILITY_CHECK_TRIES_MAX) {
                mAccountVisibilityCheckTries += 1;
                Log.w(TAG, "AccountManager hasn't registered our service yet. Retry "
                        + mAccountVisibilityCheckTries + "/" + ACCOUNT_VISIBILITY_CHECK_TRIES_MAX);
                mAuthServiceHandler.postDelayed(this, ACCOUNT_VISIBILITY_CHECK_MS);
            } else {
                Log.e(TAG, "Failed to register Authenication Service and get account visibility");
            }
        }
    };

    public static boolean isEnabled() {
        return BluetoothProperties.isProfilePbapClientEnabled().orElse(false);
    }
@@ -88,6 +129,8 @@ public class PbapClientService extends ProfileService {
        mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(),
                "DatabaseManager cannot be null when PbapClientService starts");

        setComponentAvailable(AUTHENTICATOR_SERVICE, true);

        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        // delay initial download until after the user is unlocked to add an account.
@@ -101,7 +144,7 @@ public class PbapClientService extends ProfileService {
            Log.w(TAG, "Unable to register pbapclient receiver", e);
        }

        removeUncleanAccounts();
        initializeAuthenticationService();
        registerSdpRecord();
        setPbapClientService(this);
        return true;
@@ -119,7 +162,8 @@ public class PbapClientService extends ProfileService {
        for (PbapClientStateMachine pbapClientStateMachine : mPbapClientStateMachineMap.values()) {
            pbapClientStateMachine.doQuit();
        }
        removeUncleanAccounts();
        cleanupAuthenicationService();
        setComponentAvailable(AUTHENTICATOR_SERVICE, false);
        return true;
    }

@@ -133,7 +177,45 @@ public class PbapClientService extends ProfileService {
        }
    }

    /**
     * Periodically check if the account framework has recognized our service and will allow us to
     * interact with our accounts. Notify state machines once our service is ready so we can trigger
     * account downloads.
     */
    private void initializeAuthenticationService() {
        mAuthServiceHandler.postDelayed(mCheckAuthService, ACCOUNT_VISIBILITY_CHECK_MS);
    }

    private void cleanupAuthenicationService() {
        mAuthServiceHandler.removeCallbacks(mCheckAuthService);
        removeUncleanAccounts();
    }

    /**
     * Determine if our account type is visible to us yet. If it is, then our service is ready and
     * our account type is ready to use.
     *
     * Make a placeholder device account and determine our visibility relative to it. Note that this
     * function uses the same restrictions are the other add and remove functions, but is *also*
     * available to all system apps instead of throwing a runtime SecurityException.
     */
    protected boolean isAuthenticationServiceReady() {
        Account account = new Account("00:00:00:00:00:00", getString(R.string.pbap_account_type));
        AccountManager accountManager = AccountManager.get(this);
        int visibility = accountManager.getAccountVisibility(account, getPackageName());
        if (DBG) {
            Log.d(TAG, "Checking visibility, visibility=" + visibility);
        }
        return visibility == AccountManager.VISIBILITY_VISIBLE
                || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;
    }

    private void removeUncleanAccounts() {
        if (!isAuthenticationServiceReady()) {
            Log.w(TAG, "Can't remove accounts. AccountManager hasn't registered our service yet.");
            return;
        }

        // Find all accounts that match the type "pbap" and delete them.
        AccountManager accountManager = AccountManager.get(this);
        Account[] accounts =
@@ -208,7 +290,7 @@ public class PbapClientService extends ProfileService {
                }
            } else if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
                for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) {
                    stateMachine.resumeDownload();
                    stateMachine.tryDownloadIfConnected();
                }
            } else if (action.equals(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED)) {
                // PbapClientConnectionHandler has code to remove calllogs when PBAP disconnects.
@@ -542,6 +624,7 @@ public class PbapClientService extends ProfileService {
    @Override
    public void dump(StringBuilder sb) {
        super.dump(sb);
        ProfileService.println(sb, "isAuthServiceReady: " + isAuthenticationServiceReady());
        for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) {
            stateMachine.dump(sb);
        }
+18 −7
Original line number Diff line number Diff line
@@ -301,10 +301,7 @@ final class PbapClientStateMachine extends StateMachine {
            onConnectionStateChanged(mCurrentDevice, mMostRecentState,
                    BluetoothProfile.STATE_CONNECTED);
            mMostRecentState = BluetoothProfile.STATE_CONNECTED;
            if (mUserManager.isUserUnlocked()) {
                mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD)
                        .sendToTarget();
            }
            downloadIfReady();
        }

        @Override
@@ -321,8 +318,7 @@ final class PbapClientStateMachine extends StateMachine {
                    break;

                case MSG_RESUME_DOWNLOAD:
                    mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD)
                            .sendToTarget();
                    downloadIfReady();
                    break;

                default:
@@ -333,6 +329,21 @@ final class PbapClientStateMachine extends StateMachine {
        }
    }

    /**
     * Trigger a contacts download if the user is unlocked and our accounts are available to us
     */
    private void downloadIfReady() {
        boolean userReady = mUserManager.isUserUnlocked();
        boolean accountServiceReady = mService.isAuthenticationServiceReady();
        if (!userReady || !accountServiceReady) {
            Log.w(TAG, "Cannot download contacts yet, userReady=" + userReady
                    + ", accountServiceReady=" + accountServiceReady);
            return;
        }
        mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD)
                .sendToTarget();
    }

    private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
        if (device == null) {
            Log.w(TAG, "onConnectionStateChanged with invalid device");
@@ -357,7 +368,7 @@ final class PbapClientStateMachine extends StateMachine {
        sendMessage(MSG_DISCONNECT, device);
    }

    public void resumeDownload() {
    public void tryDownloadIfConnected() {
        sendMessage(MSG_RESUME_DOWNLOAD);
    }

+1 −1
Original line number Diff line number Diff line
{
  "name": "com.android.bluetooth",
  "version": 330090000,
  "version": 339990000,
  "requireNativeLibs": [
    "libaptX_encoder.so",
    "libaptXHD_encoder.so"
+11 −11
Original line number Diff line number Diff line
@@ -359,8 +359,6 @@ class HearingAidImpl : public HearingAid {
  void OnGattConnected(tGATT_STATUS status, uint16_t conn_id,
                       tGATT_IF client_if, RawAddress address,
                       tBT_TRANSPORT transport, uint16_t mtu) {
    VLOG(2) << __func__ << ": address=" << address << ", conn_id=" << conn_id;

    HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
    if (!hearingDevice) {
      /* When Hearing Aid is quickly disabled and enabled in settings, this case
@@ -371,6 +369,8 @@ class HearingAidImpl : public HearingAid {
      return;
    }

    LOG(INFO) << __func__ << ": address=" << address << ", conn_id=" << conn_id;

    if (status != GATT_SUCCESS) {
      if (!hearingDevice->connecting_actively) {
        // acceptlist connection failed, that's ok.
@@ -402,6 +402,15 @@ class HearingAidImpl : public HearingAid {
      hearingDevice->connection_update_status = AWAITING;
    }

    if (controller_get_interface()->supports_ble_2m_phy()) {
      LOG(INFO) << address << " set preferred 2M PHY";
      BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
    }

    // Set data length
    // TODO(jpawlowski: for 16khz only 87 is required, optimize
    BTM_SetBleDataLength(address, 167);

    if (BTM_SecIsSecurityPending(address)) {
      /* if security collision happened, wait for encryption done
       * (BTA_GATTC_ENC_CMPL_CB_EVT) */
@@ -890,15 +899,6 @@ class HearingAidImpl : public HearingAid {
  void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) {
    tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512};

    if (controller_get_interface()->supports_ble_2m_phy()) {
      LOG(INFO) << hearingDevice->address << " set preferred PHY to 2M";
      BTM_BleSetPhy(hearingDevice->address, PHY_LE_2M, PHY_LE_2M, 0);
    }

    // Set data length
    // TODO(jpawlowski: for 16khz only 87 is required, optimize
    BTM_SetBleDataLength(hearingDevice->address, 167);

    SendEnableServiceChangedInd(hearingDevice);

    uint8_t service_id = hearingDevice->isLeft()
Loading