Make a few custom slices implement CustomSliceable.

Bug: 80263568
Test: robotests, slice-browser
Change-Id: Id809a347d77448917154c2d1144fd2517e70829a
This commit is contained in:
Fan Zhang
2018-12-05 14:42:53 -08:00
parent bccad4abd8
commit d7fa2fa64e
10 changed files with 119 additions and 95 deletions

View File

@@ -36,8 +36,9 @@ import java.util.List;
public class EmergencyInfoPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin {
public static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
private static final String KEY_EMERGENCY_INFO = "emergency_info";
private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
private static final String PACKAGE_NAME_EMERGENCY = "com.android.emergency";
public EmergencyInfoPreferenceController(Context context) {
@@ -57,7 +58,7 @@ public class EmergencyInfoPreferenceController extends AbstractPreferenceControl
public void updateState(Preference preference) {
UserInfo info = mContext.getSystemService(UserManager.class).getUserInfo(
UserHandle.myUserId());
UserHandle.myUserId());
preference.setSummary(mContext.getString(R.string.emergency_info_summary, info.name));
}

View File

@@ -28,6 +28,7 @@ import android.content.IntentFilter;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.net.Uri;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.util.Log;
@@ -41,69 +42,78 @@ import androidx.slice.builders.SliceAction;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settings.slices.CustomSliceable;
/**
* Utility class to build a Flashlight Slice, and handle all associated actions.
*/
public class FlashlightSliceBuilder {
public class FlashlightSlice implements CustomSliceable {
private static final String TAG = "FlashlightSliceBuilder";
/**
* Action notifying a change on the Flashlight Slice.
*/
public static final String ACTION_FLASHLIGHT_SLICE_CHANGED =
"com.android.settings.flashlight.action.FLASHLIGHT_SLICE_CHANGED";
private static final String TAG = "FlashlightSlice";
/**
* Action broadcasting a change on whether flashlight is on or off.
*/
public static final String ACTION_FLASHLIGHT_CHANGED =
private static final String ACTION_FLASHLIGHT_CHANGED =
"com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
public static final IntentFilter INTENT_FILTER = new IntentFilter(ACTION_FLASHLIGHT_CHANGED);
private final Context mContext;
private FlashlightSliceBuilder() {
public FlashlightSlice(Context context) {
mContext = context;
}
public static Slice getSlice(Context context) {
if (!isFlashlightAvailable(context)) {
@Override
public Slice getSlice() {
if (!isFlashlightAvailable(mContext)) {
return null;
}
final PendingIntent toggleAction = getBroadcastIntent(context);
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
final PendingIntent toggleAction = getBroadcastIntent(mContext);
@ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
final IconCompat icon =
IconCompat.createWithResource(context, R.drawable.ic_signal_flashlight);
return new ListBuilder(context, CustomSliceRegistry.FLASHLIGHT_SLICE_URI,
IconCompat.createWithResource(mContext, R.drawable.ic_signal_flashlight);
return new ListBuilder(mContext, CustomSliceRegistry.FLASHLIGHT_SLICE_URI,
ListBuilder.INFINITY)
.setAccentColor(color)
.addRow(new RowBuilder()
.setTitle(context.getText(R.string.power_flashlight))
.setTitle(mContext.getText(R.string.power_flashlight))
.setTitleItem(icon, ICON_IMAGE)
.setPrimaryAction(
SliceAction.createToggle(toggleAction, null, isFlashlightEnabled(context))))
SliceAction.createToggle(toggleAction, null,
isFlashlightEnabled(mContext))))
.build();
}
/**
* Update the current flashlight status to the boolean value keyed by
* {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
*/
public static void handleUriChange(Context context, Intent intent) {
@Override
public Uri getUri() {
return CustomSliceRegistry.FLASHLIGHT_SLICE_URI;
}
@Override
public IntentFilter getIntentFilter() {
return new IntentFilter(ACTION_FLASHLIGHT_CHANGED);
}
@Override
public void onNotifyChange(Intent intent) {
try {
final String cameraId = getCameraId(context);
final String cameraId = getCameraId(mContext);
if (cameraId != null) {
final boolean state = intent.getBooleanExtra(
EXTRA_TOGGLE_STATE, isFlashlightEnabled(context));
final CameraManager cameraManager = context.getSystemService(CameraManager.class);
EXTRA_TOGGLE_STATE, isFlashlightEnabled(mContext));
final CameraManager cameraManager = mContext.getSystemService(CameraManager.class);
cameraManager.setTorchMode(cameraId, state);
}
} catch (CameraAccessException e) {
Log.e(TAG, "Camera couldn't set torch mode.", e);
}
context.getContentResolver().notifyChange(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, null);
mContext.getContentResolver().notifyChange(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, null);
}
@Override
public Intent getIntent() {
return null;
}
private static String getCameraId(Context context) throws CameraAccessException {
@@ -121,12 +131,6 @@ public class FlashlightSliceBuilder {
return null;
}
private static PendingIntent getBroadcastIntent(Context context) {
final Intent intent = new Intent(ACTION_FLASHLIGHT_SLICE_CHANGED);
intent.setClass(context, SliceBroadcastReceiver.class);
return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
private static boolean isFlashlightAvailable(Context context) {
return Settings.Secure.getInt(

View File

@@ -16,9 +16,12 @@
package com.android.settings.homepage.contextualcards.deviceinfo;
import static com.android.settings.accounts.EmergencyInfoPreferenceController.ACTION_EDIT_EMERGENCY_INFO;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
@@ -27,37 +30,57 @@ import androidx.slice.builders.SliceAction;
import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.CustomSliceable;
// This is a slice helper class for EmergencyInfo
public class EmergencyInfoSlice {
public class EmergencyInfoSlice implements CustomSliceable {
private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
private final Context mContext;
public static Slice getSlice(Context context) {
final ListBuilder listBuilder = new ListBuilder(context,
public EmergencyInfoSlice(Context context) {
mContext = context;
}
@Override
public Slice getSlice() {
final ListBuilder listBuilder = new ListBuilder(mContext,
CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI,
ListBuilder.INFINITY);
listBuilder.addRow(
new ListBuilder.RowBuilder()
.setTitle(context.getText(R.string.emergency_info_title))
.setTitle(mContext.getText(R.string.emergency_info_title))
.setSubtitle(
context.getText(R.string.emergency_info_contextual_card_summary))
.setPrimaryAction(createPrimaryAction(context)));
mContext.getText(R.string.emergency_info_contextual_card_summary))
.setPrimaryAction(createPrimaryAction()));
return listBuilder.build();
}
private static SliceAction createPrimaryAction(Context context) {
PendingIntent pendingIntent =
@Override
public Uri getUri() {
return CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI;
}
@Override
public Intent getIntent() {
return new Intent(ACTION_EDIT_EMERGENCY_INFO);
}
@Override
public void onNotifyChange(Intent intent) {
}
private SliceAction createPrimaryAction() {
final PendingIntent pendingIntent =
PendingIntent.getActivity(
context,
mContext,
0 /* requestCode */,
new Intent(ACTION_EDIT_EMERGENCY_INFO),
getIntent(),
PendingIntent.FLAG_UPDATE_CURRENT);
return SliceAction.createDeeplink(
pendingIntent,
IconCompat.createWithResource(context, R.drawable.empty_icon),
IconCompat.createWithResource(mContext, R.drawable.empty_icon),
ListBuilder.ICON_IMAGE,
context.getText(R.string.emergency_info_title));
mContext.getText(R.string.emergency_info_title));
}
}

View File

@@ -38,29 +38,31 @@ import com.android.settings.R;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBuilderUtils;
/**
* Utility class to build an intent-based Location Slice.
*/
public class LocationSliceBuilder {
public class LocationSlice implements CustomSliceable {
private LocationSliceBuilder() {
private final Context mContext;
public LocationSlice(Context context) {
mContext = context;
}
/**
* Return a Location Slice bound to {@link CustomSliceRegistry#LOCATION_SLICE_URI}.
*/
public static Slice getSlice(Context context) {
final IconCompat icon = IconCompat.createWithResource(context,
@Override
public Slice getSlice() {
final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_signal_location);
final String title = context.getString(R.string.location_settings_title);
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
final PendingIntent primaryAction = getPrimaryAction(context);
final CharSequence title = mContext.getText(R.string.location_settings_title);
@ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
final PendingIntent primaryAction = getPrimaryAction();
final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon,
ListBuilder.ICON_IMAGE, title);
return new ListBuilder(context, CustomSliceRegistry.LOCATION_SLICE_URI,
return new ListBuilder(mContext, CustomSliceRegistry.LOCATION_SLICE_URI,
ListBuilder.INFINITY)
.setAccentColor(color)
.addRow(new RowBuilder()
@@ -70,19 +72,30 @@ public class LocationSliceBuilder {
.build();
}
public static Intent getIntent(Context context) {
final String screenTitle = context.getText(R.string.location_settings_title).toString();
@Override
public Uri getUri() {
return CustomSliceRegistry.LOCATION_SLICE_URI;
}
@Override
public void onNotifyChange(Intent intent) {
}
@Override
public Intent getIntent() {
final String screenTitle = mContext.getText(R.string.location_settings_title).toString();
final Uri contentUri = new Uri.Builder().appendPath(KEY_LOCATION).build();
return SliceBuilderUtils.buildSearchResultPageIntent(context,
return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
LocationSettings.class.getName(), KEY_LOCATION, screenTitle,
MetricsEvent.LOCATION)
.setClassName(context.getPackageName(), SubSettings.class.getName())
.setClassName(mContext.getPackageName(), SubSettings.class.getName())
.setData(contentUri);
}
private static PendingIntent getPrimaryAction(Context context) {
final Intent intent = getIntent(context);
return PendingIntent.getActivity(context, 0 /* requestCode */,
private PendingIntent getPrimaryAction() {
final Intent intent = getIntent();
return PendingIntent.getActivity(mContext, 0 /* requestCode */,
intent, 0 /* flags */);
}
}

View File

@@ -22,13 +22,16 @@ import android.util.ArrayMap;
import androidx.annotation.VisibleForTesting;
import com.android.settings.flashlight.FlashlightSlice;
import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice;
import com.android.settings.homepage.contextualcards.deviceinfo.DeviceInfoSlice;
import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice;
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
import com.android.settings.location.LocationSlice;
import com.android.settings.wifi.WifiSlice;
import java.util.Map;
@@ -106,6 +109,9 @@ public class CustomSliceManager {
mUriMap.put(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI, ConnectedDeviceSlice.class);
mUriMap.put(CustomSliceRegistry.DATA_USAGE_SLICE_URI, DataUsageSlice.class);
mUriMap.put(CustomSliceRegistry.DEVICE_INFO_SLICE_URI, DeviceInfoSlice.class);
mUriMap.put(CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI, EmergencyInfoSlice.class);
mUriMap.put(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, FlashlightSlice.class);
mUriMap.put(CustomSliceRegistry.LOCATION_SLICE_URI, LocationSlice.class);
mUriMap.put(CustomSliceRegistry.LOW_STORAGE_SLICE_URI, LowStorageSlice.class);
mUriMap.put(CustomSliceRegistry.STORAGE_SLICE_URI, StorageSlice.class);
mUriMap.put(CustomSliceRegistry.WIFI_SLICE_URI, WifiSlice.class);

View File

@@ -41,9 +41,6 @@ import androidx.slice.SliceProvider;
import com.android.settings.R;
import com.android.settings.bluetooth.BluetoothSliceBuilder;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.flashlight.FlashlightSliceBuilder;
import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
import com.android.settings.location.LocationSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.SliceBroadcastRelay;
@@ -182,12 +179,6 @@ public class SettingsSliceProvider extends SliceProvider {
} else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
registerIntentToUri(BluetoothSliceBuilder.INTENT_FILTER, sliceUri);
return;
} else if (CustomSliceRegistry.FLASHLIGHT_SLICE_URI.equals(sliceUri)) {
registerIntentToUri(FlashlightSliceBuilder.INTENT_FILTER, sliceUri);
mRegisteredUris.add(sliceUri);
return;
} else if (CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI.equals(sliceUri)) {
return;
}
// Start warming the slice, we expect someone will want it soon.
@@ -240,8 +231,6 @@ public class SettingsSliceProvider extends SliceProvider {
return ZenModeSliceBuilder.getSlice(getContext());
} else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
return BluetoothSliceBuilder.getSlice(getContext());
} else if (CustomSliceRegistry.LOCATION_SLICE_URI.equals(sliceUri)) {
return LocationSliceBuilder.getSlice(getContext());
} else if (CustomSliceRegistry.ENHANCED_4G_SLICE_URI.equals(sliceUri)) {
return FeatureFactory.getFactory(getContext())
.getSlicesFeatureProvider()
@@ -252,10 +241,6 @@ public class SettingsSliceProvider extends SliceProvider {
.getSlicesFeatureProvider()
.getNewWifiCallingSliceHelper(getContext())
.createWifiCallingPreferenceSlice(sliceUri);
} else if (CustomSliceRegistry.FLASHLIGHT_SLICE_URI.equals(sliceUri)) {
return FlashlightSliceBuilder.getSlice(getContext());
} else if (CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI.equals(sliceUri)) {
return EmergencyInfoSlice.getSlice(getContext());
}
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);

View File

@@ -17,7 +17,6 @@
package com.android.settings.slices;
import static com.android.settings.bluetooth.BluetoothSliceBuilder.ACTION_BLUETOOTH_SLICE_CHANGED;
import static com.android.settings.flashlight.FlashlightSliceBuilder.ACTION_FLASHLIGHT_SLICE_CHANGED;
import static com.android.settings.network.telephony.Enhanced4gLteSliceHelper.ACTION_ENHANCED_4G_LTE_CHANGED;
import static com.android.settings.notification.ZenModeSliceBuilder.ACTION_ZEN_MODE_SLICE_CHANGED;
import static com.android.settings.slices.SettingsSliceProvider.ACTION_COPY;
@@ -46,7 +45,6 @@ import com.android.settings.bluetooth.BluetoothSliceBuilder;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.flashlight.FlashlightSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
@@ -108,9 +106,6 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
.getNewWifiCallingSliceHelper(context)
.handleWifiCallingPreferenceChanged(intent);
break;
case ACTION_FLASHLIGHT_SLICE_CHANGED:
FlashlightSliceBuilder.handleUriChange(context, intent);
break;
case ACTION_COPY:
handleCopyAction(context, key, isPlatformSlice);
break;

View File

@@ -24,7 +24,6 @@ import android.util.Log;
import androidx.annotation.Keep;
import com.android.settings.bluetooth.BluetoothSliceBuilder;
import com.android.settings.location.LocationSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
import com.android.settings.overlay.FeatureFactory;
@@ -66,8 +65,6 @@ public class SliceDeepLinkSpringBoard extends Activity {
launchIntent = ZenModeSliceBuilder.getIntent(this /* context */);
} else if (CustomSliceRegistry.BLUETOOTH_URI.equals(sliceUri)) {
launchIntent = BluetoothSliceBuilder.getIntent(this /* context */);
} else if (CustomSliceRegistry.LOCATION_SLICE_URI.equals(sliceUri)) {
launchIntent = LocationSliceBuilder.getIntent(this /* context */);
} else {
final SlicesDatabaseAccessor slicesDatabaseAccessor =
new SlicesDatabaseAccessor(this /* context */);

View File

@@ -42,7 +42,7 @@ import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
public class FlashlightSliceBuilderTest {
public class FlashlightSliceTest {
private Context mContext;
@@ -58,7 +58,7 @@ public class FlashlightSliceBuilderTest {
public void getFlashlightSlice_correctData() {
Settings.Secure.putInt(
mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
final Slice slice = FlashlightSliceBuilder.getSlice(mContext);
final Slice slice = new FlashlightSlice(mContext).getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
final List<SliceAction> toggles = metadata.getToggles();

View File

@@ -24,7 +24,7 @@ import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
public class LocationSliceBuilderTest {
public class LocationSliceTest {
private Context mContext;
@@ -38,7 +38,7 @@ public class LocationSliceBuilderTest {
@Test
public void getLocationSlice_correctSliceContent() {
final Slice LocationSlice = LocationSliceBuilder.getSlice(mContext);
final Slice LocationSlice = new LocationSlice(mContext).getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, LocationSlice);
final List<SliceAction> toggles = metadata.getToggles();