summaryrefslogtreecommitdiff
path: root/androidx/app/slice/widget/ListContent.java
diff options
context:
space:
mode:
Diffstat (limited to 'androidx/app/slice/widget/ListContent.java')
-rw-r--r--androidx/app/slice/widget/ListContent.java187
1 files changed, 187 insertions, 0 deletions
diff --git a/androidx/app/slice/widget/ListContent.java b/androidx/app/slice/widget/ListContent.java
new file mode 100644
index 00000000..86e9409b
--- /dev/null
+++ b/androidx/app/slice/widget/ListContent.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2017 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 androidx.app.slice.widget;
+
+import static android.app.slice.Slice.HINT_ACTIONS;
+import static android.app.slice.Slice.HINT_LIST;
+import static android.app.slice.Slice.HINT_LIST_ITEM;
+import static android.app.slice.Slice.SUBTYPE_COLOR;
+import static android.app.slice.SliceItem.FORMAT_ACTION;
+import static android.app.slice.SliceItem.FORMAT_INT;
+import static android.app.slice.SliceItem.FORMAT_SLICE;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.app.slice.Slice;
+import androidx.app.slice.SliceItem;
+import androidx.app.slice.core.SliceHints;
+import androidx.app.slice.core.SliceQuery;
+
+/**
+ * Extracts information required to present content in a list format from a slice.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class ListContent {
+
+ private SliceItem mColorItem;
+ private SliceItem mSummaryItem;
+ private ArrayList<SliceItem> mRowItems = new ArrayList<>();
+ private boolean mHasHeader;
+
+ public ListContent(Slice slice) {
+ populate(slice);
+ }
+
+ /**
+ * Resets the content.
+ */
+ public void reset() {
+ mColorItem = null;
+ mSummaryItem = null;
+ mRowItems.clear();
+ mHasHeader = false;
+ }
+
+ /**
+ * @return whether this row has content that is valid to display.
+ */
+ public boolean populate(Slice slice) {
+ reset();
+ mColorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
+ // Find summary
+ SliceItem summaryItem = getSummaryItem(slice);
+ mSummaryItem = summaryItem;
+ // Filter + create row items
+ List<SliceItem> children = slice.getItems();
+ for (int i = 0; i < children.size(); i++) {
+ final SliceItem child = children.get(i);
+ final String format = child.getFormat();
+ if (!child.hasAnyHints(SliceHints.HINT_SUMMARY, HINT_ACTIONS)
+ && (FORMAT_ACTION.equals(format) || FORMAT_SLICE.equals(format))) {
+ if (!mHasHeader && !child.hasHint(HINT_LIST_ITEM)) {
+ mHasHeader = true;
+ mRowItems.add(0, child);
+ } else {
+ mRowItems.add(child);
+ }
+ }
+ }
+ return isValid();
+ }
+
+ /**
+ * @return whether this list has content that is valid to display.
+ */
+ public boolean isValid() {
+ return mSummaryItem != null
+ || mRowItems.size() > 0;
+ }
+
+ @Nullable
+ public SliceItem getColorItem() {
+ return mColorItem;
+ }
+
+ @Nullable
+ public SliceItem getSummaryItem() {
+ return mSummaryItem;
+ }
+
+ public ArrayList<SliceItem> getRowItems() {
+ return mRowItems;
+ }
+
+ /**
+ * @return whether this list has a header or not.
+ */
+ public boolean hasHeader() {
+ return mHasHeader;
+ }
+
+ /**
+ * @return A slice item of format slice that is hinted to be shown when the slice is in small
+ * format, or is the best option if nothing is appropriately hinted.
+ */
+ private static SliceItem getSummaryItem(@NonNull Slice slice) {
+ List<SliceItem> items = slice.getItems();
+ // See if a summary is specified
+ SliceItem summary = SliceQuery.find(slice, FORMAT_SLICE, SliceHints.HINT_SUMMARY, null);
+ if (summary != null) {
+ return summary;
+ }
+ // Otherwise use the first non-color item and use it if it's a slice
+ SliceItem firstSlice = null;
+ for (int i = 0; i < items.size(); i++) {
+ if (!FORMAT_INT.equals(items.get(i).getFormat())) {
+ firstSlice = items.get(i);
+ break;
+ }
+ }
+ if (firstSlice != null && FORMAT_SLICE.equals(firstSlice.getFormat())) {
+ // Check if this slice is appropriate to use to populate small template
+ if (firstSlice.hasHint(HINT_LIST)) {
+ // Check for header, use that if it exists
+ SliceItem listHeader = SliceQuery.find(firstSlice, FORMAT_SLICE,
+ null,
+ new String[] {
+ HINT_LIST_ITEM, HINT_LIST
+ });
+ if (listHeader != null) {
+ return findFirstSlice(listHeader);
+ } else {
+ // Otherwise use the first list item
+ SliceItem newFirst = firstSlice.getSlice().getItems().get(0);
+ return findFirstSlice(newFirst);
+ }
+ } else {
+ // Not a list, find first slice with non-slice children
+ return findFirstSlice(firstSlice);
+ }
+ }
+ // Fallback, just use this and convert to SliceItem type slice
+ Slice.Builder sb = new Slice.Builder(slice.getUri());
+ Slice s = sb.addSubSlice(slice).build();
+ return s.getItems().get(0);
+ }
+
+ /**
+ * @return Finds the first slice that has non-slice children.
+ */
+ private static SliceItem findFirstSlice(SliceItem slice) {
+ if (!FORMAT_SLICE.equals(slice.getFormat())) {
+ return slice;
+ }
+ List<SliceItem> items = slice.getSlice().getItems();
+ for (int i = 0; i < items.size(); i++) {
+ if (FORMAT_SLICE.equals(items.get(i).getFormat())) {
+ SliceItem childSlice = items.get(i);
+ return findFirstSlice(childSlice);
+ } else {
+ // Doesn't have slice children so return it
+ return slice;
+ }
+ }
+ // Slices all the way down, just return it
+ return slice;
+ }
+}