From 4d74f94897e3e179d9bf6a91cd5eace8eb1f6cd0 Mon Sep 17 00:00:00 2001 From: Jack He Date: Tue, 16 Mar 2021 16:05:42 -0700 Subject: [PATCH] Bluetooth: Wait for provisioning after init flag change * Wait for device provisioning to be completed before restart stack after an init flag change Bug: 181226310 Test: make, setup wizard Change-Id: I1128d9ef25b7703da31cfe55a812aaa745ab5f41 --- .../server/BluetoothDeviceConfigListener.java | 16 ++++++- .../server/BluetoothManagerService.java | 46 ++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/BluetoothDeviceConfigListener.java b/services/core/java/com/android/server/BluetoothDeviceConfigListener.java index 2dcf82ff94103..611a37de70f43 100644 --- a/services/core/java/com/android/server/BluetoothDeviceConfigListener.java +++ b/services/core/java/com/android/server/BluetoothDeviceConfigListener.java @@ -17,6 +17,9 @@ package com.android.server; import android.provider.DeviceConfig; +import android.util.Slog; + +import java.util.ArrayList; /** * The BluetoothDeviceConfigListener handles system device config change callback and checks @@ -30,10 +33,12 @@ import android.provider.DeviceConfig; class BluetoothDeviceConfigListener { private static final String TAG = "BluetoothDeviceConfigListener"; - BluetoothManagerService mService; + private final BluetoothManagerService mService; + private final boolean mLogDebug; - BluetoothDeviceConfigListener(BluetoothManagerService service) { + BluetoothDeviceConfigListener(BluetoothManagerService service, boolean logDebug) { mService = service; + mLogDebug = logDebug; DeviceConfig.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_BLUETOOTH, (Runnable r) -> r.run(), @@ -47,6 +52,13 @@ class BluetoothDeviceConfigListener { if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_BLUETOOTH)) { return; } + if (mLogDebug) { + ArrayList flags = new ArrayList<>(); + for (String name : properties.getKeyset()) { + flags.add(name + "='" + properties.getString(name, "") + "'"); + } + Slog.d(TAG, "onPropertiesChanged: " + String.join(",", flags)); + } boolean foundInit = false; for (String name : properties.getKeyset()) { if (name.startsWith("INIT_")) { diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index aab05532e2b7f..992ef2657a655 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -453,6 +453,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mHandler.hasMessages(MESSAGE_INIT_FLAGS_CHANGED) && state == BluetoothProfile.STATE_DISCONNECTED && !mBluetoothModeChangeHelper.isA2dpOrHearingAidConnected()) { + Slog.i(TAG, "Device disconnected, reactivating pending flag changes"); onInitFlagsChanged(); } } @@ -810,6 +811,35 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return enabledProfiles; } + private boolean isDeviceProvisioned() { + return Settings.Global.getInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, + 0) != 0; + } + + // Monitor change of BLE scan only mode settings. + private void registerForProvisioningStateChange() { + ContentObserver contentObserver = new ContentObserver(null) { + @Override + public void onChange(boolean selfChange) { + if (!isDeviceProvisioned()) { + if (DBG) { + Slog.d(TAG, "DEVICE_PROVISIONED setting changed, but device is not " + + "provisioned"); + } + return; + } + if (mHandler.hasMessages(MESSAGE_INIT_FLAGS_CHANGED)) { + Slog.i(TAG, "Device provisioned, reactivating pending flag changes"); + onInitFlagsChanged(); + } + } + }; + + mContentResolver.registerContentObserver( + Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), false, + contentObserver); + } + // Monitor change of BLE scan only mode settings. private void registerForBleScanModeChange() { ContentObserver contentObserver = new ContentObserver(null) { @@ -1375,7 +1405,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mBluetoothAirplaneModeListener != null) { mBluetoothAirplaneModeListener.start(mBluetoothModeChangeHelper); } - mBluetoothDeviceConfigListener = new BluetoothDeviceConfigListener(this); + registerForProvisioningStateChange(); + mBluetoothDeviceConfigListener = new BluetoothDeviceConfigListener(this, DBG); } /** @@ -2219,12 +2250,25 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED); if (mBluetoothModeChangeHelper.isA2dpOrHearingAidConnected()) { + Slog.i(TAG, "Delaying MESSAGE_INIT_FLAGS_CHANGED by " + + DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS + + " ms due to existing connections"); + mHandler.sendEmptyMessageDelayed( + MESSAGE_INIT_FLAGS_CHANGED, + DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS); + break; + } + if (!isDeviceProvisioned()) { + Slog.i(TAG, "Delaying MESSAGE_INIT_FLAGS_CHANGED by " + + DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS + + "ms because device is not provisioned"); mHandler.sendEmptyMessageDelayed( MESSAGE_INIT_FLAGS_CHANGED, DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS); break; } if (mBluetooth != null && isEnabled()) { + Slog.i(TAG, "Restarting Bluetooth due to init flag change"); restartForReason( BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED); }