2nd attempt to fix Slice strict mode.
1. Use real BluetoothAdapter instead of settingslib version. The settingslib version contains calls that violates strictmode rules. 2. Override StrictMode rules in SettingsSliceProvider when it's called in background thread. When in background, the enforcement from Slice framework (StrictMode#ThreadPolicy) is not useful and can be safely ignored. Change-Id: I68523148f4c1dc88a54e207447d21ec439478cdf Merged-In: I68523148f4c1dc88a54e207447d21ec439478cdf Fixes: 79985175 Test: robotests
This commit is contained in:
@@ -17,8 +17,6 @@ package com.android.settings.bluetooth;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
@@ -28,6 +26,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
@@ -42,8 +41,6 @@ import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
|
||||
public class BluetoothSliceBuilder {
|
||||
|
||||
private static final String TAG = "BluetoothSliceBuilder";
|
||||
@@ -71,7 +68,8 @@ public class BluetoothSliceBuilder {
|
||||
INTENT_FILTER.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
|
||||
}
|
||||
|
||||
private BluetoothSliceBuilder() {}
|
||||
private BluetoothSliceBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Bluetooth Slice bound to {@link #BLUETOOTH_URI}.
|
||||
@@ -80,7 +78,7 @@ public class BluetoothSliceBuilder {
|
||||
* Bluetooth.
|
||||
*/
|
||||
public static Slice getSlice(Context context) {
|
||||
final boolean isBluetoothEnabled = isBluetoothEnabled(context);
|
||||
final boolean isBluetoothEnabled = isBluetoothEnabled();
|
||||
final CharSequence title = context.getText(R.string.bluetooth_settings);
|
||||
final IconCompat icon = IconCompat.createWithResource(context,
|
||||
R.drawable.ic_settings_bluetooth);
|
||||
@@ -115,9 +113,8 @@ public class BluetoothSliceBuilder {
|
||||
// handle it.
|
||||
}
|
||||
|
||||
private static boolean isBluetoothEnabled(Context context) {
|
||||
final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(context,
|
||||
null /* callback */).getBluetoothAdapter();
|
||||
private static boolean isBluetoothEnabled() {
|
||||
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
return adapter.isEnabled();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,23 +23,23 @@ import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.StrictMode;
|
||||
import android.provider.Settings;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.KeyValueListParser;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.settings.location.LocationSliceBuilder;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.location.LocationSliceBuilder;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
|
||||
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
import com.android.settingslib.SliceBroadcastRelay;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
@@ -150,7 +150,7 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
@Override
|
||||
public void onSlicePinned(Uri sliceUri) {
|
||||
if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
|
||||
registerIntentToUri(WifiSliceBuilder.INTENT_FILTER , sliceUri);
|
||||
registerIntentToUri(WifiSliceBuilder.INTENT_FILTER, sliceUri);
|
||||
return;
|
||||
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
|
||||
registerIntentToUri(ZenModeSliceBuilder.INTENT_FILTER, sliceUri);
|
||||
@@ -176,41 +176,51 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
|
||||
@Override
|
||||
public Slice onBindSlice(Uri sliceUri) {
|
||||
final Set<String> blockedKeys = getBlockedKeys();
|
||||
final String key = sliceUri.getLastPathSegment();
|
||||
if (blockedKeys.contains(key)) {
|
||||
Log.e(TAG, "Requested blocked slice with Uri: " + sliceUri);
|
||||
return null;
|
||||
}
|
||||
final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
|
||||
try {
|
||||
if (!ThreadUtils.isMainThread()) {
|
||||
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
|
||||
.permitAll()
|
||||
.build());
|
||||
}
|
||||
final Set<String> blockedKeys = getBlockedKeys();
|
||||
final String key = sliceUri.getLastPathSegment();
|
||||
if (blockedKeys.contains(key)) {
|
||||
Log.e(TAG, "Requested blocked slice with Uri: " + sliceUri);
|
||||
return null;
|
||||
}
|
||||
|
||||
// If adding a new Slice, do not directly match Slice URIs.
|
||||
// Use {@link SlicesDatabaseAccessor}.
|
||||
if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
|
||||
return FeatureFactory.getFactory(getContext())
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(getContext())
|
||||
.createWifiCallingSlice(sliceUri);
|
||||
} else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
|
||||
return WifiSliceBuilder.getSlice(getContext());
|
||||
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
|
||||
return ZenModeSliceBuilder.getSlice(getContext());
|
||||
} else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
|
||||
return BluetoothSliceBuilder.getSlice(getContext());
|
||||
} else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
|
||||
return LocationSliceBuilder.getSlice(getContext());
|
||||
}
|
||||
// If adding a new Slice, do not directly match Slice URIs.
|
||||
// Use {@link SlicesDatabaseAccessor}.
|
||||
if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
|
||||
return FeatureFactory.getFactory(getContext())
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(getContext())
|
||||
.createWifiCallingSlice(sliceUri);
|
||||
} else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
|
||||
return WifiSliceBuilder.getSlice(getContext());
|
||||
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
|
||||
return ZenModeSliceBuilder.getSlice(getContext());
|
||||
} else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
|
||||
return BluetoothSliceBuilder.getSlice(getContext());
|
||||
} else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
|
||||
return LocationSliceBuilder.getSlice(getContext());
|
||||
}
|
||||
|
||||
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
||||
if (cachedSliceData == null) {
|
||||
loadSliceInBackground(sliceUri);
|
||||
return getSliceStub(sliceUri);
|
||||
}
|
||||
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
||||
if (cachedSliceData == null) {
|
||||
loadSliceInBackground(sliceUri);
|
||||
return getSliceStub(sliceUri);
|
||||
}
|
||||
|
||||
// Remove the SliceData from the cache after it has been used to prevent a memory-leak.
|
||||
if (!mSliceDataCache.containsKey(sliceUri)) {
|
||||
mSliceWeakDataCache.remove(sliceUri);
|
||||
// Remove the SliceData from the cache after it has been used to prevent a memory-leak.
|
||||
if (!mSliceDataCache.containsKey(sliceUri)) {
|
||||
mSliceWeakDataCache.remove(sliceUri);
|
||||
}
|
||||
return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData);
|
||||
} finally {
|
||||
StrictMode.setThreadPolicy(oldPolicy);
|
||||
}
|
||||
return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user