Merge "Use LruCache to cache advanced bluetooth deivce icon" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c59b1057d8
@@ -24,6 +24,10 @@ import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.BluetoothUuid;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@@ -32,12 +36,16 @@ import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.LruCache;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.settingslib.widget.AdaptiveOutlineDrawable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -100,6 +108,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
private boolean mIsHearingAidProfileConnectedFail = false;
|
||||
// Group second device for Hearing Aid
|
||||
private CachedBluetoothDevice mSubDevice;
|
||||
@VisibleForTesting
|
||||
LruCache<String, BitmapDrawable> mDrawableCache;
|
||||
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
@@ -131,6 +141,19 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
mDevice = device;
|
||||
fillData();
|
||||
mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID;
|
||||
initDrawableCache();
|
||||
}
|
||||
|
||||
private void initDrawableCache() {
|
||||
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
|
||||
int cacheSize = maxMemory / 8;
|
||||
|
||||
mDrawableCache = new LruCache<String, BitmapDrawable>(cacheSize) {
|
||||
@Override
|
||||
protected int sizeOf(String key, BitmapDrawable bitmap) {
|
||||
return bitmap.getBitmap().getByteCount() / 1024;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,6 +404,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
if (dev != null) {
|
||||
final boolean successful = dev.removeBond();
|
||||
if (successful) {
|
||||
releaseLruCache();
|
||||
if (BluetoothUtils.D) {
|
||||
Log.d(TAG, "Command sent successfully:REMOVE_BOND " + describe(null));
|
||||
}
|
||||
@@ -500,7 +524,21 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
dispatchAttributesChanged();
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
if (BluetoothUtils.isAdvancedDetailsHeader(mDevice)) {
|
||||
Uri uri = BluetoothUtils.getUriMetaData(getDevice(),
|
||||
BluetoothDevice.METADATA_MAIN_ICON);
|
||||
if (uri != null && mDrawableCache.get(uri.toString()) == null) {
|
||||
mDrawableCache.put(uri.toString(),
|
||||
(BitmapDrawable) BluetoothUtils.getBtDrawableWithDescription(
|
||||
mContext, this).first);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadUtils.postOnMainThread(() -> {
|
||||
dispatchAttributesChanged();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void setJustDiscovered(boolean justDiscovered) {
|
||||
@@ -1178,4 +1216,28 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
mSubDevice.mJustDiscovered = tmpJustDiscovered;
|
||||
fetchActiveDevices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached bluetooth icon with description
|
||||
*/
|
||||
public Pair<Drawable, String> getDrawableWithDescription() {
|
||||
Uri uri = BluetoothUtils.getUriMetaData(mDevice, BluetoothDevice.METADATA_MAIN_ICON);
|
||||
if (BluetoothUtils.isAdvancedDetailsHeader(mDevice) && uri != null) {
|
||||
BitmapDrawable drawable = mDrawableCache.get(uri.toString());
|
||||
if (drawable != null) {
|
||||
Resources resources = mContext.getResources();
|
||||
return new Pair<>(new AdaptiveOutlineDrawable(
|
||||
resources, drawable.getBitmap()),
|
||||
BluetoothUtils.getBtClassDrawableWithDescription(mContext, this).second);
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
return BluetoothUtils.getBtRainbowDrawableWithDescription(mContext, this);
|
||||
}
|
||||
|
||||
void releaseLruCache() {
|
||||
mDrawableCache.evictAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.media.AudioManager;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settingslib.widget.AdaptiveOutlineDrawable;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -957,4 +958,41 @@ public class CachedBluetoothDeviceTest {
|
||||
|
||||
// Should not crash
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDrawableWithDescription_isAdvancedDevice_returnAdvancedIcon() {
|
||||
when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_ICON))
|
||||
.thenReturn("fake_uri".getBytes());
|
||||
when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
|
||||
mCachedDevice.refresh();
|
||||
|
||||
assertThat(mCachedDevice.getDrawableWithDescription().first).isInstanceOf(
|
||||
AdaptiveOutlineDrawable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDrawableWithDescription_isNotAdvancedDevice_returnBluetoothIcon() {
|
||||
when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("false".getBytes());
|
||||
|
||||
mCachedDevice.refresh();
|
||||
|
||||
assertThat(mCachedDevice.getDrawableWithDescription().first).isNotInstanceOf(
|
||||
AdaptiveOutlineDrawable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void releaseLruCache_lruCacheShouldBeRelease() {
|
||||
when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_ICON))
|
||||
.thenReturn("fake_uri".getBytes());
|
||||
when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
|
||||
mCachedDevice.refresh();
|
||||
mCachedDevice.releaseLruCache();
|
||||
|
||||
assertThat(mCachedDevice.mDrawableCache.size()).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user