Merge "Improve BT slice card loading performance" into rvc-dev
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
index c0527c9..ebfaca9 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
@@ -37,6 +37,7 @@
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.homepage.contextualcards.slices.BluetoothUpdateWorker;
import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.slice.ContextualWifiScanWorker;
@@ -67,6 +68,7 @@
final Context context = getContext();
if (savedInstanceState == null) {
FeatureFactory.getFactory(context).getSlicesFeatureProvider().newUiSession();
+ BluetoothUpdateWorker.initLocalBtManager(getContext());
}
mContextualCardManager = new ContextualCardManager(context, getSettingsLifecycle(),
savedInstanceState);
diff --git a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java
index 8b74313..19de403 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java
@@ -81,15 +81,12 @@
private static boolean sBluetoothEnabling;
private final Context mContext;
- private final AvailableMediaBluetoothDeviceUpdater mAvailableMediaBtDeviceUpdater;
- private final SavedBluetoothDeviceUpdater mSavedBtDeviceUpdater;
+ private AvailableMediaBluetoothDeviceUpdater mAvailableMediaBtDeviceUpdater;
+ private SavedBluetoothDeviceUpdater mSavedBtDeviceUpdater;
public BluetoothDevicesSlice(Context context) {
mContext = context;
- mAvailableMediaBtDeviceUpdater = new AvailableMediaBluetoothDeviceUpdater(mContext,
- null /* fragment */, null /* devicePreferenceCallback */);
- mSavedBtDeviceUpdater = new SavedBluetoothDeviceUpdater(mContext,
- null /* fragment */, null /* devicePreferenceCallback */);
+ BluetoothUpdateWorker.initLocalBtManager(context);
}
@Override
@@ -119,16 +116,8 @@
// Add the header of Bluetooth on
listBuilder.addRow(getBluetoothOnHeader());
- // Get row builders of Bluetooth devices.
- final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilders();
-
- // Determine the displayable row count.
- final int displayableCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT);
-
- // Add device rows up to the count.
- for (int i = 0; i < displayableCount; i++) {
- listBuilder.addRow(rows.get(i));
- }
+ // Add row builders of Bluetooth devices.
+ getBluetoothRowBuilders().forEach(row -> listBuilder.addRow(row));
return listBuilder.build();
}
@@ -181,19 +170,18 @@
List<CachedBluetoothDevice> getPairedBluetoothDevices() {
final List<CachedBluetoothDevice> bluetoothDeviceList = new ArrayList<>();
- // If Bluetooth is disable, skip to get the Bluetooth devices.
+ // If Bluetooth is disable, skip getting the Bluetooth devices.
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is disabled.");
return bluetoothDeviceList;
}
- // Get the Bluetooth devices from LocalBluetoothManager.
- final LocalBluetoothManager localBtManager =
- com.android.settings.bluetooth.Utils.getLocalBtManager(mContext);
+ final LocalBluetoothManager localBtManager = BluetoothUpdateWorker.getLocalBtManager();
if (localBtManager == null) {
- Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is unsupported.");
+ Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is not ready.");
return bluetoothDeviceList;
}
+
final Collection<CachedBluetoothDevice> cachedDevices =
localBtManager.getCachedDeviceManager().getCachedDevicesCopy();
@@ -292,8 +280,21 @@
private List<ListBuilder.RowBuilder> getBluetoothRowBuilders() {
final List<ListBuilder.RowBuilder> bluetoothRows = new ArrayList<>();
+ final List<CachedBluetoothDevice> pairedDevices = getPairedBluetoothDevices();
+ if (pairedDevices.isEmpty()) {
+ return bluetoothRows;
+ }
+
+ // Initialize updaters without being blocked after paired devices is available because
+ // LocalBluetoothManager is ready.
+ lazyInitUpdaters();
+
// Create row builders based on paired devices.
- for (CachedBluetoothDevice device : getPairedBluetoothDevices()) {
+ for (CachedBluetoothDevice device : pairedDevices) {
+ if (bluetoothRows.size() >= DEFAULT_EXPANDED_ROW_COUNT) {
+ break;
+ }
+
String summary = device.getConnectionSummary();
if (summary == null) {
summary = mContext.getString(
@@ -321,6 +322,18 @@
return bluetoothRows;
}
+ private void lazyInitUpdaters() {
+ if (mAvailableMediaBtDeviceUpdater == null) {
+ mAvailableMediaBtDeviceUpdater = new AvailableMediaBluetoothDeviceUpdater(mContext,
+ null /* fragment */, null /* devicePreferenceCallback */);
+ }
+
+ if (mSavedBtDeviceUpdater == null) {
+ mSavedBtDeviceUpdater = new SavedBluetoothDeviceUpdater(mContext,
+ null /* fragment */, null /* devicePreferenceCallback */);
+ }
+ }
+
@VisibleForTesting
SliceAction buildPrimaryBluetoothAction(CachedBluetoothDevice bluetoothDevice) {
final Intent intent = new Intent(getUri().toString())
diff --git a/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorker.java b/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorker.java
index 1602f56..8f15f2c 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorker.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorker.java
@@ -18,9 +18,14 @@
import android.content.Context;
import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
import android.util.Log;
-import com.android.settings.bluetooth.Utils;
+import androidx.annotation.Nullable;
+
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -30,29 +35,46 @@
private static final String TAG = "BluetoothUpdateWorker";
- private final LocalBluetoothManager mLocalBluetoothManager;
+ private static LocalBluetoothManager sLocalBluetoothManager;
+
+ private LoadBtManagerHandler mLoadBtManagerHandler;
public BluetoothUpdateWorker(Context context, Uri uri) {
super(context, uri);
- mLocalBluetoothManager = Utils.getLocalBtManager(context);
+ mLoadBtManagerHandler = LoadBtManagerHandler.getInstance(context);
+ if (sLocalBluetoothManager == null) {
+ mLoadBtManagerHandler.startLoadingBtManager(this);
+ }
+ }
+
+ /** Initialize {@link LocalBluetoothManager} in the background */
+ public static void initLocalBtManager(Context context) {
+ if (sLocalBluetoothManager == null) {
+ LoadBtManagerHandler.getInstance(context).startLoadingBtManager();
+ }
+ }
+
+ @Nullable
+ static LocalBluetoothManager getLocalBtManager() {
+ return sLocalBluetoothManager;
}
@Override
protected void onSlicePinned() {
- if (mLocalBluetoothManager == null) {
- Log.i(TAG, "onSlicePinned() Bluetooth is unsupported.");
+ final LocalBluetoothManager localBtManager = mLoadBtManagerHandler.getLocalBtManager();
+ if (localBtManager == null) {
return;
}
- mLocalBluetoothManager.getEventManager().registerCallback(this);
+ localBtManager.getEventManager().registerCallback(this);
}
@Override
protected void onSliceUnpinned() {
- if (mLocalBluetoothManager == null) {
- Log.i(TAG, "onSliceUnpinned() Bluetooth is unsupported.");
+ final LocalBluetoothManager localBtManager = mLoadBtManagerHandler.getLocalBtManager();
+ if (localBtManager == null) {
return;
}
- mLocalBluetoothManager.getEventManager().unregisterCallback(this);
+ localBtManager.getEventManager().unregisterCallback(this);
}
@Override
@@ -84,4 +106,59 @@
int bluetoothProfile) {
notifySliceChange();
}
+
+ private static class LoadBtManagerHandler extends Handler {
+
+ private static LoadBtManagerHandler sHandler;
+
+ private final Runnable mLoadBtManagerTask;
+ private final Context mContext;
+ private BluetoothUpdateWorker mWorker;
+
+ private static LoadBtManagerHandler getInstance(Context context) {
+ if (sHandler == null) {
+ final HandlerThread workerThread = new HandlerThread(TAG,
+ Process.THREAD_PRIORITY_BACKGROUND);
+ workerThread.start();
+ sHandler = new LoadBtManagerHandler(context, workerThread.getLooper());
+ }
+ return sHandler;
+ }
+
+ private LoadBtManagerHandler(Context context, Looper looper) {
+ super(looper);
+ mContext = context;
+ mLoadBtManagerTask = () -> {
+ Log.d(TAG, "LoadBtManagerHandler: start loading...");
+ final long startTime = System.currentTimeMillis();
+ sLocalBluetoothManager = getLocalBtManager();
+ Log.d(TAG, "LoadBtManagerHandler took " + (System.currentTimeMillis() - startTime)
+ + " ms");
+ };
+ }
+
+ private LocalBluetoothManager getLocalBtManager() {
+ if (sLocalBluetoothManager != null) {
+ return sLocalBluetoothManager;
+ }
+ return LocalBluetoothManager.getInstance(mContext,
+ (context, btManager) -> {
+ if (mWorker != null) {
+ // notify change if the worker is ready
+ mWorker.notifySliceChange();
+ }
+ });
+ }
+
+ private void startLoadingBtManager() {
+ if (!hasCallbacks(mLoadBtManagerTask)) {
+ post(mLoadBtManagerTask);
+ }
+ }
+
+ private void startLoadingBtManager(BluetoothUpdateWorker worker) {
+ mWorker = worker;
+ startLoadingBtManager();
+ }
+ }
}
\ No newline at end of file