Added support for hostExtra to ListBuilder
Test: manual on phone using /tts slice in SliceBrowser
Fixes: b/162543846
Relnote: Added new API ListBuilder#setHostExtra and SliceMetadata#getHostExtras to save and extract additional information for host from slice.
Change-Id: Ib07683a36ee66e722af0bc873837fdc373c5905f
diff --git a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
index 690140f..37b2fde 100644
--- a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
+++ b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
@@ -35,6 +35,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
+import android.speech.tts.TextToSpeech;
import android.util.ArrayMap;
import android.util.Log;
import android.util.TypedValue;
@@ -67,6 +68,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
/**
* Example use of SliceView. Uses a search bar to select/auto-complete a slice uri which is
@@ -88,6 +90,7 @@
private LiveData<Slice> mSliceLiveData;
private SliceView mSliceView;
private SharedPreferences mSharedPreferences;
+ private TextToSpeech mTextToSpeech;
// Mode menu
private int mSelectedMode;
@@ -145,6 +148,8 @@
return false;
}
});
+ mTextToSpeech = new TextToSpeech(getApplicationContext(), status -> {
+ });
mSharedPreferences = getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
@@ -357,6 +362,11 @@
}
mShowingSerialized = false;
mSliceView.setSlice(slice);
+ Bundle hostExtras = SliceMetadata.from(this, slice).getHostExtras();
+ if (hostExtras.getString("tts") != null) {
+ mTextToSpeech.setLanguage(Locale.ENGLISH);
+ mTextToSpeech.speak(hostExtras.getString("tts"), TextToSpeech.QUEUE_FLUSH, null);
+ }
});
}
diff --git a/slices/builders/api/current.txt b/slices/builders/api/current.txt
index 2274a73..c4633a5 100644
--- a/slices/builders/api/current.txt
+++ b/slices/builders/api/current.txt
@@ -38,6 +38,7 @@
method public androidx.slice.builders.ListBuilder addSelection(androidx.slice.builders.SelectionBuilder);
method public androidx.slice.builders.ListBuilder setAccentColor(@ColorInt int);
method public androidx.slice.builders.ListBuilder setHeader(androidx.slice.builders.ListBuilder.HeaderBuilder);
+ method public androidx.slice.builders.ListBuilder setHostExtra(String, String);
method public androidx.slice.builders.ListBuilder setIsError(boolean);
method public androidx.slice.builders.ListBuilder setKeywords(java.util.Set<java.lang.String!>!);
method public androidx.slice.builders.ListBuilder setLayoutDirection(int);
diff --git a/slices/builders/api/public_plus_experimental_current.txt b/slices/builders/api/public_plus_experimental_current.txt
index 2274a73..c4633a5 100644
--- a/slices/builders/api/public_plus_experimental_current.txt
+++ b/slices/builders/api/public_plus_experimental_current.txt
@@ -38,6 +38,7 @@
method public androidx.slice.builders.ListBuilder addSelection(androidx.slice.builders.SelectionBuilder);
method public androidx.slice.builders.ListBuilder setAccentColor(@ColorInt int);
method public androidx.slice.builders.ListBuilder setHeader(androidx.slice.builders.ListBuilder.HeaderBuilder);
+ method public androidx.slice.builders.ListBuilder setHostExtra(String, String);
method public androidx.slice.builders.ListBuilder setIsError(boolean);
method public androidx.slice.builders.ListBuilder setKeywords(java.util.Set<java.lang.String!>!);
method public androidx.slice.builders.ListBuilder setLayoutDirection(int);
diff --git a/slices/builders/api/restricted_current.txt b/slices/builders/api/restricted_current.txt
index 0d562805..ecd0dc5 100644
--- a/slices/builders/api/restricted_current.txt
+++ b/slices/builders/api/restricted_current.txt
@@ -38,6 +38,7 @@
method public androidx.slice.builders.ListBuilder addSelection(androidx.slice.builders.SelectionBuilder);
method public androidx.slice.builders.ListBuilder setAccentColor(@ColorInt int);
method public androidx.slice.builders.ListBuilder setHeader(androidx.slice.builders.ListBuilder.HeaderBuilder);
+ method public androidx.slice.builders.ListBuilder setHostExtra(String, String);
method public androidx.slice.builders.ListBuilder setIsError(boolean);
method public androidx.slice.builders.ListBuilder setKeywords(java.util.Set<java.lang.String!>!);
method public androidx.slice.builders.ListBuilder setLayoutDirection(int);
diff --git a/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
index 03b74fc..fe62480 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
@@ -381,6 +381,19 @@
return this;
}
+
+ /**
+ * Sets additional information to be passed to the host of the slice.
+ *
+ * @param key The name of the extra data
+ * @param value The String data value
+ */
+ @NonNull
+ public ListBuilder setHostExtra(@NonNull String key, @NonNull String value) {
+ mImpl.setHostExtra(key, value);
+ return this;
+ }
+
/**
* If all content in a slice cannot be shown, the row added here may be displayed where the
* content is cut off. This row should have an affordance to take the user to an activity to
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java
index 62fcc98..0aff93b 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java
@@ -21,6 +21,7 @@
import android.app.PendingIntent;
import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
@@ -140,5 +141,13 @@
* Sets the desired layout direction for the content in this slice.
*/
void setLayoutDirection(int layoutDirection);
+
+ /**
+ * Sets additional information to be passed to the host of the slice.
+ *
+ * @param key The name of the extra data
+ * @param value The String data value
+ */
+ void setHostExtra(@NonNull String key, @NonNull String value);
}
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java
index 4fad6d9..fb63466 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java
@@ -22,15 +22,19 @@
import static android.app.slice.Slice.HINT_TTL;
import static android.app.slice.Slice.SUBTYPE_COLOR;
import static android.app.slice.Slice.SUBTYPE_LAYOUT_DIRECTION;
+import static android.app.slice.SliceItem.FORMAT_BUNDLE;
import static android.app.slice.SliceItem.FORMAT_TEXT;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import static androidx.slice.builders.ListBuilder.INFINITY;
+import static androidx.slice.core.SliceHints.SUBTYPE_HOST_EXTRAS;
import static androidx.slice.core.SliceHints.SUBTYPE_MILLIS;
import android.app.PendingIntent;
+import android.os.Bundle;
import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
@@ -63,6 +67,7 @@
private CharSequence mSubtitle;
private SliceAction mSliceAction;
private IconCompat mIconCompat;
+ private Bundle mHostExtras;
/**
*/
@@ -237,6 +242,14 @@
getBuilder().addInt(layoutDirection, SUBTYPE_LAYOUT_DIRECTION);
}
+ @Override
+ public void setHostExtra(@NonNull String key, @NonNull String value) {
+ if (mHostExtras == null) {
+ mHostExtras = new Bundle();
+ }
+ mHostExtras.putString(key, value);
+ }
+
/**
*/
@Override
@@ -271,6 +284,11 @@
if (mIconCompat != null) {
builder.addIcon(mIconCompat, null, new String[] { HINT_TITLE });
}
+
+ if (mHostExtras != null) {
+ slice.addItem(
+ new SliceItem(mHostExtras, FORMAT_BUNDLE, SUBTYPE_HOST_EXTRAS, new String[0]));
+ }
builder.addSubSlice(slice.build());
}
}
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java
index 83f1662..a857830 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderImpl.java
@@ -34,6 +34,7 @@
import static android.app.slice.Slice.SUBTYPE_RANGE;
import static android.app.slice.Slice.SUBTYPE_VALUE;
import static android.app.slice.SliceItem.FORMAT_ACTION;
+import static android.app.slice.SliceItem.FORMAT_BUNDLE;
import static android.app.slice.SliceItem.FORMAT_SLICE;
import static android.app.slice.SliceItem.FORMAT_TEXT;
@@ -42,12 +43,14 @@
import static androidx.slice.builders.ListBuilder.INFINITY;
import static androidx.slice.builders.ListBuilder.RANGE_MODE_DETERMINATE;
import static androidx.slice.core.SliceHints.HINT_END_OF_SECTION;
+import static androidx.slice.core.SliceHints.SUBTYPE_HOST_EXTRAS;
import static androidx.slice.core.SliceHints.SUBTYPE_MILLIS;
import static androidx.slice.core.SliceHints.SUBTYPE_MIN;
import static androidx.slice.core.SliceHints.SUBTYPE_SELECTION;
import android.app.PendingIntent;
import android.net.Uri;
+import android.os.Bundle;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
@@ -89,6 +92,7 @@
private boolean mFirstRowChecked;
private boolean mIsFirstRowTypeValid;
private boolean mFirstRowHasText;
+ private Bundle mHostExtras;
public ListBuilderImpl(Slice.Builder b, SliceSpec spec) {
this(b, spec, new SystemClock());
@@ -125,6 +129,10 @@
}
getBuilder().addSubSlice(sb.addHints(HINT_KEYWORDS).build());
}
+ if (mHostExtras != null) {
+ builder.addItem(new SliceItem(mHostExtras, FORMAT_BUNDLE, SUBTYPE_HOST_EXTRAS,
+ new String[0]));
+ }
}
/**
@@ -295,6 +303,15 @@
getBuilder().addInt(layoutDirection, SUBTYPE_LAYOUT_DIRECTION);
}
+ @Override
+ public void setHostExtra(@NonNull String key, @NonNull String value) {
+ if (mHostExtras == null) {
+ mHostExtras = new Bundle();
+ }
+ mHostExtras.putString(key, value);
+ }
+
+
/**
* There are some requirements that first row of a list is not a grid row and has some text.
* This method helps check whether first row fulfils these requirements.
diff --git a/slices/core/api/restricted_current.txt b/slices/core/api/restricted_current.txt
index 82062d6..a2f829a 100644
--- a/slices/core/api/restricted_current.txt
+++ b/slices/core/api/restricted_current.txt
@@ -241,6 +241,7 @@
field public static final int RAW_IMAGE_SMALL = 3; // 0x3
field public static final String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
field public static final int SMALL_IMAGE = 1; // 0x1
+ field public static final String SUBTYPE_HOST_EXTRAS = "host_extras";
field public static final String SUBTYPE_MILLIS = "millis";
field public static final String SUBTYPE_MIN = "min";
field public static final String SUBTYPE_SELECTION = "selection";
diff --git a/slices/core/src/main/java/androidx/slice/SliceConvert.java b/slices/core/src/main/java/androidx/slice/SliceConvert.java
index 22a01e6..da18bfa 100644
--- a/slices/core/src/main/java/androidx/slice/SliceConvert.java
+++ b/slices/core/src/main/java/androidx/slice/SliceConvert.java
@@ -17,6 +17,7 @@
import static android.app.slice.SliceItem.FORMAT_ACTION;
+import static android.app.slice.SliceItem.FORMAT_BUNDLE;
import static android.app.slice.SliceItem.FORMAT_IMAGE;
import static android.app.slice.SliceItem.FORMAT_INT;
import static android.app.slice.SliceItem.FORMAT_LONG;
@@ -26,6 +27,7 @@
import android.content.Context;
import android.content.res.Resources;
+import android.os.Bundle;
import android.util.Log;
import androidx.annotation.RequiresApi;
@@ -77,6 +79,9 @@
case FORMAT_LONG:
builder.addLong(item.getLong(), item.getSubType(), item.getHints());
break;
+ case FORMAT_BUNDLE:
+ builder.addBundle((Bundle) item.mObj, item.getSubType(), item.getHints());
+ break;
}
}
return builder.build();
@@ -140,6 +145,10 @@
case FORMAT_LONG:
builder.addLong(item.getLong(), item.getSubType(), item.getHints());
break;
+ case FORMAT_BUNDLE:
+ builder.addItem(new SliceItem(item.getBundle(), item.getFormat(),
+ item.getSubType(), item.getHints()));
+ break;
}
}
return builder.build();
diff --git a/slices/core/src/main/java/androidx/slice/SliceItem.java b/slices/core/src/main/java/androidx/slice/SliceItem.java
index 67e9292..10c87f0 100644
--- a/slices/core/src/main/java/androidx/slice/SliceItem.java
+++ b/slices/core/src/main/java/androidx/slice/SliceItem.java
@@ -17,6 +17,7 @@
package androidx.slice;
import static android.app.slice.SliceItem.FORMAT_ACTION;
+import static android.app.slice.SliceItem.FORMAT_BUNDLE;
import static android.app.slice.SliceItem.FORMAT_IMAGE;
import static android.app.slice.SliceItem.FORMAT_INT;
import static android.app.slice.SliceItem.FORMAT_LONG;
@@ -99,7 +100,7 @@
*/
@RestrictTo(Scope.LIBRARY)
@StringDef({FORMAT_SLICE, FORMAT_TEXT, FORMAT_IMAGE, FORMAT_ACTION, FORMAT_INT,
- FORMAT_LONG, FORMAT_REMOTE_INPUT, FORMAT_LONG})
+ FORMAT_LONG, FORMAT_REMOTE_INPUT, FORMAT_LONG, FORMAT_BUNDLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SliceType {
}
@@ -424,6 +425,8 @@
case FORMAT_LONG:
dest.putLong(OBJ, (Long) mObj);
break;
+ case FORMAT_BUNDLE:
+ dest.putBundle(OBJ, (Bundle) mObj);
}
}
@@ -445,6 +448,8 @@
return in.getInt(OBJ);
case FORMAT_LONG:
return in.getLong(OBJ);
+ case FORMAT_BUNDLE:
+ return in.getBundle(OBJ);
}
throw new RuntimeException("Unsupported type " + type);
}
diff --git a/slices/core/src/main/java/androidx/slice/SliceItemHolder.java b/slices/core/src/main/java/androidx/slice/SliceItemHolder.java
index 504e9a7..9e4a7ac 100644
--- a/slices/core/src/main/java/androidx/slice/SliceItemHolder.java
+++ b/slices/core/src/main/java/androidx/slice/SliceItemHolder.java
@@ -17,6 +17,7 @@
package androidx.slice;
import static android.app.slice.SliceItem.FORMAT_ACTION;
+import static android.app.slice.SliceItem.FORMAT_BUNDLE;
import static android.app.slice.SliceItem.FORMAT_IMAGE;
import static android.app.slice.SliceItem.FORMAT_INT;
import static android.app.slice.SliceItem.FORMAT_LONG;
@@ -25,6 +26,7 @@
import static android.app.slice.SliceItem.FORMAT_TEXT;
import android.app.PendingIntent;
+import android.os.Bundle;
import android.os.Parcelable;
import android.text.Spanned;
@@ -64,6 +66,8 @@
int mInt = 0;
@ParcelField(value = 5, defaultValue = "0")
long mLong = 0;
+ @ParcelField(value = 6, defaultValue = "null")
+ Bundle mBundle = null;
@NonParcelField
private SliceItemPool mPool;
@@ -109,6 +113,9 @@
case FORMAT_LONG:
mLong = (Long) mObj;
break;
+ case FORMAT_BUNDLE:
+ mBundle = (Bundle) mObj;
+
}
if (SliceItemHolder.sHandler != null) {
SliceItemHolder.sHandler.handle(this, format);
@@ -141,6 +148,8 @@
return mInt;
case FORMAT_LONG:
return mLong;
+ case FORMAT_BUNDLE:
+ return mBundle;
default:
throw new IllegalArgumentException("Unrecognized format " + format);
}
diff --git a/slices/core/src/main/java/androidx/slice/core/SliceHints.java b/slices/core/src/main/java/androidx/slice/core/SliceHints.java
index c85391a..460ec07 100644
--- a/slices/core/src/main/java/androidx/slice/core/SliceHints.java
+++ b/slices/core/src/main/java/androidx/slice/core/SliceHints.java
@@ -119,6 +119,8 @@
*/
public static final String SUBTYPE_SELECTION_OPTION_VALUE = "selection_option_value";
+ public static final String SUBTYPE_HOST_EXTRAS = "host_extras";
+
@IntDef({
LARGE_IMAGE, SMALL_IMAGE, ICON_IMAGE, RAW_IMAGE_SMALL, RAW_IMAGE_LARGE, UNKNOWN_IMAGE
})
diff --git a/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java b/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java
index 18ccdc9..4e52c6b 100644
--- a/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java
+++ b/slices/test/src/main/java/androidx/slice/test/SampleSliceProvider.java
@@ -81,6 +81,7 @@
public static final String EXTRA_TOAST_MESSAGE = "com.example.androidx.extra.TOAST_MESSAGE";
public static final String ACTION_TOAST_RANGE_VALUE =
"com.example.androidx.slice.action.TOAST_RANGE_VALUE";
+ public static final String ACTION_PLAY_TTS = "com.example.androidx.slice.action.PLAY_TTS";
public static final String[] URI_PATHS = {
"message",
@@ -118,7 +119,8 @@
"longtext",
"loading",
"selection",
- "notification"
+ "notification",
+ "tts"
};
/**
@@ -228,6 +230,8 @@
return createSelectionSlice(sliceUri);
case "/notification":
return createNotificationSlice(sliceUri);
+ case "/tts":
+ return createTtsSlice(sliceUri);
}
Log.w(TAG, String.format("Unknown uri: %s", sliceUri));
return null;
@@ -1392,6 +1396,24 @@
.build();
}
+ private Slice createTtsSlice(Uri sliceUri) {
+ Slice slice = new ListBuilder(getContext(), sliceUri, INFINITY)
+ // Attach additional information for host. Depending on the host apps, this
+ // information might or might not be used.
+ // In this case, SliceBrowser is customized to play TTS when binding the slice.
+ .setHostExtra("tts", "hello world")
+ .addRow(
+ new RowBuilder().setPrimaryAction(
+ SliceAction.create(
+ getBroadcastIntent(ACTION_PLAY_TTS, null),
+ IconCompat.createWithResource(getContext(),
+ R.drawable.message),
+ ICON_IMAGE, "TTS"
+ )
+ ).setTitle("Text to speech").setSubtitle("Play")).build();
+ return slice;
+ }
+
private PendingIntent getIntent(String action) {
Intent intent = new Intent(action);
PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
diff --git a/slices/test/src/main/java/androidx/slice/test/SliceBroadcastReceiver.java b/slices/test/src/main/java/androidx/slice/test/SliceBroadcastReceiver.java
index 78f0ffd..524f868 100644
--- a/slices/test/src/main/java/androidx/slice/test/SliceBroadcastReceiver.java
+++ b/slices/test/src/main/java/androidx/slice/test/SliceBroadcastReceiver.java
@@ -38,7 +38,6 @@
*/
@RequiresApi(19)
public class SliceBroadcastReceiver extends BroadcastReceiver {
-
@SuppressWarnings("deprecation")
@Override
public void onReceive(final Context context, Intent i) {
@@ -76,6 +75,9 @@
context.getContentResolver().notifyChange(getUri("inputrange", context), null);
context.getContentResolver().notifyChange(getUri("richinputrange", context), null);
break;
+ case SampleSliceProvider.ACTION_PLAY_TTS:
+ context.getContentResolver().notifyChange(getUri("tts", context), null);
+ break;
}
}
}
diff --git a/slices/view/api/current.txt b/slices/view/api/current.txt
index 8ed32c3..43d96ee 100644
--- a/slices/view/api/current.txt
+++ b/slices/view/api/current.txt
@@ -5,6 +5,7 @@
method public static androidx.slice.SliceMetadata! from(android.content.Context, androidx.slice.Slice);
method public long getExpiry();
method public int getHeaderType();
+ method public android.os.Bundle getHostExtras();
method public android.app.PendingIntent? getInputRangeAction();
method public long getLastUpdatedTime();
method public int getLoadingState();
diff --git a/slices/view/api/public_plus_experimental_current.txt b/slices/view/api/public_plus_experimental_current.txt
index 8ed32c3..43d96ee 100644
--- a/slices/view/api/public_plus_experimental_current.txt
+++ b/slices/view/api/public_plus_experimental_current.txt
@@ -5,6 +5,7 @@
method public static androidx.slice.SliceMetadata! from(android.content.Context, androidx.slice.Slice);
method public long getExpiry();
method public int getHeaderType();
+ method public android.os.Bundle getHostExtras();
method public android.app.PendingIntent? getInputRangeAction();
method public long getLastUpdatedTime();
method public int getLoadingState();
diff --git a/slices/view/api/restricted_current.txt b/slices/view/api/restricted_current.txt
index 42d75d4..e21df42e 100644
--- a/slices/view/api/restricted_current.txt
+++ b/slices/view/api/restricted_current.txt
@@ -5,6 +5,7 @@
method public static androidx.slice.SliceMetadata! from(android.content.Context, androidx.slice.Slice);
method public long getExpiry();
method public int getHeaderType();
+ method public android.os.Bundle getHostExtras();
method public android.app.PendingIntent? getInputRangeAction();
method public long getLastUpdatedTime();
method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.slice.widget.ListContent! getListContent();
diff --git a/slices/view/src/main/java/androidx/slice/SliceMetadata.java b/slices/view/src/main/java/androidx/slice/SliceMetadata.java
index 257963d..de6f132 100644
--- a/slices/view/src/main/java/androidx/slice/SliceMetadata.java
+++ b/slices/view/src/main/java/androidx/slice/SliceMetadata.java
@@ -30,12 +30,14 @@
import static android.app.slice.Slice.SUBTYPE_MAX;
import static android.app.slice.Slice.SUBTYPE_VALUE;
import static android.app.slice.SliceItem.FORMAT_ACTION;
+import static android.app.slice.SliceItem.FORMAT_BUNDLE;
import static android.app.slice.SliceItem.FORMAT_INT;
import static android.app.slice.SliceItem.FORMAT_LONG;
import static android.app.slice.SliceItem.FORMAT_SLICE;
import static android.app.slice.SliceItem.FORMAT_TEXT;
import static androidx.slice.core.SliceHints.HINT_CACHED;
+import static androidx.slice.core.SliceHints.SUBTYPE_HOST_EXTRAS;
import static androidx.slice.core.SliceHints.SUBTYPE_MIN;
import static androidx.slice.widget.EventInfo.ROW_TYPE_PROGRESS;
import static androidx.slice.widget.EventInfo.ROW_TYPE_SLIDER;
@@ -43,6 +45,7 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.text.TextUtils;
import androidx.annotation.IntDef;
@@ -104,6 +107,7 @@
private SliceAction mPrimaryAction;
private List<SliceAction> mSliceActions;
private @EventInfo.SliceRowType int mTemplateType;
+ private final Bundle mHostExtras;
/**
* Create a SliceMetadata object to provide access to some information around the slice and
@@ -136,6 +140,13 @@
if (updatedItem != null) {
mLastUpdated = updatedItem.getLong();
}
+ SliceItem hostExtrasItem = SliceQuery.findSubtype(slice, FORMAT_BUNDLE,
+ SUBTYPE_HOST_EXTRAS);
+ if (hostExtrasItem != null && hostExtrasItem.mObj instanceof Bundle) {
+ mHostExtras = (Bundle) hostExtrasItem.mObj;
+ } else {
+ mHostExtras = Bundle.EMPTY;
+ }
mListContent = new ListContent(slice);
mHeaderContent = mListContent.getHeader();
mTemplateType = mListContent.getHeaderTemplateType();
@@ -247,6 +258,11 @@
return toggles;
}
+ @NonNull
+ public Bundle getHostExtras() {
+ return mHostExtras;
+ }
+
/**
* Sends the intent to adjust the state of the provided toggle action.
*
diff --git a/slices/view/src/main/java/androidx/slice/SliceXml.java b/slices/view/src/main/java/androidx/slice/SliceXml.java
index a952669..55043fe 100644
--- a/slices/view/src/main/java/androidx/slice/SliceXml.java
+++ b/slices/view/src/main/java/androidx/slice/SliceXml.java
@@ -195,6 +195,9 @@
v = parser.getText();
b.addLong(Long.parseLong(v), subtype, hints);
break;
+ case android.app.slice.SliceItem.FORMAT_BUNDLE:
+ // Nothing for now
+ break;
default:
throw new IllegalArgumentException("Unrecognized format " + format);
}
@@ -327,6 +330,9 @@
case android.app.slice.SliceItem.FORMAT_LONG:
serializer.text(String.valueOf(item.getLong()));
break;
+ case android.app.slice.SliceItem.FORMAT_BUNDLE:
+ // Nothing for now
+ break;
default:
throw new IllegalArgumentException("Unrecognized format " + format);
}