Loading src/com/android/settings/bluetooth/BluetoothSliceBuilder.java +3 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -83,7 +81,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); Loading Loading @@ -119,9 +117,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(); } Loading src/com/android/settings/slices/SettingsSliceProvider.java +48 −38 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ 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.text.TextUtils; Loading @@ -31,13 +32,13 @@ import android.util.KeyValueListParser; import android.util.Log; import android.util.Pair; 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.core.BasePreferenceController; 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; Loading @@ -53,7 +54,6 @@ import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.SliceProvider; Loading Loading @@ -177,6 +177,13 @@ public class SettingsSliceProvider extends SliceProvider { @Override public Slice onBindSlice(Uri sliceUri) { 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)) { Loading Loading @@ -212,6 +219,9 @@ public class SettingsSliceProvider extends SliceProvider { mSliceWeakDataCache.remove(sliceUri); } return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData); } finally { StrictMode.setThreadPolicy(oldPolicy); } } /** Loading tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +46 −7 Original line number Diff line number Diff line Loading @@ -18,9 +18,7 @@ package com.android.settings.slices; import static android.content.ContentResolver.SCHEME_CONTENT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading @@ -38,19 +36,24 @@ import android.os.StrictMode; import android.provider.SettingsSlicesContract; import android.util.ArraySet; import com.android.settings.location.LocationSliceBuilder; import com.android.settings.wifi.WifiSliceBuilder; import com.android.settings.bluetooth.BluetoothSliceBuilder; import com.android.settings.location.LocationSliceBuilder; import com.android.settings.notification.ZenModeSliceBuilder; import com.android.settings.testutils.DatabaseTestUtils; import com.android.settings.testutils.FakeToggleController; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.wifi.WifiSliceBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; import java.util.Arrays; import java.util.Collection; Loading @@ -66,6 +69,7 @@ import androidx.slice.Slice; * TODO Investigate using ShadowContentResolver.registerProviderInternal(String, ContentProvider) */ @RunWith(SettingsRobolectricTestRunner.class) @Config(shadows = ShadowThreadUtils.class) public class SettingsSliceProviderTest { private static final String KEY = "KEY"; Loading Loading @@ -98,6 +102,7 @@ public class SettingsSliceProviderTest { public void setUp() { mContext = spy(RuntimeEnvironment.application); mProvider = spy(new SettingsSliceProvider()); ShadowStrictMode.reset(); mProvider.mSliceWeakDataCache = new HashMap<>(); mProvider.mSliceDataCache = new HashMap<>(); mProvider.mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(mContext); Loading @@ -112,6 +117,7 @@ public class SettingsSliceProviderTest { @After public void cleanUp() { ShadowThreadUtils.reset(); DatabaseTestUtils.clearDb(mContext); } Loading Loading @@ -184,7 +190,8 @@ public class SettingsSliceProviderTest { } @Test public void onBindSlice_shouldNotOverrideStrictMode() { public void onBindSlice_mainThread_shouldNotOverrideStrictMode() { ShadowThreadUtils.setIsMainThread(true); final StrictMode.ThreadPolicy oldThreadPolicy = StrictMode.getThreadPolicy(); SliceData data = getDummyData(); mProvider.mSliceWeakDataCache.put(data.getUri(), data); Loading @@ -196,7 +203,19 @@ public class SettingsSliceProviderTest { } @Test public void onBindSlice_requestsBlockedSlice_retunsNull() { @Config(shadows = ShadowStrictMode.class) public void onBindSlice_backgroundThread_shouldOverrideStrictMode() { ShadowThreadUtils.setIsMainThread(false); SliceData data = getDummyData(); mProvider.mSliceWeakDataCache.put(data.getUri(), data); mProvider.onBindSlice(data.getUri()); assertThat(ShadowStrictMode.isThreadPolicyOverridden()).isTrue(); } @Test public void onBindSlice_requestsBlockedSlice_returnsNull() { final String blockedKey = "blocked_key"; final Set<String> blockedSet = new ArraySet<>(); blockedSet.add(blockedKey); Loading Loading @@ -456,7 +475,7 @@ public class SettingsSliceProviderTest { mDb.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values); } private SliceData getDummyData() { private static SliceData getDummyData() { return new SliceData.Builder() .setKey(KEY) .setTitle(TITLE) Loading @@ -468,4 +487,24 @@ public class SettingsSliceProviderTest { .setPreferenceControllerClassName(PREF_CONTROLLER) .build(); } @Implements(value = StrictMode.class, inheritImplementationMethods = true) public static class ShadowStrictMode { private static int sSetThreadPolicyCount; @Resetter public static void reset() { sSetThreadPolicyCount = 0; } @Implementation public static void setThreadPolicy(final StrictMode.ThreadPolicy policy) { sSetThreadPolicyCount++; } public static boolean isThreadPolicyOverridden() { return sSetThreadPolicyCount != 0; } } } No newline at end of file tests/robotests/src/com/android/settings/testutils/shadow/ShadowThreadUtils.java +18 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,18 @@ import com.android.settingslib.utils.ThreadUtils; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; @Implements(ThreadUtils.class) public class ShadowThreadUtils { private static boolean sIsMainThread = true; @Resetter public static void reset() { sIsMainThread = true; } @Implementation public static void postOnBackgroundThread(Runnable runnable) { runnable.run(); Loading @@ -33,4 +41,14 @@ public class ShadowThreadUtils { public static void postOnMainThread(Runnable runnable) { runnable.run(); } @Implementation public static boolean isMainThread() { return sIsMainThread; } public static void setIsMainThread(boolean isMainThread) { sIsMainThread = isMainThread; } } Loading
src/com/android/settings/bluetooth/BluetoothSliceBuilder.java +3 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -83,7 +81,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); Loading Loading @@ -119,9 +117,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(); } Loading
src/com/android/settings/slices/SettingsSliceProvider.java +48 −38 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ 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.text.TextUtils; Loading @@ -31,13 +32,13 @@ import android.util.KeyValueListParser; import android.util.Log; import android.util.Pair; 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.core.BasePreferenceController; 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; Loading @@ -53,7 +54,6 @@ import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.SliceProvider; Loading Loading @@ -177,6 +177,13 @@ public class SettingsSliceProvider extends SliceProvider { @Override public Slice onBindSlice(Uri sliceUri) { 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)) { Loading Loading @@ -212,6 +219,9 @@ public class SettingsSliceProvider extends SliceProvider { mSliceWeakDataCache.remove(sliceUri); } return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData); } finally { StrictMode.setThreadPolicy(oldPolicy); } } /** Loading
tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +46 −7 Original line number Diff line number Diff line Loading @@ -18,9 +18,7 @@ package com.android.settings.slices; import static android.content.ContentResolver.SCHEME_CONTENT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading @@ -38,19 +36,24 @@ import android.os.StrictMode; import android.provider.SettingsSlicesContract; import android.util.ArraySet; import com.android.settings.location.LocationSliceBuilder; import com.android.settings.wifi.WifiSliceBuilder; import com.android.settings.bluetooth.BluetoothSliceBuilder; import com.android.settings.location.LocationSliceBuilder; import com.android.settings.notification.ZenModeSliceBuilder; import com.android.settings.testutils.DatabaseTestUtils; import com.android.settings.testutils.FakeToggleController; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.wifi.WifiSliceBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; import java.util.Arrays; import java.util.Collection; Loading @@ -66,6 +69,7 @@ import androidx.slice.Slice; * TODO Investigate using ShadowContentResolver.registerProviderInternal(String, ContentProvider) */ @RunWith(SettingsRobolectricTestRunner.class) @Config(shadows = ShadowThreadUtils.class) public class SettingsSliceProviderTest { private static final String KEY = "KEY"; Loading Loading @@ -98,6 +102,7 @@ public class SettingsSliceProviderTest { public void setUp() { mContext = spy(RuntimeEnvironment.application); mProvider = spy(new SettingsSliceProvider()); ShadowStrictMode.reset(); mProvider.mSliceWeakDataCache = new HashMap<>(); mProvider.mSliceDataCache = new HashMap<>(); mProvider.mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(mContext); Loading @@ -112,6 +117,7 @@ public class SettingsSliceProviderTest { @After public void cleanUp() { ShadowThreadUtils.reset(); DatabaseTestUtils.clearDb(mContext); } Loading Loading @@ -184,7 +190,8 @@ public class SettingsSliceProviderTest { } @Test public void onBindSlice_shouldNotOverrideStrictMode() { public void onBindSlice_mainThread_shouldNotOverrideStrictMode() { ShadowThreadUtils.setIsMainThread(true); final StrictMode.ThreadPolicy oldThreadPolicy = StrictMode.getThreadPolicy(); SliceData data = getDummyData(); mProvider.mSliceWeakDataCache.put(data.getUri(), data); Loading @@ -196,7 +203,19 @@ public class SettingsSliceProviderTest { } @Test public void onBindSlice_requestsBlockedSlice_retunsNull() { @Config(shadows = ShadowStrictMode.class) public void onBindSlice_backgroundThread_shouldOverrideStrictMode() { ShadowThreadUtils.setIsMainThread(false); SliceData data = getDummyData(); mProvider.mSliceWeakDataCache.put(data.getUri(), data); mProvider.onBindSlice(data.getUri()); assertThat(ShadowStrictMode.isThreadPolicyOverridden()).isTrue(); } @Test public void onBindSlice_requestsBlockedSlice_returnsNull() { final String blockedKey = "blocked_key"; final Set<String> blockedSet = new ArraySet<>(); blockedSet.add(blockedKey); Loading Loading @@ -456,7 +475,7 @@ public class SettingsSliceProviderTest { mDb.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values); } private SliceData getDummyData() { private static SliceData getDummyData() { return new SliceData.Builder() .setKey(KEY) .setTitle(TITLE) Loading @@ -468,4 +487,24 @@ public class SettingsSliceProviderTest { .setPreferenceControllerClassName(PREF_CONTROLLER) .build(); } @Implements(value = StrictMode.class, inheritImplementationMethods = true) public static class ShadowStrictMode { private static int sSetThreadPolicyCount; @Resetter public static void reset() { sSetThreadPolicyCount = 0; } @Implementation public static void setThreadPolicy(final StrictMode.ThreadPolicy policy) { sSetThreadPolicyCount++; } public static boolean isThreadPolicyOverridden() { return sSetThreadPolicyCount != 0; } } } No newline at end of file
tests/robotests/src/com/android/settings/testutils/shadow/ShadowThreadUtils.java +18 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,18 @@ import com.android.settingslib.utils.ThreadUtils; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; @Implements(ThreadUtils.class) public class ShadowThreadUtils { private static boolean sIsMainThread = true; @Resetter public static void reset() { sIsMainThread = true; } @Implementation public static void postOnBackgroundThread(Runnable runnable) { runnable.run(); Loading @@ -33,4 +41,14 @@ public class ShadowThreadUtils { public static void postOnMainThread(Runnable runnable) { runnable.run(); } @Implementation public static boolean isMainThread() { return sIsMainThread; } public static void setIsMainThread(boolean isMainThread) { sIsMainThread = isMainThread; } }