Allow GridBuilder to specify a top-level content intent
Bug: 68378574
Test: manual, check weather / contact / gallery slices
Check that weather is tappable
Change-Id: If10c48a05c0991b371887ee167799db6a5c7641d
diff --git a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
index e692ca0..0ce0190 100644
--- a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
+++ b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
@@ -124,7 +124,11 @@
}
private Slice createWeather(Uri sliceUri) {
+ SliceAction primaryAction = new SliceAction(getBroadcastIntent(ACTION_TOAST,
+ "open weather app"), Icon.createWithResource(getContext(), R.drawable.weather_1),
+ "Weather is happening!");
return new GridBuilder(getContext(), sliceUri)
+ .setPrimaryAction(primaryAction)
.addCell(cb -> cb
.addLargeImage(Icon.createWithResource(getContext(), R.drawable.weather_1))
.addText("MON")
diff --git a/slices/builders/api/current.txt b/slices/builders/api/current.txt
index 21cfaf5..7d9d54a 100644
--- a/slices/builders/api/current.txt
+++ b/slices/builders/api/current.txt
@@ -8,6 +8,7 @@
method public androidx.app.slice.builders.GridBuilder addSeeMoreAction(android.app.PendingIntent);
method public androidx.app.slice.builders.GridBuilder addSeeMoreCell(androidx.app.slice.builders.GridBuilder.CellBuilder);
method public androidx.app.slice.builders.GridBuilder addSeeMoreCell(java.util.function.Consumer<androidx.app.slice.builders.GridBuilder.CellBuilder>);
+ method public androidx.app.slice.builders.GridBuilder setPrimaryAction(androidx.app.slice.builders.SliceAction);
}
public static final class GridBuilder.CellBuilder extends androidx.app.slice.builders.TemplateSliceBuilder {
diff --git a/slices/builders/src/main/java/androidx/app/slice/builders/GridBuilder.java b/slices/builders/src/main/java/androidx/app/slice/builders/GridBuilder.java
index 0dff405..c3fc27a 100644
--- a/slices/builders/src/main/java/androidx/app/slice/builders/GridBuilder.java
+++ b/slices/builders/src/main/java/androidx/app/slice/builders/GridBuilder.java
@@ -179,6 +179,14 @@
return this;
}
+ /**
+ * Sets the intent to send when the slice is activated.
+ */
+ @NonNull
+ public GridBuilder setPrimaryAction(@NonNull SliceAction action) {
+ mImpl.setPrimaryAction(action);
+ return this;
+ }
/**
* @hide
diff --git a/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilder.java b/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilder.java
index 302e1b3..d15dba5 100644
--- a/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilder.java
+++ b/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilder.java
@@ -26,6 +26,7 @@
import android.support.annotation.RestrictTo;
import androidx.app.slice.Slice;
+import androidx.app.slice.builders.SliceAction;
/**
* @hide
@@ -70,6 +71,11 @@
void addSeeMoreAction(PendingIntent intent);
/**
+ * Sets the action to be invoked if the user taps on the main content of the template.
+ */
+ void setPrimaryAction(SliceAction action);
+
+ /**
* Builds a standalone slice of this grid builder (i.e. not contained within a List).
*/
Slice buildIndividual();
diff --git a/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderBasicImpl.java b/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderBasicImpl.java
index 67bbfa1..dce8b9f 100644
--- a/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderBasicImpl.java
+++ b/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderBasicImpl.java
@@ -27,6 +27,7 @@
import androidx.app.slice.Slice;
import androidx.app.slice.SliceSpec;
+import androidx.app.slice.builders.SliceAction;
/**
@@ -77,6 +78,12 @@
/**
*/
@Override
+ public void setPrimaryAction(SliceAction action) {
+ }
+
+ /**
+ */
+ @Override
public Slice buildIndividual() {
// Empty slice, nothing useful from a grid to basic.
return getBuilder().build();
diff --git a/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderListV1Impl.java b/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderListV1Impl.java
index fe755bd..4d2ec07 100644
--- a/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderListV1Impl.java
+++ b/slices/builders/src/main/java/androidx/app/slice/builders/impl/GridBuilderListV1Impl.java
@@ -21,6 +21,8 @@
import static android.app.slice.Slice.HINT_LIST_ITEM;
import static android.app.slice.Slice.HINT_PARTIAL;
import static android.app.slice.Slice.HINT_SEE_MORE;
+import static android.app.slice.Slice.HINT_SHORTCUT;
+import static android.app.slice.Slice.HINT_TITLE;
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
import android.app.PendingIntent;
@@ -32,6 +34,7 @@
import androidx.app.slice.Slice;
import androidx.app.slice.SliceSpec;
+import androidx.app.slice.builders.SliceAction;
/**
* @hide
@@ -39,6 +42,8 @@
@RestrictTo(LIBRARY)
public class GridBuilderListV1Impl extends TemplateBuilderImpl implements GridBuilder {
+ private SliceAction mPrimaryAction;
+
/**
*/
public GridBuilderListV1Impl(@NonNull Slice.Builder builder, SliceSpec spec) {
@@ -50,6 +55,10 @@
@Override
public void apply(Slice.Builder builder) {
builder.addHints(HINT_HORIZONTAL, HINT_LIST_ITEM);
+ if (mPrimaryAction != null) {
+ Slice.Builder sb = new Slice.Builder(builder).addHints(HINT_SHORTCUT, HINT_TITLE);
+ builder.addSubSlice(mPrimaryAction.buildSlice(sb));
+ }
}
/**
@@ -96,10 +105,23 @@
/**
*/
@Override
+ public void setPrimaryAction(SliceAction action) {
+ mPrimaryAction = action;
+ }
+
+ /**
+ */
+ @Override
public Slice buildIndividual() {
- return new Slice.Builder(getBuilder()).addHints(HINT_HORIZONTAL, HINT_LIST_ITEM)
- .addSubSlice(getBuilder()
- .addHints(HINT_HORIZONTAL, HINT_LIST_ITEM).build()).build();
+ Slice.Builder sb = new Slice.Builder(getBuilder())
+ .addHints(HINT_HORIZONTAL, HINT_LIST_ITEM);
+ sb.addSubSlice(getBuilder().addHints(HINT_HORIZONTAL, HINT_LIST_ITEM).build());
+ if (mPrimaryAction != null) {
+ Slice.Builder actionBuilder = new Slice.Builder(getBuilder())
+ .addHints(HINT_SHORTCUT, HINT_TITLE);
+ sb.addSubSlice(mPrimaryAction.buildSlice(actionBuilder));
+ }
+ return sb.build();
}
/**
diff --git a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java
index d4551ef..ca24c98 100644
--- a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java
+++ b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java
@@ -98,7 +98,11 @@
}
private Slice createWeather(Uri sliceUri) {
+ SliceAction primaryAction = new SliceAction(getBroadcastIntent(ACTION_TOAST,
+ "open weather app"), Icon.createWithResource(getContext(), R.drawable.weather_1),
+ "Weather is happening!");
GridBuilder b = new GridBuilder(getContext(), sliceUri);
+ b.setPrimaryAction(primaryAction);
return b.addCell(new GridBuilder.CellBuilder(b)
.addLargeImage(Icon.createWithResource(getContext(), R.drawable.weather_1))
.addText("MON")
diff --git a/slices/view/src/main/java/androidx/app/slice/widget/GridContent.java b/slices/view/src/main/java/androidx/app/slice/widget/GridContent.java
index 9569dc0..794187d 100644
--- a/slices/view/src/main/java/androidx/app/slice/widget/GridContent.java
+++ b/slices/view/src/main/java/androidx/app/slice/widget/GridContent.java
@@ -16,6 +16,9 @@
package androidx.app.slice.widget;
+import static android.app.slice.Slice.HINT_ACTIONS;
+import static android.app.slice.Slice.HINT_SHORTCUT;
+import static android.app.slice.Slice.HINT_TITLE;
import static android.app.slice.Slice.SUBTYPE_COLOR;
import static android.app.slice.SliceItem.FORMAT_ACTION;
import static android.app.slice.SliceItem.FORMAT_IMAGE;
@@ -24,6 +27,7 @@
import static android.app.slice.SliceItem.FORMAT_TEXT;
import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
+import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import java.util.ArrayList;
@@ -40,8 +44,9 @@
public class GridContent {
private boolean mAllImages;
- public SliceItem mColorItem;
- public ArrayList<CellContent> mGridContent = new ArrayList<>();
+ private SliceItem mColorItem;
+ private SliceItem mPrimaryAction;
+ private ArrayList<CellContent> mGridContent = new ArrayList<>();
public GridContent(SliceItem gridItem) {
populate(gridItem);
@@ -58,9 +63,13 @@
public boolean populate(SliceItem gridItem) {
reset();
mColorItem = SliceQuery.findSubtype(gridItem, FORMAT_INT, SUBTYPE_COLOR);
+ String[] hints = new String[] {HINT_SHORTCUT, HINT_TITLE};
+ mPrimaryAction = SliceQuery.find(gridItem, FORMAT_SLICE, hints,
+ new String[] {HINT_ACTIONS} /* nonHints */);
mAllImages = true;
if (FORMAT_SLICE.equals(gridItem.getFormat())) {
List<SliceItem> items = gridItem.getSlice().getItems();
+ items = filterInvalidItems(items);
// Check if it it's only one item that is a slice
if (items.size() == 1 && items.get(0).getFormat().equals(FORMAT_SLICE)) {
items = items.get(0).getSlice().getItems();
@@ -99,6 +108,14 @@
}
/**
+ * @return the content intent item for this grid.
+ */
+ @Nullable
+ public SliceItem getContentIntent() {
+ return mPrimaryAction;
+ }
+
+ /**
* @return whether this grid has content that is valid to display.
*/
public boolean isValid() {
@@ -112,6 +129,17 @@
return mAllImages;
}
+ private List<SliceItem> filterInvalidItems(List<SliceItem> items) {
+ List<SliceItem> filteredItems = new ArrayList<>();
+ for (int i = 0; i < items.size(); i++) {
+ SliceItem item = items.get(i);
+ if (!item.hasHint(HINT_SHORTCUT)) {
+ filteredItems.add(item);
+ }
+ }
+ return filteredItems;
+ }
+
/**
* Extracts information required to present content in a cell.
* @hide
@@ -130,7 +158,8 @@
*/
public boolean populate(SliceItem cellItem) {
final String format = cellItem.getFormat();
- if (FORMAT_SLICE.equals(format) || FORMAT_ACTION.equals(format)) {
+ if (!cellItem.hasHint(HINT_SHORTCUT)
+ && (FORMAT_SLICE.equals(format) || FORMAT_ACTION.equals(format))) {
List<SliceItem> items = cellItem.getSlice().getItems();
// If we've only got one item that's a slice / action use those items instead
if (items.size() == 1 && (FORMAT_ACTION.equals(items.get(0).getFormat())
diff --git a/slices/view/src/main/java/androidx/app/slice/widget/GridRowView.java b/slices/view/src/main/java/androidx/app/slice/widget/GridRowView.java
index 6b0ae5a..f837713 100644
--- a/slices/view/src/main/java/androidx/app/slice/widget/GridRowView.java
+++ b/slices/view/src/main/java/androidx/app/slice/widget/GridRowView.java
@@ -162,6 +162,13 @@
}
private void populateViews(GridContent gc) {
+ if (gc.getContentIntent() != null) {
+ EventInfo info = new EventInfo(getMode(), EventInfo.ACTION_TYPE_CONTENT,
+ EventInfo.ROW_TYPE_GRID, mRowIndex);
+ Pair<SliceItem, EventInfo> tagItem = new Pair(gc.getContentIntent(), info);
+ mViewContainer.setTag(tagItem);
+ makeClickable(mViewContainer);
+ }
mIsAllImages = gc.isAllImages();
ArrayList<GridContent.CellContent> cells = gc.getGridContent();
final int max = mIsAllImages ? MAX_IMAGES : MAX_ALL;