SliceMetadataTest.java revision ac7a30acc7b945a83e70f94375a172acc16e2e7d
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.slice;
18
19import static android.app.slice.Slice.HINT_PARTIAL;
20import static android.app.slice.Slice.HINT_TITLE;
21
22import static androidx.slice.SliceMetadata.LOADED_ALL;
23import static androidx.slice.SliceMetadata.LOADED_NONE;
24import static androidx.slice.SliceMetadata.LOADED_PARTIAL;
25import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
26import static androidx.slice.core.SliceHints.HINT_KEYWORDS;
27
28import static junit.framework.Assert.assertEquals;
29import static junit.framework.Assert.assertTrue;
30
31import static org.junit.Assert.assertArrayEquals;
32import static org.junit.Assert.assertNull;
33
34import android.app.PendingIntent;
35import android.content.Context;
36import android.content.Intent;
37import android.graphics.Bitmap;
38import android.graphics.Canvas;
39import android.graphics.drawable.Icon;
40import android.net.Uri;
41import android.support.test.InstrumentationRegistry;
42import android.support.test.filters.SmallTest;
43import android.support.test.runner.AndroidJUnit4;
44
45import androidx.core.graphics.drawable.IconCompat;
46import androidx.core.util.Pair;
47import androidx.slice.builders.GridRowBuilder;
48import androidx.slice.builders.ListBuilder;
49import androidx.slice.builders.SliceAction;
50import androidx.slice.compat.SliceProviderCompat;
51import androidx.slice.core.SliceActionImpl;
52import androidx.slice.core.SliceHints;
53import androidx.slice.render.SliceRenderActivity;
54import androidx.slice.widget.EventInfo;
55import androidx.slice.widget.SliceLiveData;
56
57import org.junit.Before;
58import org.junit.Test;
59import org.junit.runner.RunWith;
60
61import java.util.ArrayList;
62import java.util.List;
63import java.util.concurrent.TimeUnit;
64
65/**
66 * Tests for {@link SliceMetadata}.
67 */
68@RunWith(AndroidJUnit4.class)
69@SmallTest
70public class SliceMetadataTest {
71
72    private final Context mContext = InstrumentationRegistry.getContext();
73
74    @Before
75    public void setup() {
76        SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
77    }
78
79    @Test
80    public void testGetSliceActionsNull() {
81        Uri uri = Uri.parse("content://pkg/slice");
82
83        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
84        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("Text"));
85
86        SliceMetadata sliceMetadata = SliceMetadata.from(mContext, lb.build());
87        assertNull(sliceMetadata.getSliceActions());
88    }
89
90    @Test
91    public void testGetSliceActions() {
92        Uri uri = Uri.parse("content://pkg/slice");
93        PendingIntent pi = getIntent("");
94        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
95        new Canvas(b).drawColor(0xffff0000);
96        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
97
98        SliceAction action1 = new SliceAction(pi, icon, "action1");
99        SliceAction action2 = new SliceAction(pi, icon, "action2");
100        SliceAction action3 = new SliceAction(pi, icon, "action3");
101
102        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
103        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("Text"))
104                .addAction(action1)
105                .addAction(action2)
106                .addAction(action3);
107
108        ArrayList<SliceAction> expectedActions = new ArrayList<>();
109        expectedActions.add(action1);
110        expectedActions.add(action2);
111        expectedActions.add(action3);
112
113        SliceMetadata sliceMetadata = SliceMetadata.from(mContext, lb.build());
114        List<SliceItem> actions = sliceMetadata.getSliceActions();
115
116        for (int i = 0; i < expectedActions.size(); i++) {
117            assertEquivalent(expectedActions.get(i), new SliceActionImpl(actions.get(i)));
118        }
119    }
120
121    @Test
122    public void testGetPrimaryActionForGrid() {
123        Uri uri = Uri.parse("content://pkg/slice");
124        PendingIntent pi = getIntent("");
125        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
126        new Canvas(b).drawColor(0xffff0000);
127        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
128
129        SliceAction primaryAction = new SliceAction(pi, icon, "action");
130
131        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
132        GridRowBuilder grb = new GridRowBuilder(lb);
133        grb.setPrimaryAction(primaryAction);
134        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
135        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
136        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
137        lb.addGridRow(grb);
138
139        Slice gridSlice = lb.build();
140        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
141        assertEquivalent(primaryAction, gridInfo.getPrimaryAction());
142    }
143
144    @Test
145    public void testGetPrimaryActionForRow() {
146        Uri uri = Uri.parse("content://pkg/slice");
147        PendingIntent pi = getIntent("");
148        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
149        new Canvas(b).drawColor(0xffff0000);
150        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
151
152        SliceAction primaryAction = new SliceAction(pi, icon, "action");
153        SliceAction endAction = new SliceAction(pi, "toogle action", false);
154
155        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
156        ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(lb)
157                .setTitle("a title")
158                .addEndItem(endAction)
159                .setPrimaryAction(primaryAction);
160        lb.addRow(rb);
161
162        Slice rowSlice = lb.build();
163        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
164        assertEquivalent(primaryAction, rowInfo.getPrimaryAction());
165    }
166
167    @Test
168    public void testGetPrimaryActionForHeader() {
169        Uri uri = Uri.parse("content://pkg/slice");
170        PendingIntent pi = getIntent("");
171        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
172        new Canvas(b).drawColor(0xffff0000);
173        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
174
175        SliceAction primaryAction = new SliceAction(pi, icon, "action");
176        SliceAction sliceAction = new SliceAction(pi, "another action", true);
177
178        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
179        lb.addAction(sliceAction);
180        ListBuilder.HeaderBuilder hb = new ListBuilder.HeaderBuilder(lb);
181        hb.setTitle("header title");
182        hb.setPrimaryAction(primaryAction);
183        lb.setHeader(hb);
184
185        Slice headerSlice = lb.build();
186        SliceMetadata headerInfo = SliceMetadata.from(mContext, headerSlice);
187        assertEquivalent(primaryAction, headerInfo.getPrimaryAction());
188    }
189
190    @Test
191    public void testGetPrimaryActionNull() {
192        Uri uri = Uri.parse("content://pkg/slice");
193        PendingIntent pi = getIntent("");
194        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
195        new Canvas(b).drawColor(0xffff0000);
196        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
197
198        SliceAction endAction1 = new SliceAction(pi, icon, "action");
199        SliceAction endAction2 = new SliceAction(pi, "toogle action", false);
200
201        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
202        ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(lb)
203                .setTitle("a title")
204                .addEndItem(endAction1)
205                .addEndItem(endAction2);
206        lb.addRow(rb);
207
208        Slice rowSlice = lb.build();
209        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
210        assertNull(rowInfo.getPrimaryAction());
211    }
212
213    @Test
214    public void testGetHeaderTypeGrid() {
215        Uri uri = Uri.parse("content://pkg/slice");
216
217        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
218        GridRowBuilder grb = new GridRowBuilder(lb);
219        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
220        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
221        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
222        lb.addGridRow(grb);
223
224        Slice gridSlice = lb.build();
225        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
226        assertEquals(EventInfo.ROW_TYPE_GRID, gridInfo.getHeaderType());
227    }
228
229    @Test
230    public void testGetHeaderTypeRow() {
231        Uri uri = Uri.parse("content://pkg/slice");
232
233        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
234        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));
235
236        Slice rowSlice = lb.build();
237        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
238        assertEquals(EventInfo.ROW_TYPE_LIST, rowInfo.getHeaderType());
239    }
240
241    @Test
242    public void testGetHeaderTypeToggle() {
243        Uri uri = Uri.parse("content://pkg/slice");
244        PendingIntent pi = getIntent("");
245
246        SliceAction toggleAction = new SliceAction(pi, "toggle", false /* isChecked */);
247        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
248        lb.addRow(new ListBuilder.RowBuilder(lb)
249                .setTitle("another title")
250                .addEndItem(toggleAction));
251
252        Slice toggleSlice = lb.build();
253        SliceMetadata toggleInfo = SliceMetadata.from(mContext, toggleSlice);
254        assertEquals(EventInfo.ROW_TYPE_TOGGLE, toggleInfo.getHeaderType());
255    }
256
257    @Test
258    public void testGetHeaderTypeSlider() {
259        Uri uri = Uri.parse("content://pkg/slice");
260        PendingIntent pi = getIntent("");
261
262        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
263        lb.addInputRange(new ListBuilder.InputRangeBuilder(lb)
264                .setTitle("another title")
265                .setValue(5)
266                .setMax(10)
267                .setAction(pi));
268
269        Slice sliderSlice = lb.build();
270        SliceMetadata sliderInfo = SliceMetadata.from(mContext, sliderSlice);
271        assertEquals(EventInfo.ROW_TYPE_SLIDER, sliderInfo.getHeaderType());
272    }
273
274    @Test
275    public void testGetHeaderTypeProgress() {
276        Uri uri = Uri.parse("content://pkg/slice");
277
278        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
279        lb.addRange(new ListBuilder.RangeBuilder(lb)
280                .setTitle("another title")
281                .setValue(5)
282                .setMax(10));
283
284        Slice sliderSlice = lb.build();
285        SliceMetadata progressInfo = SliceMetadata.from(mContext, sliderSlice);
286        assertEquals(EventInfo.ROW_TYPE_PROGRESS, progressInfo.getHeaderType());
287    }
288
289    @Test
290    public void testGetHeaderTypeHeader() {
291        Uri uri = Uri.parse("content://pkg/slice");
292
293        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
294        ListBuilder.HeaderBuilder hb = new ListBuilder.HeaderBuilder(lb);
295        hb.setTitle("header title");
296        lb.setHeader(hb);
297
298        Slice headerSlice = lb.build();
299        SliceMetadata headerInfo = SliceMetadata.from(mContext, headerSlice);
300        assertEquals(EventInfo.ROW_TYPE_LIST, headerInfo.getHeaderType());
301    }
302
303    @Test
304    public void testHasLargeModeFullGrid() {
305        // If a grid is "full" with two text and an image there is a different small / large state.
306        Uri uri = Uri.parse("content://pkg/slice");
307        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
308        new Canvas(b).drawColor(0xffff0000);
309        Icon icon = Icon.createWithBitmap(b);
310
311        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
312        GridRowBuilder grb = new GridRowBuilder(lb);
313        grb.addCell(new GridRowBuilder.CellBuilder(grb)
314                .addText("some text")
315                .addText("more text")
316                .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
317        grb.addCell(new GridRowBuilder.CellBuilder(grb)
318                .addText("some text")
319                .addText("more text")
320                .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
321        grb.addCell(new GridRowBuilder.CellBuilder(grb)
322                .addText("some text")
323                .addText("more text")
324                .addImage(IconCompat.createFromIcon(icon), ICON_IMAGE));
325        lb.addGridRow(grb);
326
327        Slice gridSlice = lb.build();
328        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
329        assertTrue(gridInfo.hasLargeMode());
330    }
331
332    @Test
333    public void testHasLargeModeGrid() {
334        // If a grid is not "full" either no image or an image and one text item, small / large
335        // is the same.
336        Uri uri = Uri.parse("content://pkg/slice");
337
338        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
339        GridRowBuilder grb = new GridRowBuilder(lb);
340        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
341        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
342        grb.addCell(new GridRowBuilder.CellBuilder(grb).addText("some text"));
343        lb.addGridRow(grb);
344
345        Slice gridSlice = lb.build();
346        SliceMetadata gridInfo = SliceMetadata.from(mContext, gridSlice);
347        assertTrue(!gridInfo.hasLargeMode());
348    }
349
350    @Test
351    public void testGetLargeModeMultipleRows() {
352        Uri uri = Uri.parse("content://pkg/slice");
353
354        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
355        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));
356        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("another row another title"));
357
358        Slice rowSlice = lb.build();
359        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
360        assertTrue(rowInfo.hasLargeMode());
361    }
362
363    @Test
364    public void testGetLargeModeSingleRow() {
365        Uri uri = Uri.parse("content://pkg/slice");
366
367        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
368        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));
369
370        Slice rowSlice = lb.build();
371        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
372        assertTrue(!rowInfo.hasLargeMode());
373    }
374
375    @Test
376    public void testGetTogglesNone() {
377        Uri uri = Uri.parse("content://pkg/slice");
378
379        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
380        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));
381
382        Slice rowSlice = lb.build();
383        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
384        assertTrue(rowInfo.getToggles().isEmpty());
385    }
386
387    @Test
388    public void testGetTogglesSingle() {
389        Uri uri = Uri.parse("content://pkg/slice");
390        PendingIntent pi = getIntent("");
391
392        SliceAction toggleAction = new SliceAction(pi, "toggle", false /* isChecked */);
393        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
394        lb.addRow(new ListBuilder.RowBuilder(lb)
395                .setTitle("another title")
396                .addEndItem(toggleAction));
397
398        Slice toggleSlice = lb.build();
399        SliceMetadata toggleInfo = SliceMetadata.from(mContext, toggleSlice);
400        List<androidx.slice.core.SliceAction> actualToggles = toggleInfo.getToggles();
401        assertEquals(1, actualToggles.size());
402        assertEquivalent(toggleAction, actualToggles.get(0));
403    }
404
405    @Test
406    public void testGetTogglesMultiple() {
407        Uri uri = Uri.parse("content://pkg/slice");
408        PendingIntent pi = getIntent("");
409        Bitmap b = Bitmap.createBitmap(50, 25, Bitmap.Config.ARGB_8888);
410        new Canvas(b).drawColor(0xffff0000);
411        IconCompat icon = IconCompat.createFromIcon(Icon.createWithBitmap(b));
412
413        SliceAction toggleAction = new SliceAction(pi, icon, "toggle", false /* isChecked */);
414        SliceAction toggleAction2 = new SliceAction(pi, icon, "toggle2", true /* isChecked */);
415
416        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
417        lb.addRow(new ListBuilder.RowBuilder(lb)
418                .setTitle("another title")
419                .addEndItem(toggleAction)
420                .addEndItem(toggleAction2));
421
422        Slice toggleSlice = lb.build();
423        SliceMetadata toggleInfo = SliceMetadata.from(mContext, toggleSlice);
424        List<androidx.slice.core.SliceAction> actualToggles = toggleInfo.getToggles();
425
426        List<SliceAction> expectedToggles = new ArrayList<>();
427        expectedToggles.add(toggleAction);
428        expectedToggles.add(toggleAction2);
429
430        for (int i = 0; i < expectedToggles.size(); i++) {
431            assertEquivalent(expectedToggles.get(i), actualToggles.get(i));
432        }
433    }
434
435    @Test
436    public void testGetRangeNull() {
437        Uri uri = Uri.parse("content://pkg/slice");
438
439        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
440        lb.addRow(new ListBuilder.RowBuilder(lb).setTitle("a title"));
441
442        Slice rowSlice = lb.build();
443        SliceMetadata rowInfo = SliceMetadata.from(mContext, rowSlice);
444        assertNull(rowInfo.getRange());
445    }
446
447    @Test
448    public void testGetRangeForSlider() {
449        Uri uri = Uri.parse("content://pkg/slice");
450        PendingIntent pi = getIntent("");
451
452        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
453        lb.addInputRange(new ListBuilder.InputRangeBuilder(lb)
454                .setTitle("another title")
455                .setValue(5)
456                .setMax(10)
457                .setAction(pi));
458
459        Slice sliderSlice = lb.build();
460        SliceMetadata sliderInfo = SliceMetadata.from(mContext, sliderSlice);
461        Pair<Integer, Integer> values = sliderInfo.getRange();
462        assertEquals(5, (int) values.first);
463        assertEquals(10, (int) values.second);
464    }
465
466    @Test
467    public void testGetRangeForProgress() {
468        Uri uri = Uri.parse("content://pkg/slice");
469
470        ListBuilder lb = new ListBuilder(mContext, uri, ListBuilder.INFINITY);
471        lb.addRange(new ListBuilder.RangeBuilder(lb)
472                .setTitle("another title")
473                .setValue(5)
474                .setMax(10));
475
476        Slice sliderSlice = lb.build();
477        SliceMetadata progressInfo = SliceMetadata.from(mContext, sliderSlice);
478        Pair<Integer, Integer> values = progressInfo.getRange();
479        assertEquals(5, (int) values.first);
480        assertEquals(10, (int) values.second);
481
482    }
483
484    @Test
485    public void testKeywords() {
486        Uri uri = Uri.parse("content://pkg/slice");
487        Slice keywordSlice = new Slice.Builder(uri)
488                .addHints(HINT_KEYWORDS)
489                .addText("keyword1", null)
490                .addText("keyword2", null)
491                .addText("keyword3", null).build();
492        Slice slice = new Slice.Builder(uri)
493                .addText("Some text", null, HINT_TITLE)
494                .addText("Some other text", null)
495                .addSubSlice(keywordSlice)
496                .build();
497
498        SliceMetadata SliceMetadata1 = SliceMetadata.from(mContext, slice);
499        List<String> sliceKeywords = SliceMetadata1.getSliceKeywords();
500        String[] expectedList = new String[] {"keyword1", "keyword2", "keyword3"};
501        assertArrayEquals(expectedList, sliceKeywords.toArray());
502
503        // Make sure it doesn't find keywords that aren't there
504        Slice slice2 = new Slice.Builder(uri)
505                .addText("Some text", null, HINT_TITLE)
506                .addText("Some other text", null).build();
507
508        SliceMetadata SliceMetadata2 = SliceMetadata.from(mContext, slice2);
509        List<String> slice2Keywords = SliceMetadata2.getSliceKeywords();
510        assertNull(slice2Keywords);
511
512        // Make sure empty list if specified to have no keywords
513        Slice noKeywordSlice = new Slice.Builder(uri).addHints(HINT_KEYWORDS).build();
514        Slice slice3 = new Slice.Builder(uri)
515                .addText("Some text", null, HINT_TITLE)
516                .addSubSlice(noKeywordSlice)
517                .build();
518
519        SliceMetadata sliceMetadata3 = SliceMetadata.from(mContext, slice3);
520        List<String> slice3Keywords = sliceMetadata3.getSliceKeywords();
521        assertTrue(slice3Keywords.isEmpty());
522    }
523
524    @Test
525    public void testGetLoadingState() {
526        Uri uri = Uri.parse("content://pkg/slice");
527        Slice s1 = new Slice.Builder(uri).build();
528        SliceMetadata SliceMetadata1 = SliceMetadata.from(mContext, s1);
529        int actualState1 = SliceMetadata1.getLoadingState();
530        assertEquals(LOADED_NONE, actualState1);
531
532        Slice s2 = new Slice.Builder(uri).addText(null, null, HINT_PARTIAL).build();
533        SliceMetadata SliceMetadata2 = SliceMetadata.from(mContext, s2);
534        int actualState2 = SliceMetadata2.getLoadingState();
535        assertEquals(LOADED_PARTIAL, actualState2);
536
537        Slice s3 = new Slice.Builder(uri).addText("Text", null).build();
538        SliceMetadata SliceMetadata3 = SliceMetadata.from(mContext, s3);
539        int actualState3 = SliceMetadata3.getLoadingState();
540        assertEquals(LOADED_ALL, actualState3);
541    }
542
543    @Test
544    public void testGetExpiry() {
545        Uri uri = Uri.parse("content://pkg/slice");
546        long timestamp = System.currentTimeMillis();
547        long ttl = TimeUnit.DAYS.toMillis(1);
548        Slice ttlSlice = new Slice.Builder(uri)
549                .addText("Some text", null)
550                .addTimestamp(timestamp, null)
551                .addTimestamp(timestamp, null, SliceHints.HINT_LAST_UPDATED)
552                .addTimestamp(ttl, null, SliceHints.HINT_TTL)
553                .build();
554
555        SliceMetadata si1 = SliceMetadata.from(mContext, ttlSlice);
556        long retrievedTtl = si1.getExpiry();
557        assertEquals(ttl, retrievedTtl);
558
559        Slice noTtlSlice = new Slice.Builder(uri)
560                .addText("Some text", null)
561                .addTimestamp(timestamp, null).build();
562        SliceMetadata si2 = SliceMetadata.from(mContext, noTtlSlice);
563        long retrievedTtl2 = si2.getExpiry();
564        assertEquals(0, retrievedTtl2);
565    }
566
567    @Test
568    public void testGetLastUpdated() {
569        Uri uri = Uri.parse("content://pkg/slice");
570        long timestamp = System.currentTimeMillis();
571        long ttl = TimeUnit.DAYS.toMillis(1);
572        Slice ttlSlice = new Slice.Builder(uri)
573                .addText("Some text", null)
574                .addTimestamp(timestamp - 20, null)
575                .addTimestamp(timestamp, null, SliceHints.HINT_LAST_UPDATED)
576                .addTimestamp(ttl, null, SliceHints.HINT_TTL)
577                .build();
578
579        SliceMetadata si1 = SliceMetadata.from(mContext, ttlSlice);
580        long retrievedLastUpdated = si1.getLastUpdatedTime();
581        assertEquals(timestamp, retrievedLastUpdated);
582
583        Slice noTtlSlice = new Slice.Builder(uri)
584                .addText("Some text", null)
585                .addTimestamp(timestamp, null).build();
586
587        SliceMetadata si2 = SliceMetadata.from(mContext, noTtlSlice);
588        long retrievedLastUpdated2 = si2.getLastUpdatedTime();
589        assertEquals(0, retrievedLastUpdated2);
590    }
591
592    @Test
593    public void testIsPermissionSlice() {
594        Uri uri = Uri.parse("content://pkg/slice");
595        Slice permissionSlice =
596                SliceProviderCompat.createPermissionSlice(mContext, uri, mContext.getPackageName());
597
598        SliceMetadata metadata = SliceMetadata.from(mContext, permissionSlice);
599        assertEquals(true, metadata.isPermissionSlice());
600    }
601
602    private PendingIntent getIntent(String action) {
603        Intent intent = new Intent(action);
604        intent.setClassName(mContext.getPackageName(), SliceRenderActivity.class.getName());
605        return PendingIntent.getActivity(mContext, 0, intent, 0);
606    }
607
608    private void assertEquivalent(androidx.slice.core.SliceAction desired,
609            androidx.slice.core.SliceAction actual) {
610        assertEquals(desired.getTitle(), actual.getTitle());
611        assertEquals(desired.getContentDescription(), actual.getContentDescription());
612        assertEquals(desired.isToggle(), actual.isToggle());
613        assertEquals(desired.isDefaultToggle(), actual.isDefaultToggle());
614        assertEquals(desired.isChecked(), actual.isChecked());
615        assertEquals(desired.getPriority(), actual.getPriority());
616        assertEquals(desired.getIcon() == null, actual.getIcon() == null);
617        assertEquals(desired.getImageMode(), actual.getImageMode());
618    }
619}
620