Merge "Get slices libraries closer to a lower minSdk." into pi-preview1-androidx-dev
am: 2f5a0d87a5

Change-Id: I6218413f43a8ebcf5a46c4ce581abe29ff32fb9f
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 786a69e..3d6c47f 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
@@ -268,6 +268,7 @@
     /**
      * Add an input range row to the list builder.
      */
+    @RequiresApi(api = Build.VERSION_CODES.N)
     @NonNull
     public ListBuilder addInputRange(@NonNull Consumer<InputRangeBuilder> c) {
         InputRangeBuilder inputRangeBuilder = new InputRangeBuilder(this);
@@ -287,6 +288,7 @@
     /**
      * Add a range row to the list builder.
      */
+    @RequiresApi(api = Build.VERSION_CODES.N)
     @NonNull
     public ListBuilder addRange(@NonNull Consumer<RangeBuilder> c) {
         RangeBuilder rangeBuilder = new RangeBuilder(this);
diff --git a/slices/core/src/main/java/androidx/slice/ArrayUtils.java b/slices/core/src/main/java/androidx/slice/ArrayUtils.java
index e807114..ef5551f 100644
--- a/slices/core/src/main/java/androidx/slice/ArrayUtils.java
+++ b/slices/core/src/main/java/androidx/slice/ArrayUtils.java
@@ -18,9 +18,9 @@
 
 import android.support.annotation.RestrictTo;
 import android.support.annotation.RestrictTo.Scope;
+import android.support.v4.util.ObjectsCompat;
 
 import java.lang.reflect.Array;
-import java.util.Objects;
 
 /**
  * @hide
@@ -30,7 +30,7 @@
 
     public static <T> boolean contains(T[] array, T item) {
         for (T t : array) {
-            if (Objects.equals(t, item)) {
+            if (ObjectsCompat.equals(t, item)) {
                 return true;
             }
         }
@@ -59,7 +59,7 @@
             }
             final int length = array.length;
             for (int i = 0; i < length; i++) {
-                if (Objects.equals(array[i], element)) {
+                if (ObjectsCompat.equals(array[i], element)) {
                     if (length == 1) {
                         return null;
                     }
diff --git a/slices/core/src/main/java/androidx/slice/Slice.java b/slices/core/src/main/java/androidx/slice/Slice.java
index 56a9af8..3732e4a 100644
--- a/slices/core/src/main/java/androidx/slice/Slice.java
+++ b/slices/core/src/main/java/androidx/slice/Slice.java
@@ -38,7 +38,6 @@
 
 import static androidx.slice.SliceConvert.unwrap;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
 import android.app.slice.SliceManager;
@@ -49,6 +48,7 @@
 import android.os.Parcelable;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
 import android.support.annotation.RestrictTo.Scope;
 import android.support.annotation.StringDef;
@@ -437,7 +437,7 @@
      * @see Slice
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
-    @SuppressWarnings("NewApi")
+    @SuppressWarnings("NewApi") // Lint doesn't understand BuildCompat.
     @Nullable
     public static Slice bindSlice(Context context, @NonNull Uri uri,
             List<SliceSpec> supportedSpecs) {
@@ -448,7 +448,7 @@
         }
     }
 
-    @TargetApi(28)
+    @RequiresApi(28)
     private static Slice callBindSlice(Context context, Uri uri,
             List<SliceSpec> supportedSpecs) {
         return SliceConvert.wrap(context.getSystemService(SliceManager.class)
diff --git a/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java b/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
index a6d74c6..bb75acc 100644
--- a/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
+++ b/slices/core/src/main/java/androidx/slice/compat/CompatPinnedList.java
@@ -23,12 +23,12 @@
 import android.support.annotation.RestrictTo;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.util.ArraySet;
+import android.support.v4.util.ObjectsCompat;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
 
 import androidx.slice.SliceSpec;
@@ -170,7 +170,7 @@
 
     private static SliceSpec findSpec(List<SliceSpec> specs, String type) {
         for (SliceSpec spec : specs) {
-            if (Objects.equals(spec.getType(), type)) {
+            if (ObjectsCompat.equals(spec.getType(), type)) {
                 return spec;
             }
         }
diff --git a/slices/core/src/main/java/androidx/slice/compat/ContentProviderWrapper.java b/slices/core/src/main/java/androidx/slice/compat/ContentProviderWrapper.java
index 30971ad..fbc2a9a 100644
--- a/slices/core/src/main/java/androidx/slice/compat/ContentProviderWrapper.java
+++ b/slices/core/src/main/java/androidx/slice/compat/ContentProviderWrapper.java
@@ -70,6 +70,7 @@
 
     @Nullable
     @Override
+    @RequiresApi(16)
     public final Cursor query(@NonNull Uri uri, @Nullable String[] projection,
             @Nullable String selection, @Nullable String[] selectionArgs,
             @Nullable String sortOrder, @Nullable CancellationSignal cancellationSignal) {
@@ -115,6 +116,7 @@
 
     @Nullable
     @Override
+    @RequiresApi(19)
     public final Uri canonicalize(@NonNull Uri url) {
         return mImpl.canonicalize(url);
     }
diff --git a/slices/core/src/main/java/androidx/slice/core/SliceQuery.java b/slices/core/src/main/java/androidx/slice/core/SliceQuery.java
index 724f4c9..a8baef0 100644
--- a/slices/core/src/main/java/androidx/slice/core/SliceQuery.java
+++ b/slices/core/src/main/java/androidx/slice/core/SliceQuery.java
@@ -19,7 +19,6 @@
 import static android.app.slice.SliceItem.FORMAT_ACTION;
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
 
@@ -41,8 +40,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-// TODO: Not expect 24.
-@TargetApi(24)
 public class SliceQuery {
 
     /**
diff --git a/slices/view/src/main/java/androidx/slice/widget/ActionRow.java b/slices/view/src/main/java/androidx/slice/widget/ActionRow.java
index aa45605..a91e3b3 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ActionRow.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ActionRow.java
@@ -20,7 +20,6 @@
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
 import static android.app.slice.SliceItem.FORMAT_REMOTE_INPUT;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
 import android.app.RemoteInput;
@@ -41,7 +40,6 @@
 import android.widget.TextView;
 
 import java.util.List;
-import java.util.function.Consumer;
 
 import androidx.slice.SliceItem;
 import androidx.slice.core.SliceQuery;
@@ -50,7 +48,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(24)
 public class ActionRow extends FrameLayout {
 
     private static final int MAX_ACTIONS = 5;
@@ -111,46 +108,43 @@
         if (color != -1) {
             setColor(color);
         }
-        actions.forEach(new Consumer<SliceItem>() {
-            @Override
-            public void accept(final SliceItem action) {
-                if (mActionsGroup.getChildCount() >= MAX_ACTIONS) {
-                    return;
-                }
-                final SliceItem input = SliceQuery.find(action, FORMAT_REMOTE_INPUT);
-                final SliceItem image = SliceQuery.find(action, FORMAT_IMAGE);
-                if (input != null && image != null
-                        && input.getRemoteInput().getAllowFreeFormInput()) {
-                    boolean tint = !image.hasHint(HINT_NO_TINT);
-                    addAction(image.getIcon(), tint, image).setOnClickListener(
+        for (final SliceItem action : actions) {
+            if (mActionsGroup.getChildCount() >= MAX_ACTIONS) {
+                return;
+            }
+            final SliceItem input = SliceQuery.find(action, FORMAT_REMOTE_INPUT);
+            final SliceItem image = SliceQuery.find(action, FORMAT_IMAGE);
+            if (input != null && image != null
+                    && input.getRemoteInput().getAllowFreeFormInput()) {
+                boolean tint = !image.hasHint(HINT_NO_TINT);
+                addAction(image.getIcon(), tint, image).setOnClickListener(
+                        new OnClickListener() {
+                            @Override
+                            public void onClick(View v) {
+                                handleRemoteInputClick(v, action.getAction(),
+                                        input.getRemoteInput());
+                            }
+                        });
+                createRemoteInputView(mColor, getContext());
+            } else if (action.hasHint(Slice.HINT_SHORTCUT)) {
+                final ActionContent ac = new ActionContent(action);
+                SliceItem iconItem = ac.getIconItem();
+                if (iconItem != null && ac.getActionItem() != null) {
+                    boolean tint = !iconItem.hasHint(HINT_NO_TINT);
+                    addAction(iconItem.getIcon(), tint, image).setOnClickListener(
                             new OnClickListener() {
                                 @Override
                                 public void onClick(View v) {
-                                    handleRemoteInputClick(v, action.getAction(),
-                                            input.getRemoteInput());
+                                    try {
+                                        ac.getActionItem().getAction().send();
+                                    } catch (CanceledException e) {
+                                        e.printStackTrace();
+                                    }
                                 }
                             });
-                    createRemoteInputView(mColor, getContext());
-                } else if (action.hasHint(Slice.HINT_SHORTCUT)) {
-                    final ActionContent ac = new ActionContent(action);
-                    SliceItem iconItem = ac.getIconItem();
-                    if (iconItem != null && ac.getActionItem() != null) {
-                        boolean tint = !iconItem.hasHint(HINT_NO_TINT);
-                        addAction(iconItem.getIcon(), tint, image).setOnClickListener(
-                                new OnClickListener() {
-                                    @Override
-                                    public void onClick(View v) {
-                                        try {
-                                            ac.getActionItem().getAction().send();
-                                        } catch (CanceledException e) {
-                                            e.printStackTrace();
-                                        }
-                                    }
-                                });
-                    }
                 }
             }
-        });
+        }
         setVisibility(getChildCount() != 0 ? View.VISIBLE : View.GONE);
     }
 
diff --git a/slices/view/src/main/java/androidx/slice/widget/GridRowView.java b/slices/view/src/main/java/androidx/slice/widget/GridRowView.java
index 4fe63a4..51885ad 100644
--- a/slices/view/src/main/java/androidx/slice/widget/GridRowView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/GridRowView.java
@@ -28,7 +28,6 @@
 
 import static androidx.slice.widget.SliceView.MODE_SMALL;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.res.Resources;
@@ -52,8 +51,6 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 import androidx.slice.Slice;
 import androidx.slice.SliceItem;
@@ -64,7 +61,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(24)
 public class GridRowView extends SliceChildView implements View.OnClickListener {
 
     private static final String TAG = "GridView";
@@ -219,12 +215,12 @@
         // In small format we display one text item and prefer titles
         if (!singleItem && getMode() == MODE_SMALL) {
             // Get all our text items
-            textItems = cellItems.stream().filter(new Predicate<SliceItem>() {
-                @Override
-                public boolean test(SliceItem s) {
-                    return FORMAT_TEXT.equals(s.getFormat());
+            textItems = new ArrayList<>();
+            for (SliceItem cellItem : cellItems) {
+                if (FORMAT_TEXT.equals(cellItem.getFormat())) {
+                    textItems.add(cellItem);
                 }
-            }).collect(Collectors.<SliceItem>toList());
+            }
             // If we have more than 1 remove non-titles
             Iterator<SliceItem> iterator = textItems.iterator();
             while (textItems.size() > 1) {
diff --git a/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java b/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
index c69e20f..8cac539 100644
--- a/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
+++ b/slices/view/src/main/java/androidx/slice/widget/LargeSliceAdapter.java
@@ -25,7 +25,6 @@
 
 import static androidx.slice.widget.SliceView.MODE_LARGE;
 
-import android.annotation.TargetApi;
 import android.app.slice.Slice;
 import android.content.Context;
 import android.support.annotation.RestrictTo;
@@ -40,8 +39,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 import androidx.slice.SliceItem;
 import androidx.slice.core.SliceQuery;
@@ -51,7 +48,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(24)
 public class LargeSliceAdapter extends RecyclerView.Adapter<LargeSliceAdapter.SliceViewHolder> {
 
     static final int TYPE_DEFAULT       = 1;
@@ -95,12 +91,10 @@
             mSlices.clear();
         } else {
             mIdGen.resetUsage();
-            mSlices = slices.stream().map(new Function<SliceItem, SliceWrapper>() {
-                @Override
-                public SliceWrapper apply(SliceItem s) {
-                    return new SliceWrapper(s, mIdGen);
-                }
-            }).collect(Collectors.<SliceWrapper>toList());
+            mSlices = new ArrayList<>(slices.size());
+            for (SliceItem s : slices) {
+                mSlices.add(new SliceWrapper(s, mIdGen));
+            }
         }
         mColor = color;
         notifyDataSetChanged();
@@ -221,7 +215,8 @@
                 mCurrentIds.put(str, mNextLong++);
             }
             long id = mCurrentIds.get(str);
-            int index = mUsedIds.getOrDefault(str, 0);
+            Integer usedIdIndex = mUsedIds.get(str);
+            int index = usedIdIndex != null ? usedIdIndex : 0;
             mUsedIds.put(str, index + 1);
             return id + index * 10000;
         }
diff --git a/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java b/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java
index 0f26308..ada7b4b 100644
--- a/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/LargeTemplateView.java
@@ -16,7 +16,6 @@
 
 package androidx.slice.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RestrictTo;
 import android.support.v7.widget.LinearLayoutManager;
@@ -33,7 +32,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(24)
 public class LargeTemplateView extends SliceChildView {
 
     private final LargeSliceAdapter mAdapter;
diff --git a/slices/view/src/main/java/androidx/slice/widget/MessageView.java b/slices/view/src/main/java/androidx/slice/widget/MessageView.java
index a8c9777..9efd7ee 100644
--- a/slices/view/src/main/java/androidx/slice/widget/MessageView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/MessageView.java
@@ -20,7 +20,6 @@
 import static android.app.slice.SliceItem.FORMAT_IMAGE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -41,7 +40,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(24)
 public class MessageView extends SliceChildView {
 
     private TextView mDetails;
diff --git a/slices/view/src/main/java/androidx/slice/widget/RemoteInputView.java b/slices/view/src/main/java/androidx/slice/widget/RemoteInputView.java
index c795b73..b3ee203 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RemoteInputView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RemoteInputView.java
@@ -17,7 +17,6 @@
 package androidx.slice.widget;
 
 import android.animation.Animator;
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
 import android.content.Context;
@@ -26,6 +25,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.support.annotation.RestrictTo;
+import android.support.v4.content.ContextCompat;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
@@ -57,7 +57,6 @@
  */
 // TODO this should be unified with SystemUI RemoteInputView (b/67527720)
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(23)
 public class RemoteInputView extends LinearLayout implements View.OnClickListener, TextWatcher {
 
     private static final String TAG = "RemoteInput";
@@ -366,7 +365,7 @@
             final InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
 
             if (mShowImeOnInputConnection && inputConnection != null) {
-                final InputMethodManager imm = getContext().getSystemService(
+                final InputMethodManager imm = ContextCompat.getSystemService(getContext(),
                         InputMethodManager.class);
                 if (imm != null) {
                     // onCreateInputConnection is called by InputMethodManager in the middle of
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowView.java b/slices/view/src/main/java/androidx/slice/widget/RowView.java
index 8bc93bd..7f522d3 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowView.java
@@ -31,7 +31,6 @@
 import static androidx.slice.core.SliceHints.SUBTYPE_VALUE;
 import static androidx.slice.widget.SliceView.MODE_SMALL;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
 import android.content.Context;
@@ -69,7 +68,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(23)
 public class RowView extends SliceChildView implements View.OnClickListener {
 
     private static final String TAG = "RowView";
diff --git a/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java b/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
index 9bf058c..cea162d 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ShortcutView.java
@@ -26,7 +26,7 @@
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
 
-import android.annotation.TargetApi;
+import android.annotation.SuppressLint;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
 import android.content.Context;
@@ -51,7 +51,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(23)
 public class ShortcutView extends SliceChildView {
 
     private static final String TAG = "ShortcutView";
@@ -72,6 +71,7 @@
         mLargeIconSize = res.getDimensionPixelSize(R.dimen.abc_slice_shortcut_size);
     }
 
+    @SuppressLint("NewApi") // mIcon can only be non-null on API 23+
     @Override
     public void setSlice(Slice slice) {
         resetView();
diff --git a/slices/view/src/main/java/androidx/slice/widget/SliceViewUtil.java b/slices/view/src/main/java/androidx/slice/widget/SliceViewUtil.java
index d1aabbe..e96528d 100644
--- a/slices/view/src/main/java/androidx/slice/widget/SliceViewUtil.java
+++ b/slices/view/src/main/java/androidx/slice/widget/SliceViewUtil.java
@@ -16,7 +16,6 @@
 
 package androidx.slice.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
@@ -34,7 +33,9 @@
 import android.support.annotation.AttrRes;
 import android.support.annotation.ColorInt;
 import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
+import android.support.v4.content.ContextCompat;
 import android.text.format.DateUtils;
 import android.view.Gravity;
 import android.view.ViewGroup;
@@ -49,7 +50,6 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-@TargetApi(23)
 public class SliceViewUtil {
 
     /**
@@ -70,9 +70,7 @@
      */
     @ColorInt
     public static int getDefaultColor(@NonNull Context context, int resId) {
-        final ColorStateList list = context.getResources().getColorStateList(resId,
-                context.getTheme());
-
+        final ColorStateList list = ContextCompat.getColorStateList(context, resId);
         return list.getDefaultColor();
     }
 
@@ -140,6 +138,7 @@
 
     /**
      */
+    @RequiresApi(23)
     public static Icon createIconFromDrawable(Drawable d) {
         if (d instanceof BitmapDrawable) {
             return Icon.createWithBitmap(((BitmapDrawable) d).getBitmap());
@@ -154,7 +153,7 @@
 
     /**
      */
-    @TargetApi(28)
+    @RequiresApi(23)
     public static void createCircledIcon(@NonNull Context context, int iconSizePx,
             Icon icon, boolean isLarge, ViewGroup parent) {
         ImageView v = new ImageView(context);