/*
 * Copyright 2018 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.slice;

import static android.app.slice.Slice.HINT_PARTIAL;
import static android.app.slice.Slice.HINT_TITLE;

import static androidx.slice.SliceMetadata.LOADED_ALL;
import static androidx.slice.SliceMetadata.LOADED_NONE;
import static androidx.slice.SliceMetadata.LOADED_PARTIAL;
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
import static androidx.slice.core.SliceHints.HINT_KEYWORDS;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNull;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import androidx.core.graphics.drawable.IconCompat;
import androidx.core.util.Pair;
import androidx.slice.builders.GridRowBuilder;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.SliceAction;
import androidx.slice.core.SliceActionImpl;
import androidx.slice.core.SliceHints;
import androidx.slice.render.SliceRenderActivity;
import androidx.slice.widget.EventInfo;
import androidx.slice.widget.SliceLiveData;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Tests for {@link SliceMetadata}.
 */
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SliceMetadataTest {

    private final Context mContext = InstrumentationRegistry.getContext();

    @Before
    public void setup() {
        SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
    }

    @Test
    public void testGetSliceActionsNull() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("Text"));

        SliceMetadata sliceMetadata = SliceMetadata.from(mContext, lb.build());
        assertNull(sliceMetadata.getSliceActions());
    }

    @Test
    public void testGetSliceActions() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");
        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
        new Canvas(b).drawColor(0xffff0000);
        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));

        SliceAction action1 = new SliceAction(pi, icon, "action1");
        SliceAction action2 = new SliceAction(pi, icon, "action2");
        SliceAction action3 = new SliceAction(pi, icon, "action3");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("Text"))
                .addAction(action1)
                .addAction(action2)
                .addAction(action3);

        ArrayList<SliceAction> expectedActions = new ArrayList<>();
        expectedActions.add(action1);
        expectedActions.add(action2);
        expectedActions.add(action3);

        SliceMetadata sliceMetadata = SliceMetadata.from(mContext, lb.build());
        List<SliceItem> actions = sliceMetadata.getSliceActions();

        for (int i = 0; i < expectedActions.size(); i++) {
            assertEquivalent(expectedActions.get(i), new SliceActionImpl(actions.get(i)));
        }
    }

    @Test
    public void testGetPrimaryActionForGrid() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");
        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
        new Canvas(b).drawColor(0xffff0000);
        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));

        SliceAction primaryAction = new SliceAction(pi, icon, "action");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        GridRowBuilder grb = new GridRowBuilder(lb);
        grb.setPrimaryAction(primaryAction);
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        lb.addGridRow(grb);

        Slice gridSlice = lb.build();
        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
        assertEquivalent(primaryAction, gridInfo.getPrimaryAction());
    }

    @Test
    public void testGetPrimaryActionForRow() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");
        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
        new Canvas(b).drawColor(0xffff0000);
        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));

        SliceAction primaryAction = new SliceAction(pi, icon, "action");
        SliceAction endAction = new SliceAction(pi, "toogle action", false);

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(lb)
                .setTitle("a title")
                .addEndItem(endAction)
                .setPrimaryAction(primaryAction);
        lb.addRow(rb);

        Slice rowSlice = lb.build();
        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
        assertEquivalent(primaryAction, rowInfo.getPrimaryAction());
    }

    @Test
    public void testGetPrimaryActionForHeader() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");
        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
        new Canvas(b).drawColor(0xffff0000);
        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));

        SliceAction primaryAction = new SliceAction(pi, icon, "action");
        SliceAction sliceAction = new SliceAction(pi, "another action", true);

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addAction(sliceAction);
        ListBuilder.HeaderBuilder hb = new ListBuilder.HeaderBuilder(lb);
        hb.setTitle("header title");
        hb.setPrimaryAction(primaryAction);
        lb.setHeader(hb);

        Slice headerSlice = lb.build();
        SliceMetadata headerInfo = SliceMetadata.from(mContext, headerSlice);
        assertEquivalent(primaryAction, headerInfo.getPrimaryAction());
    }

    @Test
    public void testGetPrimaryActionNull() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");
        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
        new Canvas(b).drawColor(0xffff0000);
        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));

        SliceAction endAction1 = new SliceAction(pi, icon, "action");
        SliceAction endAction2 = new SliceAction(pi, "toogle action", false);

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(lb)
                .setTitle("a title")
                .addEndItem(endAction1)
                .addEndItem(endAction2);
        lb.addRow(rb);

        Slice rowSlice = lb.build();
        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
        assertNull(rowInfo.getPrimaryAction());
    }

    @Test
    public void testGetHeaderTypeGrid() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        GridRowBuilder grb = new GridRowBuilder(lb);
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        lb.addGridRow(grb);

        Slice gridSlice = lb.build();
        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
        assertEquals(EventInfo.ROW_TYPE_GRID, gridInfo.getHeaderType());
    }

    @Test
    public void testGetHeaderTypeRow() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));

        Slice rowSlice = lb.build();
        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
        assertEquals(EventInfo.ROW_TYPE_LIST, rowInfo.getHeaderType());
    }

    @Test
    public void testGetHeaderTypeToggle() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");

        SliceAction toggleAction = new SliceAction(pi, "toggle", false /* isChecked */);
        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb)
                .setTitle("another title")
                .addEndItem(toggleAction));

        Slice toggleSlice = lb.build();
        SliceMetadata toggleInfo = SliceMetadata.from(mContext, toggleSlice);
        assertEquals(EventInfo.ROW_TYPE_TOGGLE, toggleInfo.getHeaderType());
    }

    @Test
    public void testGetHeaderTypeSlider() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addInputRange(new ListBuilder.InputRangeBuilder(lb)
                .setTitle("another title")
                .setValue(5)
                .setMax(10)
                .setAction(pi));

        Slice sliderSlice = lb.build();
        SliceMetadata sliderInfo = SliceMetadata.from(mContext, sliderSlice);
        assertEquals(EventInfo.ROW_TYPE_SLIDER, sliderInfo.getHeaderType());
    }

    @Test
    public void testGetHeaderTypeProgress() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRange(new ListBuilder.RangeBuilder(lb)
                .setTitle("another title")
                .setValue(5)
                .setMax(10));

        Slice sliderSlice = lb.build();
        SliceMetadata progressInfo = SliceMetadata.from(mContext, sliderSlice);
        assertEquals(EventInfo.ROW_TYPE_PROGRESS, progressInfo.getHeaderType());
    }

    @Test
    public void testGetHeaderTypeHeader() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        ListBuilder.HeaderBuilder hb = new ListBuilder.HeaderBuilder(lb);
        hb.setTitle("header title");
        lb.setHeader(hb);

        Slice headerSlice = lb.build();
        SliceMetadata headerInfo = SliceMetadata.from(mContext, headerSlice);
        assertEquals(EventInfo.ROW_TYPE_LIST, headerInfo.getHeaderType());
    }

    @Test
    public void testHasLargeModeFullGrid() {
        // If a grid is "full" with two text and an image there is a different small / large state.
        Uri uri = Uri.parse("content://pkg/slice");
        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
        new Canvas(b).drawColor(0xffff0000);
        Icon icon = Icon.createWithBitmap(b);

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        GridRowBuilder grb = new GridRowBuilder(lb);
        grb.addCell(new GridRowBuilder.CellBuilder(grb)
                .addText("some text")
                .addText("more text")
                .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
        grb.addCell(new GridRowBuilder.CellBuilder(grb)
                .addText("some text")
                .addText("more text")
                .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
        grb.addCell(new GridRowBuilder.CellBuilder(grb)
                .addText("some text")
                .addText("more text")
                .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
        lb.addGridRow(grb);

        Slice gridSlice = lb.build();
        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
        assertTrue(gridInfo.hasLargeMode());
    }

    @Test
    public void testHasLargeModeGrid() {
        // If a grid is not "full" either no image or an image and one text item, small / large
        // is the same.
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        GridRowBuilder grb = new GridRowBuilder(lb);
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
        lb.addGridRow(grb);

        Slice gridSlice = lb.build();
        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
        assertTrue(!gridInfo.hasLargeMode());
    }

    @Test
    public void testGetLargeModeMultipleRows() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("another row another title"));

        Slice rowSlice = lb.build();
        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
        assertTrue(rowInfo.hasLargeMode());
    }

    @Test
    public void testGetLargeModeSingleRow() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));

        Slice rowSlice = lb.build();
        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
        assertTrue(!rowInfo.hasLargeMode());
    }

    @Test
    public void testGetTogglesNone() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));

        Slice rowSlice = lb.build();
        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
        assertTrue(rowInfo.getToggles().isEmpty());
    }

    @Test
    public void testGetTogglesSingle() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");

        SliceAction toggleAction = new SliceAction(pi, "toggle", false /* isChecked */);
        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb)
                .setTitle("another title")
                .addEndItem(toggleAction));

        Slice toggleSlice = lb.build();
        SliceMetadata toggleInfo = SliceMetadata.from(mContext, toggleSlice);
        List<androidx.slice.core.SliceAction> actualToggles = toggleInfo.getToggles();
        assertEquals(1, actualToggles.size());
        assertEquivalent(toggleAction, actualToggles.get(0));
    }

    @Test
    public void testGetTogglesMultiple() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");
        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
        new Canvas(b).drawColor(0xffff0000);
        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));

        SliceAction toggleAction = new SliceAction(pi, icon, "toggle", false /* isChecked */);
        SliceAction toggleAction2 = new SliceAction(pi, icon, "toggle2", true /* isChecked */);

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb)
                .setTitle("another title")
                .addEndItem(toggleAction)
                .addEndItem(toggleAction2));

        Slice toggleSlice = lb.build();
        SliceMetadata toggleInfo = SliceMetadata.from(mContext, toggleSlice);
        List<androidx.slice.core.SliceAction> actualToggles = toggleInfo.getToggles();

        List<SliceAction> expectedToggles = new ArrayList<>();
        expectedToggles.add(toggleAction);
        expectedToggles.add(toggleAction2);

        for (int i = 0; i < expectedToggles.size(); i++) {
            assertEquivalent(expectedToggles.get(i), actualToggles.get(i));
        }
    }

    @Test
    public void testGetRangeNull() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));

        Slice rowSlice = lb.build();
        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
        assertNull(rowInfo.getRange());
    }

    @Test
    public void testGetRangeForSlider() {
        Uri uri = Uri.parse("content://pkg/slice");
        PendingIntent pi = getIntent("");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addInputRange(new ListBuilder.InputRangeBuilder(lb)
                .setTitle("another title")
                .setValue(7)
                .setMin(5)
                .setMax(10)
                .setInputAction(pi));

        Slice sliderSlice = lb.build();
        SliceMetadata sliderInfo = SliceMetadata.from(mContext, sliderSlice);

        Pair<Integer, Integer> values = sliderInfo.getRange();
        assertEquals(5, (int) values.first);
        assertEquals(10, (int) values.second);

        int currentValue = sliderInfo.getRangeValue();
        assertEquals(7, currentValue);
    }

    @Test
    public void testGetRangeForProgress() {
        Uri uri = Uri.parse("content://pkg/slice");

        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
        lb.addRange(new ListBuilder.RangeBuilder(lb)
                .setTitle("another title")
                .setValue(5)
                .setMax(10));

        Slice sliderSlice = lb.build();
        SliceMetadata progressInfo = SliceMetadata.from(mContext, sliderSlice);
        Pair<Integer, Integer> values = progressInfo.getRange();
        assertEquals(0, (int) values.first);
        assertEquals(10, (int) values.second);
    }

    @Test
    public void testKeywords() {
        Uri uri = Uri.parse("content://pkg/slice");
        Slice keywordSlice = new Slice.Builder(uri)
                .addHints(HINT_KEYWORDS)
                .addText("keyword1", null)
                .addText("keyword2", null)
                .addText("keyword3", null).build();
        Slice slice = new Slice.Builder(uri)
                .addText("Some text", null, HINT_TITLE)
                .addText("Some other text", null)
                .addSubSlice(keywordSlice)
                .build();

        SliceMetadata SliceMetadata1 = SliceMetadata.from(mContext, slice);
        List<String> sliceKeywords = SliceMetadata1.getSliceKeywords();
        String[] expectedList = new String[] {"keyword1", "keyword2", "keyword3"};
        assertArrayEquals(expectedList, sliceKeywords.toArray());

        // Make sure it doesn't find keywords that aren't there
        Slice slice2 = new Slice.Builder(uri)
                .addText("Some text", null, HINT_TITLE)
                .addText("Some other text", null).build();

        SliceMetadata SliceMetadata2 = SliceMetadata.from(mContext, slice2);
        List<String> slice2Keywords = SliceMetadata2.getSliceKeywords();
        assertNull(slice2Keywords);

        // Make sure empty list if specified to have no keywords
        Slice noKeywordSlice = new Slice.Builder(uri).addHints(HINT_KEYWORDS).build();
        Slice slice3 = new Slice.Builder(uri)
                .addText("Some text", null, HINT_TITLE)
                .addSubSlice(noKeywordSlice)
                .build();

        SliceMetadata sliceMetadata3 = SliceMetadata.from(mContext, slice3);
        List<String> slice3Keywords = sliceMetadata3.getSliceKeywords();
        assertTrue(slice3Keywords.isEmpty());
    }

    @Test
    public void testGetLoadingState() {
        Uri uri = Uri.parse("content://pkg/slice");
        Slice s1 = new Slice.Builder(uri).build();
        SliceMetadata SliceMetadata1 = SliceMetadata.from(mContext, s1);
        int actualState1 = SliceMetadata1.getLoadingState();
        assertEquals(LOADED_NONE, actualState1);

        Slice s2 = new Slice.Builder(uri).addText(null, null, HINT_PARTIAL).build();
        SliceMetadata SliceMetadata2 = SliceMetadata.from(mContext, s2);
        int actualState2 = SliceMetadata2.getLoadingState();
        assertEquals(LOADED_PARTIAL, actualState2);

        Slice s3 = new Slice.Builder(uri).addText("Text", null).build();
        SliceMetadata SliceMetadata3 = SliceMetadata.from(mContext, s3);
        int actualState3 = SliceMetadata3.getLoadingState();
        assertEquals(LOADED_ALL, actualState3);
    }

    @Test
    public void testGetExpiry() {
        Uri uri = Uri.parse("content://pkg/slice");
        long timestamp = System.currentTimeMillis();
        long ttl = TimeUnit.DAYS.toMillis(1);
        Slice ttlSlice = new Slice.Builder(uri)
                .addText("Some text", null)
                .addTimestamp(timestamp, null)
                .addTimestamp(timestamp, null, SliceHints.HINT_LAST_UPDATED)
                .addTimestamp(ttl, null, SliceHints.HINT_TTL)
                .build();

        SliceMetadata si1 = SliceMetadata.from(mContext, ttlSlice);
        long retrievedTtl = si1.getExpiry();
        assertEquals(ttl, retrievedTtl);

        Slice noTtlSlice = new Slice.Builder(uri)
                .addText("Some text", null)
                .addTimestamp(timestamp, null).build();
        SliceMetadata si2 = SliceMetadata.from(mContext, noTtlSlice);
        long retrievedTtl2 = si2.getExpiry();
        assertEquals(0, retrievedTtl2);
    }

    @Test
    public void testGetLastUpdated() {
        Uri uri = Uri.parse("content://pkg/slice");
        long timestamp = System.currentTimeMillis();
        long ttl = TimeUnit.DAYS.toMillis(1);
        Slice ttlSlice = new Slice.Builder(uri)
                .addText("Some text", null)
                .addTimestamp(timestamp - 20, null)
                .addTimestamp(timestamp, null, SliceHints.HINT_LAST_UPDATED)
                .addTimestamp(ttl, null, SliceHints.HINT_TTL)
                .build();

        SliceMetadata si1 = SliceMetadata.from(mContext, ttlSlice);
        long retrievedLastUpdated = si1.getLastUpdatedTime();
        assertEquals(timestamp, retrievedLastUpdated);

        Slice noTtlSlice = new Slice.Builder(uri)
                .addText("Some text", null)
                .addTimestamp(timestamp, null).build();

        SliceMetadata si2 = SliceMetadata.from(mContext, noTtlSlice);
        long retrievedLastUpdated2 = si2.getLastUpdatedTime();
        assertEquals(0, retrievedLastUpdated2);
    }

    @Test
    public void testIsPermissionSlice() {
        Uri uri = Uri.parse("content://pkg/slice");
        Slice permissionSlice =
                SliceProvider.createPermissionSlice(mContext, uri, mContext.getPackageName());

        SliceMetadata metadata = SliceMetadata.from(mContext, permissionSlice);
        assertEquals(true, metadata.isPermissionSlice());
    }

    private PendingIntent getIntent(String action) {
        Intent intent = new Intent(action);
        intent.setClassName(mContext.getPackageName(), SliceRenderActivity.class.getName());
        return PendingIntent.getActivity(mContext, 0, intent, 0);
    }

    private void assertEquivalent(androidx.slice.core.SliceAction desired,
            androidx.slice.core.SliceAction actual) {
        assertEquals(desired.getTitle(), actual.getTitle());
        assertEquals(desired.getContentDescription(), actual.getContentDescription());
        assertEquals(desired.isToggle(), actual.isToggle());
        assertEquals(desired.isDefaultToggle(), actual.isDefaultToggle());
        assertEquals(desired.isChecked(), actual.isChecked());
        assertEquals(desired.getPriority(), actual.getPriority());
        assertEquals(desired.getIcon() == null, actual.getIcon() == null);
        assertEquals(desired.getImageMode(), actual.getImageMode());
    }
}
