diff --git a/res/values/config.xml b/res/values/config.xml
index 8e55ea95e36..f46134f301b 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -134,4 +134,9 @@
true
+
+ false
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 42151fb6759..634831633ef 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -19,8 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="my_device_info_pref_screen"
- android:title="@string/about_settings"
- settings:initialExpandedChildrenCount="7">
+ android:title="@string/about_settings">
mCandidates;
private final SettingsObserver mSettingsObserver;
public VibrationPreferenceFragment() {
mCandidates = new ArrayMap<>();
- mCandidates.put(KEY_INTENSITY_OFF,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
- R.string.accessibility_vibration_intensity_off,
- Vibrator.VIBRATION_INTENSITY_OFF));
- mCandidates.put(KEY_INTENSITY_LOW,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_LOW,
- R.string.accessibility_vibration_intensity_low,
- Vibrator.VIBRATION_INTENSITY_LOW));
- mCandidates.put(KEY_INTENSITY_MEDIUM,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_MEDIUM,
- R.string.accessibility_vibration_intensity_medium,
- Vibrator.VIBRATION_INTENSITY_MEDIUM));
- mCandidates.put(KEY_INTENSITY_HIGH,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_HIGH,
- R.string.accessibility_vibration_intensity_high,
- Vibrator.VIBRATION_INTENSITY_HIGH));
mSettingsObserver = new SettingsObserver();
}
@@ -82,6 +71,39 @@ public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragm
public void onAttach(Context context) {
super.onAttach(context);
mSettingsObserver.register();
+ if (mCandidates.isEmpty()) {
+ loadCandidates(context);
+ }
+ }
+
+ private void loadCandidates(Context context) {
+ final boolean supportsMultipleIntensities = context.getResources().getBoolean(
+ R.bool.config_vibration_supports_multiple_intensities);
+ if (supportsMultipleIntensities) {
+ mCandidates.put(KEY_INTENSITY_OFF,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
+ R.string.accessibility_vibration_intensity_off,
+ Vibrator.VIBRATION_INTENSITY_OFF));
+ mCandidates.put(KEY_INTENSITY_LOW,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_LOW,
+ R.string.accessibility_vibration_intensity_low,
+ Vibrator.VIBRATION_INTENSITY_LOW));
+ mCandidates.put(KEY_INTENSITY_MEDIUM,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_MEDIUM,
+ R.string.accessibility_vibration_intensity_medium,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM));
+ mCandidates.put(KEY_INTENSITY_HIGH,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_HIGH,
+ R.string.accessibility_vibration_intensity_high,
+ Vibrator.VIBRATION_INTENSITY_HIGH));
+ } else {
+ mCandidates.put(KEY_INTENSITY_OFF,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
+ R.string.switch_off_text, Vibrator.VIBRATION_INTENSITY_OFF));
+ mCandidates.put(KEY_INTENSITY_ON,
+ new VibrationIntensityCandidateInfo(KEY_INTENSITY_ON,
+ R.string.switch_on_text, getDefaultVibrationIntensity()));
+ }
}
@Override
@@ -105,6 +127,24 @@ public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragm
*/
protected void onVibrationIntensitySelected(int intensity) { }
+ /**
+ * Play a vibration effect with intensity just selected by user
+ */
+ protected void playVibrationPreview() {
+ Vibrator vibrator = getContext().getSystemService(Vibrator.class);
+ VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+ AudioAttributes.Builder builder = new AudioAttributes.Builder();
+ builder.setUsage(getPreviewVibrationAudioAttributesUsage());
+ vibrator.vibrate(effect, builder.build());
+ }
+
+ /**
+ * Get the AudioAttributes usage for vibration preview.
+ */
+ protected int getPreviewVibrationAudioAttributesUsage() {
+ return AudioAttributes.USAGE_UNKNOWN;
+ }
+
@Override
protected List extends CandidateInfo> getCandidates() {
List candidates = new ArrayList<>(mCandidates.values());
@@ -118,7 +158,10 @@ public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragm
final int vibrationIntensity = Settings.System.getInt(getContext().getContentResolver(),
getVibrationIntensitySetting(), getDefaultVibrationIntensity());
for (VibrationIntensityCandidateInfo candidate : mCandidates.values()) {
- if (candidate.getIntensity() == vibrationIntensity) {
+ final boolean matchesIntensity = candidate.getIntensity() == vibrationIntensity;
+ final boolean matchesOn = candidate.getKey().equals(KEY_INTENSITY_ON)
+ && vibrationIntensity != Vibrator.VIBRATION_INTENSITY_OFF;
+ if (matchesIntensity || matchesOn) {
return candidate.getKey();
}
}
@@ -189,6 +232,7 @@ public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragm
@Override
public void onChange(boolean selfChange, Uri uri) {
updateCandidates();
+ playVibrationPreview();
}
}
}
diff --git a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
index 5ec193c372a..cdc54a6ad58 100644
--- a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
+++ b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
@@ -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;
@@ -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);
@@ -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();
}
diff --git a/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java b/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java
index 3d551cdefaf..46b493fe046 100644
--- a/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java
+++ b/src/com/android/settings/development/EmulateDisplayCutoutPreferenceController.java
@@ -19,20 +19,23 @@ package com.android.settings.development;
import static android.os.UserHandle.USER_SYSTEM;
import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.view.DisplayCutout;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import android.text.TextUtils;
-import android.view.DisplayCutout;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.wrapper.OverlayManagerWrapper;
-import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+import java.util.ArrayList;
import java.util.List;
public class EmulateDisplayCutoutPreferenceController extends
@@ -41,7 +44,7 @@ public class EmulateDisplayCutoutPreferenceController extends
private static final String KEY = "display_cutout_emulation";
- private final OverlayManagerWrapper mOverlayManager;
+ private final IOverlayManager mOverlayManager;
private final boolean mAvailable;
private ListPreference mPreference;
@@ -49,7 +52,7 @@ public class EmulateDisplayCutoutPreferenceController extends
@VisibleForTesting
EmulateDisplayCutoutPreferenceController(Context context, PackageManager packageManager,
- OverlayManagerWrapper overlayManager) {
+ IOverlayManager overlayManager) {
super(context);
mOverlayManager = overlayManager;
mPackageManager = packageManager;
@@ -57,7 +60,8 @@ public class EmulateDisplayCutoutPreferenceController extends
}
public EmulateDisplayCutoutPreferenceController(Context context) {
- this(context, context.getPackageManager(), new OverlayManagerWrapper());
+ this(context, context.getPackageManager(), IOverlayManager.Stub
+ .asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
}
@Override
@@ -102,10 +106,14 @@ public class EmulateDisplayCutoutPreferenceController extends
}
final boolean result;
- if (TextUtils.isEmpty(packageName)) {
- result = mOverlayManager.setEnabled(currentPackageName, false, USER_SYSTEM);
- } else {
- result = mOverlayManager.setEnabledExclusiveInCategory(packageName, USER_SYSTEM);
+ try {
+ if (TextUtils.isEmpty(packageName)) {
+ result = mOverlayManager.setEnabled(currentPackageName, false, USER_SYSTEM);
+ } else {
+ result = mOverlayManager.setEnabledExclusiveInCategory(packageName, USER_SYSTEM);
+ }
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
}
updateState(mPreference);
return result;
@@ -145,13 +153,17 @@ public class EmulateDisplayCutoutPreferenceController extends
}
private OverlayInfo[] getOverlayInfos() {
- @SuppressWarnings("unchecked") List overlayInfos =
- mOverlayManager.getOverlayInfosForTarget("android", USER_SYSTEM);
- for (int i = overlayInfos.size() - 1; i >= 0; i--) {
- if (!DisplayCutout.EMULATION_OVERLAY_CATEGORY.equals(
- overlayInfos.get(i).category)) {
- overlayInfos.remove(i);
+ List overlayInfos;
+ try {
+ overlayInfos = mOverlayManager.getOverlayInfosForTarget("android", USER_SYSTEM);
+ for (int i = overlayInfos.size() - 1; i >= 0; i--) {
+ if (!DisplayCutout.EMULATION_OVERLAY_CATEGORY.equals(
+ overlayInfos.get(i).category)) {
+ overlayInfos.remove(i);
+ }
}
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
}
return overlayInfos.toArray(new OverlayInfo[overlayInfos.size()]);
}
diff --git a/src/com/android/settings/display/ThemePreferenceController.java b/src/com/android/settings/display/ThemePreferenceController.java
index 2cdf7e21c30..c71a7abf498 100644
--- a/src/com/android/settings/display/ThemePreferenceController.java
+++ b/src/com/android/settings/display/ThemePreferenceController.java
@@ -13,23 +13,22 @@
*/
package com.android.settings.display;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_THEME;
+
import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
import android.text.TextUtils;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.wrapper.OverlayManagerWrapper;
-import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -37,7 +36,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_THEME;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
public class ThemePreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
@@ -45,16 +46,16 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
private static final String KEY_THEME = "theme";
private final MetricsFeatureProvider mMetricsFeatureProvider;
- private final OverlayManagerWrapper mOverlayService;
+ private final IOverlayManager mOverlayService;
private final PackageManager mPackageManager;
public ThemePreferenceController(Context context) {
- this(context, ServiceManager.getService(Context.OVERLAY_SERVICE) != null
- ? new OverlayManagerWrapper() : null);
+ this(context, IOverlayManager.Stub
+ .asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
}
@VisibleForTesting
- ThemePreferenceController(Context context, OverlayManagerWrapper overlayManager) {
+ ThemePreferenceController(Context context, IOverlayManager overlayManager) {
super(context);
mOverlayService = overlayManager;
mPackageManager = context.getPackageManager();
@@ -77,7 +78,7 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
@Override
public void updateState(Preference preference) {
ListPreference pref = (ListPreference) preference;
- String[] pkgs = getAvailableThemes();
+ String[] pkgs = getAvailableThemes(false /* currentThemeOnly */);
CharSequence[] labels = new CharSequence[pkgs.length];
for (int i = 0; i < pkgs.length; i++) {
try {
@@ -109,11 +110,15 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- String current = getTheme();
+ String current = getCurrentTheme();
if (Objects.equals(newValue, current)) {
return true;
}
- mOverlayService.setEnabledExclusiveInCategory((String) newValue, UserHandle.myUserId());
+ try {
+ mOverlayService.setEnabledExclusiveInCategory((String) newValue, UserHandle.myUserId());
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
return true;
}
@@ -129,39 +134,43 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
}
}
- private String getTheme() {
- List infos = mOverlayService.getOverlayInfosForTarget("android",
- UserHandle.myUserId());
- for (int i = 0, size = infos.size(); i < size; i++) {
- if (infos.get(i).isEnabled() && isTheme(infos.get(i))) {
- return infos.get(i).packageName;
- }
- }
- return null;
- }
-
@Override
public boolean isAvailable() {
if (mOverlayService == null) return false;
- String[] themes = getAvailableThemes();
+ String[] themes = getAvailableThemes(false /* currentThemeOnly */);
return themes != null && themes.length > 1;
}
@VisibleForTesting
String getCurrentTheme() {
- return getTheme();
+ String[] themePackages = getAvailableThemes(true /* currentThemeOnly */);
+ return themePackages.length < 1 ? null : themePackages[0];
}
@VisibleForTesting
- String[] getAvailableThemes() {
- List infos = mOverlayService.getOverlayInfosForTarget("android",
- UserHandle.myUserId());
- List pkgs = new ArrayList<>(infos.size());
- for (int i = 0, size = infos.size(); i < size; i++) {
- if (isTheme(infos.get(i))) {
- pkgs.add(infos.get(i).packageName);
+ String[] getAvailableThemes(boolean currentThemeOnly) {
+ List infos;
+ List pkgs;
+ try {
+ infos = mOverlayService.getOverlayInfosForTarget("android", UserHandle.myUserId());
+ pkgs = new ArrayList<>(infos.size());
+ for (int i = 0, size = infos.size(); i < size; i++) {
+ if (isTheme(infos.get(i))) {
+ if (infos.get(i).isEnabled() && currentThemeOnly) {
+ return new String[] {infos.get(i).packageName};
+ } else {
+ pkgs.add(infos.get(i).packageName);
+ }
+ }
}
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+
+ // Current enabled theme is not found.
+ if (currentThemeOnly) {
+ return new String[0];
}
return pkgs.toArray(new String[pkgs.size()]);
}
diff --git a/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
index fbd779c37c0..d4dc4d2ed40 100644
--- a/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/SmartBatteryPreferenceController.java
@@ -19,6 +19,8 @@ package com.android.settings.fuelgauge;
import android.content.Context;
import android.provider.Settings;
+import android.text.TextUtils;
+
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
@@ -48,6 +50,11 @@ public class SmartBatteryPreferenceController extends BasePreferenceController i
: UNSUPPORTED_ON_DEVICE;
}
+ @Override
+ public boolean isSliceable() {
+ return TextUtils.equals(getPreferenceKey(), "smart_battery");
+ }
+
@Override
public void updateState(Preference preference) {
super.updateState(preference);
diff --git a/src/com/android/settings/notification/AlarmVolumePreferenceController.java b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
index 3c238aa7f29..92a1e907766 100644
--- a/src/com/android/settings/notification/AlarmVolumePreferenceController.java
+++ b/src/com/android/settings/notification/AlarmVolumePreferenceController.java
@@ -18,6 +18,7 @@ package com.android.settings.notification;
import android.content.Context;
import android.media.AudioManager;
+import android.text.TextUtils;
import com.android.settings.R;
@@ -36,6 +37,11 @@ public class AlarmVolumePreferenceController extends
&& !mHelper.isSingleVolume() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
+ @Override
+ public boolean isSliceable() {
+ return TextUtils.equals(getPreferenceKey(), "alarm_volume");
+ }
+
@Override
public String getPreferenceKey() {
return KEY_ALARM_VOLUME;
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 52888b0e698..f4dfd6ee71d 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -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;
@@ -31,13 +32,13 @@ 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;
@@ -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;
@@ -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);
mRegisteredUris.add(sliceUri);
return;
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
@@ -177,41 +177,51 @@ public class SettingsSliceProvider extends SliceProvider {
@Override
public Slice onBindSlice(Uri sliceUri) {
- final Set 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 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);
}
/**
@@ -302,14 +312,14 @@ public class SettingsSliceProvider extends SliceProvider {
final SliceData sliceData;
try {
- sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri);
+ sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri);
} catch (IllegalStateException e) {
Log.d(TAG, "Could not create slicedata for uri: " + uri);
return;
}
final BasePreferenceController controller = SliceBuilderUtils.getPreferenceController(
- getContext(), sliceData);
+ getContext(), sliceData);
final IntentFilter filter = controller.getIntentFilter();
if (filter != null) {
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index 213bf00c028..d81734a974d 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -27,6 +27,7 @@ import static com.android.settings.wifi.WifiSliceBuilder.ACTION_WIFI_SLICE_CHANG
import android.app.slice.Slice;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -155,6 +156,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
sliderController.setSliderPosition(newPosition);
logSliceValueChange(context, key, newPosition);
+ updateUri(context, key, isPlatformSlice);
}
/**
@@ -177,8 +179,15 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
}
private void updateUri(Context context, String key, boolean isPlatformDefined) {
- final String path = SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key;
- final Uri uri = SliceBuilderUtils.getUri(path, isPlatformDefined);
+ final String authority = isPlatformDefined
+ ? SettingsSlicesContract.AUTHORITY
+ : SettingsSliceProvider.SLICE_AUTHORITY;
+ final Uri uri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
context.getContentResolver().notifyChange(uri, null /* observer */);
}
}
diff --git a/src/com/android/settings/wrapper/OverlayManagerWrapper.java b/src/com/android/settings/wrapper/OverlayManagerWrapper.java
deleted file mode 100644
index 6e3c2348857..00000000000
--- a/src/com/android/settings/wrapper/OverlayManagerWrapper.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wrapper;
-
-import android.content.Context;
-import android.content.om.IOverlayManager;
-import android.content.om.OverlayInfo;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class OverlayManagerWrapper {
-
- private final IOverlayManager mOverlayManager;
-
- public OverlayManagerWrapper(IOverlayManager overlayManager) {
- mOverlayManager = overlayManager;
- }
-
- public OverlayManagerWrapper() {
- this(IOverlayManager.Stub.asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
- }
-
- public List getOverlayInfosForTarget(String overlay, int userId) {
- if (mOverlayManager == null) {
- return new ArrayList<>();
- }
- try {
- List infos
- = mOverlayManager.getOverlayInfosForTarget(overlay, userId);
- ArrayList result = new ArrayList<>(infos.size());
- for (int i = 0; i < infos.size(); i++) {
- result.add(new OverlayInfo(infos.get(i)));
- }
- return result;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- public boolean setEnabled(String overlay, boolean enabled, int userId) {
- if (mOverlayManager == null) {
- return false;
- }
- try {
- return mOverlayManager.setEnabled(overlay, enabled, userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- public boolean setEnabledExclusiveInCategory(String overlay, int userId) {
- if (mOverlayManager == null) {
- return false;
- }
- try {
- return mOverlayManager.setEnabledExclusiveInCategory(overlay, userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- public static class OverlayInfo {
-
- public static final String CATEGORY_THEME = android.content.om.OverlayInfo.CATEGORY_THEME;
- public final String packageName;
- public final String category;
- private final boolean mEnabled;
-
- public OverlayInfo(String packageName, String category, boolean enabled) {
- this.packageName = packageName;
- this.category = category;
- mEnabled = enabled;
- }
-
- public OverlayInfo(android.content.om.OverlayInfo info) {
- mEnabled = info.isEnabled();
- category = info.category;
- packageName = info.packageName;
- }
-
- public boolean isEnabled() {
- return mEnabled;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
index 4cab0282977..98b1770668f 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationGesturesPreferenceControllerTest.java
@@ -114,4 +114,19 @@ public class MagnificationGesturesPreferenceControllerTest {
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, -1))
.isEqualTo(OFF);
}
+
+ @Test
+ public void isSliceableCorrectKey_returnsTrue() {
+ final MagnificationGesturesPreferenceController controller =
+ new MagnificationGesturesPreferenceController(mContext,
+ "screen_magnification_gestures_preference_screen");
+ assertThat(controller.isSliceable()).isTrue();
+ }
+
+ @Test
+ public void isSliceableIncorrectKey_returnsFalse() {
+ final MagnificationGesturesPreferenceController controller =
+ new MagnificationGesturesPreferenceController(mContext, "bad_key");
+ assertThat(controller.isSliceable()).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
index d0d77711c2a..128e33bb351 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationNavbarPreferenceControllerTest.java
@@ -158,4 +158,19 @@ public class MagnificationNavbarPreferenceControllerTest {
sIsApplicable = applicable;
}
}
+
+ @Test
+ public void isSliceableCorrectKey_returnsTrue() {
+ final MagnificationNavbarPreferenceController controller =
+ new MagnificationNavbarPreferenceController(mContext,
+ "screen_magnification_navbar_preference_screen");
+ assertThat(controller.isSliceable()).isTrue();
+ }
+
+ @Test
+ public void isSliceableIncorrectKey_returnsFalse() {
+ final MagnificationNavbarPreferenceController controller =
+ new MagnificationNavbarPreferenceController(mContext, "bad_key");
+ assertThat(controller.isSliceable()).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
index 2a166f3fda2..dda2ae5e780 100644
--- a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
@@ -18,10 +18,12 @@ package com.android.settings.accessibility;
import static android.provider.Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import androidx.lifecycle.LifecycleOwner;
import android.content.Context;
+import android.content.res.Resources;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.preference.Preference;
@@ -48,6 +50,7 @@ public class NotificationVibrationIntensityPreferenceControllerTest {
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
+ private Resources mResources;
private NotificationVibrationIntensityPreferenceController mController;
private Preference mPreference;
@@ -56,7 +59,11 @@ public class NotificationVibrationIntensityPreferenceControllerTest {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
+ mResources = spy(mContext.getResources());
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
+ .thenReturn(true);
mController = new NotificationVibrationIntensityPreferenceController(mContext) {
@Override
protected int getDefaultIntensity() {
@@ -68,7 +75,6 @@ public class NotificationVibrationIntensityPreferenceControllerTest {
mPreference.setSummary("Test");
when(mScreen.findPreference(mController.getPreferenceKey()))
.thenReturn(mPreference);
- mController.displayPreference(mScreen);
}
@Test
@@ -80,7 +86,10 @@ public class NotificationVibrationIntensityPreferenceControllerTest {
}
@Test
- public void updateState_shouldRefreshSummary() {
+ public void updateState_withMultipleIntensitySuport_shouldRefreshSummary() {
+ setSupportsMultipleIntensities(true);
+ showPreference();
+
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
@@ -105,4 +114,43 @@ public class NotificationVibrationIntensityPreferenceControllerTest {
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_off));
}
+
+ @Test
+ public void updateState_withoutMultipleIntensitySupport_shouldRefreshSummary() {
+ setSupportsMultipleIntensities(false);
+ showPreference();
+
+ Settings.System.putInt(mContext.getContentResolver(),
+ NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.switch_on_text));
+
+ Settings.System.putInt(mContext.getContentResolver(),
+ NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.switch_on_text));
+
+ Settings.System.putInt(mContext.getContentResolver(),
+ NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.switch_on_text));
+
+ Settings.System.putInt(mContext.getContentResolver(),
+ NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.switch_off_text));
+ }
+
+ private void setSupportsMultipleIntensities(boolean hasSupport) {
+ when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
+ .thenReturn(hasSupport);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mScreen);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
index 8550cf98916..ecd2ff9ce57 100644
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
@@ -20,16 +20,19 @@ import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_LOW;
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_MEDIUM;
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_OFF;
+import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_ON;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import android.app.Activity;
import android.content.Context;
+import android.content.res.Resources;
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
+import com.android.settings.R;
import com.android.settings.accessibility.VibrationPreferenceFragment.VibrationIntensityCandidateInfo;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -58,12 +61,11 @@ public class VibrationPreferenceFragmentTest {
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_HIGH, KEY_INTENSITY_HIGH);
}
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Activity mActivity;
@Mock
private UserManager mUserManager;
private Context mContext;
+ private Resources mResources;
private TestVibrationPreferenceFragment mFragment;
@Before
@@ -71,16 +73,18 @@ public class VibrationPreferenceFragmentTest {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest();
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
+ mResources = spy(mContext.getResources());
+ when(mContext.getResources()).thenReturn(mResources);
mFragment = spy(new TestVibrationPreferenceFragment());
- doReturn(mUserManager).when(mActivity).getSystemService(Context.USER_SERVICE);
- doReturn(mContext).when(mFragment).getContext();
- mFragment.onAttach(mActivity);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
}
@Test
public void changeIntensitySetting_shouldResultInCorrespondingKey() {
+ setSupportsMultipleIntensities(true);
+ mFragment.onAttach(mContext);
for (Map.Entry entry : INTENSITY_TO_KEY.entrySet()) {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY, entry.getKey());
@@ -88,13 +92,38 @@ public class VibrationPreferenceFragmentTest {
}
}
+ @Test
+ public void changeIntensitySetting_WithoutMultipleIntensitySupport_shouldResultInOn() {
+ setSupportsMultipleIntensities(false);
+ mFragment.onAttach(mContext);
+ for (int intensity : INTENSITY_TO_KEY.keySet()) {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY, intensity);
+ final String expectedKey = intensity == Vibrator.VIBRATION_INTENSITY_OFF
+ ? KEY_INTENSITY_OFF
+ : KEY_INTENSITY_ON;
+ assertThat(mFragment.getDefaultKey()).isEqualTo(expectedKey);
+ }
+ }
+
@Test
public void initialDefaultKey_shouldBeMedium() {
+ setSupportsMultipleIntensities(true);
+ mFragment.onAttach(mContext);
assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_MEDIUM);
}
+ @Test
+ public void initialDefaultKey_WithoutMultipleIntensitySupport_shouldBeOn() {
+ setSupportsMultipleIntensities(false);
+ mFragment.onAttach(mContext);
+ assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_ON);
+ }
+
@Test
public void candidates_shouldBeSortedByIntensity() {
+ setSupportsMultipleIntensities(true);
+ mFragment.onAttach(mContext);
final List extends CandidateInfo> candidates = mFragment.getCandidates();
assertThat(candidates.size()).isEqualTo(INTENSITY_TO_KEY.size());
VibrationIntensityCandidateInfo prevCandidate =
@@ -106,6 +135,11 @@ public class VibrationPreferenceFragmentTest {
}
}
+ private void setSupportsMultipleIntensities(boolean hasSupport) {
+ when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
+ .thenReturn(hasSupport);
+ }
+
private class TestVibrationPreferenceFragment extends VibrationPreferenceFragment {
@Override
protected int getPreferenceScreenResId() {
@@ -129,5 +163,10 @@ public class VibrationPreferenceFragmentTest {
protected int getDefaultVibrationIntensity() {
return Vibrator.VIBRATION_INTENSITY_MEDIUM;
}
+
+ @Override
+ public Context getContext() {
+ return mContext;
+ }
}
}
diff --git a/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java
index 34a0581e582..fd063cb37b6 100644
--- a/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/EmulateDisplayCutoutPreferenceControllerTest.java
@@ -26,14 +26,15 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
import android.content.pm.PackageManager;
+import android.os.RemoteException;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceScreen;
import android.view.DisplayCutout;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.wrapper.OverlayManagerWrapper;
-import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import org.junit.Before;
import org.junit.Test;
@@ -41,6 +42,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
import java.util.Arrays;
@RunWith(SettingsRobolectricTestRunner.class)
@@ -54,7 +56,7 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
@Mock
private Context mContext;
@Mock
- private OverlayManagerWrapper mOverlayManager;
+ private IOverlayManager mOverlayManager;
@Mock
private PackageManager mPackageManager;
@Mock
@@ -64,6 +66,7 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.OVERLAY_SERVICE)).thenReturn(mOverlayManager);
mockCurrentOverlays();
when(mPackageManager.getApplicationInfo(any(), anyInt()))
.thenThrow(PackageManager.NameNotFoundException.class);
@@ -72,8 +75,12 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
}
Object mockCurrentOverlays(OverlayInfo... overlays) {
- return when(mOverlayManager.getOverlayInfosForTarget(eq("android"), anyInt()))
- .thenReturn(Arrays.asList(overlays));
+ try {
+ return when(mOverlayManager.getOverlayInfosForTarget(eq("android"), anyInt()))
+ .thenReturn(Arrays.asList(overlays));
+ } catch (RemoteException re) {
+ return new ArrayList();
+ }
}
@Test
@@ -146,6 +153,15 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
}
private static OverlayInfo createFakeOverlay(String pkg, boolean enabled) {
- return new OverlayInfo(pkg, DisplayCutout.EMULATION_OVERLAY_CATEGORY, enabled);
+ final int state = (enabled) ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED;
+
+ return new OverlayInfo(pkg /* packageName */,
+ pkg + ".target" /* targetPackageName */,
+ DisplayCutout.EMULATION_OVERLAY_CATEGORY /* category */,
+ pkg + ".baseCodePath" /* baseCodePath */,
+ state /* state */,
+ 0 /* userId */,
+ 0 /* priority */,
+ true /* isStatic */);
}
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
index 47cdd35f6f6..19ffdc6d731 100644
--- a/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
@@ -16,25 +16,26 @@
package com.android.settings.display;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import androidx.preference.ListPreference;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.wrapper.OverlayManagerWrapper;
import org.junit.Before;
import org.junit.Test;
@@ -44,6 +45,10 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import java.util.Arrays;
+
+import androidx.preference.ListPreference;
+
@RunWith(SettingsRobolectricTestRunner.class)
public class ThemePreferenceControllerTest {
@@ -55,6 +60,8 @@ public class ThemePreferenceControllerTest {
private ApplicationInfo mApplicationInfo;
@Mock
private ListPreference mPreference;
+ @Mock
+ private IOverlayManager mOverlayManager;
private ThemePreferenceController mController;
@@ -67,8 +74,28 @@ public class ThemePreferenceControllerTest {
when(mContext.getString(R.string.default_theme))
.thenReturn(RuntimeEnvironment.application.getString(R.string.default_theme));
- mController =
- spy(new ThemePreferenceController(mContext, mock(OverlayManagerWrapper.class)));
+ when(mContext.getSystemService(Context.OVERLAY_SERVICE)).thenReturn(mOverlayManager);
+ mController = spy(new ThemePreferenceController(mContext, mOverlayManager));
+ }
+
+ @Test
+ public void testAvailable_false() throws Exception {
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
+ new PackageInfo());
+ when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
+ .thenReturn(Arrays.asList(new OverlayInfo("", "", "", "", 0, 0, 0, false)));
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void testAvailable_true() throws Exception {
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
+ new PackageInfo());
+ when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
+ .thenReturn(Arrays.asList(
+ new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true),
+ new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true)));
+ assertThat(mController.isAvailable()).isTrue();
}
@Test
@@ -79,7 +106,7 @@ public class ThemePreferenceControllerTest {
final String themeLabel2 = "Theme2";
final String[] themes = {pkg1, pkg2};
doReturn("pkg1.theme1").when(mController).getCurrentTheme();
- doReturn(themes).when(mController).getAvailableThemes();
+ doReturn(themes).when(mController).getAvailableThemes(false /* currentThemeOnly */);
when(mPackageManager.getApplicationInfo(anyString(), anyInt()).loadLabel(mPackageManager))
.thenReturn(themeLabel1)
.thenReturn(themeLabel2);
@@ -98,7 +125,7 @@ public class ThemePreferenceControllerTest {
final String themeLabel2 = "Theme2";
final String[] themes = {pkg1, pkg2};
doReturn(null).when(mController).getCurrentTheme();
- doReturn(themes).when(mController).getAvailableThemes();
+ doReturn(themes).when(mController).getAvailableThemes(false /* currentThemeOnly */);
when(mPackageManager.getApplicationInfo(anyString(), anyInt()).loadLabel(mPackageManager))
.thenReturn(themeLabel1)
.thenReturn(themeLabel2);
@@ -109,4 +136,32 @@ public class ThemePreferenceControllerTest {
.setSummary(RuntimeEnvironment.application.getString(R.string.default_theme));
verify(mPreference).setValue(null);
}
+
+ @Test
+ public void getCurrentTheme_withEnabledState() throws Exception {
+ OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
+ OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
+ OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
+ OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
+ when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
+ Arrays.asList(info1, info2));
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
+ new PackageInfo());
+
+ assertThat(mController.getCurrentTheme()).isEqualTo(info1.packageName);
+ }
+
+ @Test
+ public void testGetCurrentTheme_withoutEnabledState() throws Exception {
+ OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
+ OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_DISABLED, 0, 0, true);
+ OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
+ OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
+ when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
+ Arrays.asList(info1, info2));
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
+ new PackageInfo());
+
+ assertThat(mController.getCurrentTheme()).isNull();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
index fc8740ef980..163b7c5c43d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/SmartBatteryPreferenceControllerTest.java
@@ -115,4 +115,11 @@ public class SmartBatteryPreferenceControllerTest {
return Settings.Global.getInt(mContentResolver,
Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, ON);
}
+
+ @Test
+ public void isSliceableCorrectKey_returnsTrue() {
+ final SmartBatteryPreferenceController controller =
+ new SmartBatteryPreferenceController(mContext);
+ assertThat(controller.isSliceable()).isTrue();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
index 6e8476c4bb5..4f48b779b6c 100644
--- a/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
@@ -73,4 +73,9 @@ public class AlarmVolumePreferenceControllerTest {
public void getAudioStream_shouldReturnAlarm() {
assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_ALARM);
}
+
+ @Test
+ public void isSliceableCorrectKey_returnsTrue() {
+ assertThat(mController.isSliceable()).isTrue();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index df960d8a912..6b1262a1e2c 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -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;
@@ -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;
@@ -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";
@@ -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);
@@ -112,6 +117,7 @@ public class SettingsSliceProviderTest {
@After
public void cleanUp() {
+ ShadowThreadUtils.reset();
DatabaseTestUtils.clearDb(mContext);
}
@@ -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);
@@ -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 blockedSet = new ArraySet<>();
blockedSet.add(blockedKey);
@@ -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)
@@ -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
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index 5f0bc962476..6d18449e5f8 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -96,8 +96,16 @@ public class SliceBroadcastReceiverTest {
@Test
public void onReceive_toggleChanged() {
final String key = "key";
+ final Uri uri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
insertSpecialCase(key);
+ final ContentResolver resolver = mock(ContentResolver.class);
+ doReturn(resolver).when(mContext).getContentResolver();
// Turn on toggle setting
FakeToggleController fakeToggleController = new FakeToggleController(mContext, key);
fakeToggleController.setChecked(true);
@@ -121,6 +129,7 @@ public class SliceBroadcastReceiverTest {
assertThat(namePair.first).isEqualTo(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME);
assertThat(namePair.second).isEqualTo(fakeToggleController.getPreferenceKey());
+ verify(resolver).notifyChange(uri, null);
assertThat(valuePair.first)
.isEqualTo(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE);
assertThat(valuePair.second).isEqualTo(0);
@@ -150,9 +159,13 @@ public class SliceBroadcastReceiverTest {
assertThat(fakeToggleController.isChecked()).isFalse();
- final Uri expectedUri = SliceBuilderUtils.getUri(
- SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key, false);
- verify(resolver).notifyChange(eq(expectedUri), eq(null));
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
+ verify(resolver).notifyChange(expectedUri, null);
}
@Test
@@ -183,6 +196,14 @@ public class SliceBroadcastReceiverTest {
@Test
public void onReceive_sliderChanged() {
final String key = "key";
+ final Uri uri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
+ final ContentResolver resolver = mock(ContentResolver.class);
+ doReturn(resolver).when(mContext).getContentResolver();
final int position = FakeSliderController.MAX_STEPS - 1;
final int oldPosition = FakeSliderController.MAX_STEPS;
mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
@@ -213,6 +234,7 @@ public class SliceBroadcastReceiverTest {
assertThat(namePair.first).isEqualTo(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME);
assertThat(namePair.second).isEqualTo(key);
+ verify(resolver).notifyChange(uri, null);
assertThat(valuePair.first)
.isEqualTo(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE);
assertThat(valuePair.second).isEqualTo(position);
@@ -286,8 +308,12 @@ public class SliceBroadcastReceiverTest {
// Check the value is the same and the Uri has been notified.
assertThat(fakeToggleController.isChecked()).isTrue();
- final Uri expectedUri = SliceBuilderUtils.getUri(
- SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key, false);
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
verify(resolver).notifyChange(eq(expectedUri), eq(null));
}
@@ -323,8 +349,12 @@ public class SliceBroadcastReceiverTest {
// Check position is the same and the Uri has been notified.
assertThat(fakeSliderController.getSliderPosition()).isEqualTo(oldPosition);
- final Uri expectedUri = SliceBuilderUtils.getUri(
- SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key, false);
+ final Uri expectedUri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(key)
+ .build();
verify(resolver).notifyChange(eq(expectedUri), eq(null));
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowThreadUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowThreadUtils.java
index 6b0411e9ab0..9513098e862 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowThreadUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowThreadUtils.java
@@ -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();
@@ -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;
+ }
+
}
diff --git a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
index 56552132515..96ffe23fd39 100644
--- a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContextWrapper;
+import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -33,9 +34,6 @@ import android.content.pm.PackageManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import androidx.preference.ListPreference;
-
-import com.android.settings.wrapper.OverlayManagerWrapper;
import org.junit.Before;
import org.junit.Test;
@@ -44,18 +42,20 @@ import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
+import androidx.preference.ListPreference;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ThemePreferenceControllerTest {
- private OverlayManagerWrapper mMockOverlayManager;
+ private IOverlayManager mMockOverlayManager;
private ContextWrapper mContext;
private ThemePreferenceController mPreferenceController;
private PackageManager mMockPackageManager;
@Before
public void setup() {
- mMockOverlayManager = mock(OverlayManagerWrapper.class);
+ mMockOverlayManager = mock(IOverlayManager.class);
mMockPackageManager = mock(PackageManager.class);
mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()) {
@Override
@@ -69,9 +69,9 @@ public class ThemePreferenceControllerTest {
@Test
public void testUpdateState() throws Exception {
OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
- "", "", OverlayInfo.STATE_ENABLED, 0, 0, true);
+ OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
- "", "", 0, 0, 0, true);
+ OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> {
ApplicationInfo info = mock(ApplicationInfo.class);
if ("com.android.Theme1".equals(inv.getArguments()[0])) {
@@ -105,9 +105,9 @@ public class ThemePreferenceControllerTest {
@Test
public void testUpdateState_withStaticOverlay() throws Exception {
OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
- "", "", OverlayInfo.STATE_ENABLED, 0, 0, true);
+ OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
- "", "", OverlayInfo.STATE_ENABLED, 0, 0, true);
+ OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> {
ApplicationInfo info = mock(ApplicationInfo.class);
if ("com.android.Theme1".equals(inv.getArguments()[0])) {
@@ -140,29 +140,10 @@ public class ThemePreferenceControllerTest {
verify(pref).setValue(eq("com.android.Theme2"));
}
- @Test
- public void testAvailable_false() throws Exception {
- when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
- new PackageInfo());
- when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
- .thenReturn(list(new OverlayInfo("", "", "", "", 0, 0, 0, false)));
- assertThat(mPreferenceController.isAvailable()).isFalse();
- }
-
- @Test
- public void testAvailable_true() throws Exception {
- when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
- new PackageInfo());
- when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
- .thenReturn(list(new OverlayInfo("", "", "", "", 0, 0, 0, true),
- new OverlayInfo("", "", "", "", 0, 0, 0, true)));
- assertThat(mPreferenceController.isAvailable()).isTrue();
- }
-
- private ArrayList list(OverlayInfo... infos) {
- ArrayList list = new ArrayList<>();
+ private ArrayList list(OverlayInfo... infos) {
+ ArrayList list = new ArrayList<>();
for (OverlayInfo info : infos) {
- list.add(new OverlayManagerWrapper.OverlayInfo(info));
+ list.add(info);
}
return list;
}