1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package android.slice.cts;
16 
17 import static org.junit.Assert.assertEquals;
18 import static org.junit.Assert.assertFalse;
19 import static org.junit.Assert.assertNotEquals;
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assume.assumeFalse;
22 
23 import android.app.PendingIntent.CanceledException;
24 import android.app.slice.Slice;
25 import android.app.slice.SliceItem;
26 import android.app.slice.SliceManager;
27 import android.app.slice.SliceSpec;
28 import android.content.BroadcastReceiver;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.IntentFilter;
32 import android.content.pm.PackageManager;
33 import android.graphics.drawable.Icon;
34 import android.net.Uri;
35 import android.os.Bundle;
36 import android.slice.cts.SliceProvider.TestParcel;
37 
38 import androidx.test.InstrumentationRegistry;
39 import androidx.test.runner.AndroidJUnit4;
40 
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.Arrays;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.Iterator;
48 import java.util.concurrent.CountDownLatch;
49 import java.util.concurrent.TimeUnit;
50 
51 @RunWith(AndroidJUnit4.class)
52 public class SliceBindingTest {
53 
54     public static boolean sFlag = false;
55 
56     private static final Uri BASE_URI = Uri.parse("content://android.slice.cts/");
57     private final Context mContext = InstrumentationRegistry.getContext();
58     private final SliceManager mSliceManager = mContext.getSystemService(SliceManager.class);
59     private boolean isSliceDisabled = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SLICES_DISABLED);
60 
61     @Test
testProcess()62     public void testProcess() {
63         assumeFalse(isSliceDisabled);
64         sFlag = false;
65         mSliceManager.bindSlice(BASE_URI.buildUpon().appendPath("set_flag").build(),
66                 Collections.emptySet());
67         assertFalse(sFlag);
68     }
69 
70     @Test
testType()71     public void testType() {
72         assertEquals(SliceProvider.SLICE_TYPE,
73                 mContext.getContentResolver().getType(BASE_URI));
74     }
75 
76     @Test
testSliceUri()77     public void testSliceUri() {
78         assumeFalse(isSliceDisabled);
79         Slice s = mSliceManager.bindSlice(BASE_URI,
80                 Collections.emptySet());
81         assertEquals(BASE_URI, s.getUri());
82     }
83 
84     @Test
testSubSlice()85     public void testSubSlice() {
86         assumeFalse(isSliceDisabled);
87         Uri uri = BASE_URI.buildUpon().appendPath("subslice").build();
88         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
89         assertEquals(uri, s.getUri());
90         assertEquals(1, s.getItems().size());
91 
92         SliceItem item = s.getItems().get(0);
93         assertEquals(SliceItem.FORMAT_SLICE, item.getFormat());
94         assertEquals("subslice", item.getSubType());
95         // The item should start with the same Uri as the parent, but be different.
96         assertTrue(item.getSlice().getUri().toString().startsWith(uri.toString()));
97         assertNotEquals(uri, item.getSlice().getUri());
98     }
99 
100     @Test
testText()101     public void testText() {
102         assumeFalse(isSliceDisabled);
103         Uri uri = BASE_URI.buildUpon().appendPath("text").build();
104         Slice s = mSliceManager.bindSlice(uri,
105                 Collections.emptySet());
106         assertEquals(uri, s.getUri());
107         assertEquals(1, s.getItems().size());
108 
109         SliceItem item = s.getItems().get(0);
110         assertEquals(SliceItem.FORMAT_TEXT, item.getFormat());
111         // TODO: Test spannables here.
112         assertEquals("Expected text", item.getText());
113     }
114 
115     @Test
testIcon()116     public void testIcon() {
117         assumeFalse(isSliceDisabled);
118         Uri uri = BASE_URI.buildUpon().appendPath("icon").build();
119         Slice s = mSliceManager.bindSlice(uri,
120                 Collections.emptySet());
121         assertEquals(uri, s.getUri());
122         assertEquals(1, s.getItems().size());
123 
124         SliceItem item = s.getItems().get(0);
125         assertEquals(SliceItem.FORMAT_IMAGE, item.getFormat());
126         assertEquals(Icon.createWithResource(mContext, R.drawable.size_48x48).toString(),
127                 item.getIcon().toString());
128     }
129 
130     @Test
testAction()131     public void testAction() {
132         assumeFalse(isSliceDisabled);
133         sFlag = false;
134         CountDownLatch latch = new CountDownLatch(1);
135         BroadcastReceiver receiver = new BroadcastReceiver() {
136             @Override
137             public void onReceive(Context context, Intent intent) {
138                 sFlag = true;
139                 latch.countDown();
140             }
141         };
142         mContext.registerReceiver(receiver,
143                 new IntentFilter(mContext.getPackageName() + ".action"));
144         Uri uri = BASE_URI.buildUpon().appendPath("action").build();
145         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
146         assertEquals(uri, s.getUri());
147         assertEquals(1, s.getItems().size());
148 
149         SliceItem item = s.getItems().get(0);
150         assertEquals(SliceItem.FORMAT_ACTION, item.getFormat());
151         try {
152             item.getAction().send();
153         } catch (CanceledException e) {
154         }
155 
156         try {
157             latch.await(100, TimeUnit.MILLISECONDS);
158         } catch (InterruptedException e) {
159             e.printStackTrace();
160         }
161         assertTrue(sFlag);
162         mContext.unregisterReceiver(receiver);
163     }
164 
165     @Test
testInt()166     public void testInt() {
167         assumeFalse(isSliceDisabled);
168         Uri uri = BASE_URI.buildUpon().appendPath("int").build();
169         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
170         assertEquals(uri, s.getUri());
171         assertEquals(1, s.getItems().size());
172 
173         SliceItem item = s.getItems().get(0);
174         assertEquals(SliceItem.FORMAT_INT, item.getFormat());
175         assertEquals(0xff121212, item.getInt());
176     }
177 
178     @Test
testTimestamp()179     public void testTimestamp() {
180         assumeFalse(isSliceDisabled);
181         Uri uri = BASE_URI.buildUpon().appendPath("timestamp").build();
182         Slice s = mSliceManager.bindSlice(uri,
183                 Collections.emptySet());
184         assertEquals(uri, s.getUri());
185         assertEquals(1, s.getItems().size());
186 
187         SliceItem item = s.getItems().get(0);
188         assertEquals(SliceItem.FORMAT_LONG, item.getFormat());
189         assertEquals(43, item.getLong());
190     }
191 
192     @Test
testHints()193     public void testHints() {
194         assumeFalse(isSliceDisabled);
195         // Note this tests that hints are propagated through to the client but not that any specific
196         // hints have any effects.
197         Uri uri = BASE_URI.buildUpon().appendPath("hints").build();
198         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
199         assertEquals(uri, s.getUri());
200 
201         assertEquals(Arrays.asList(Slice.HINT_LIST), s.getHints());
202         assertEquals(Arrays.asList(Slice.HINT_TITLE), s.getItems().get(0).getHints());
203         assertEquals(Arrays.asList(Slice.HINT_NO_TINT, Slice.HINT_LARGE),
204                 s.getItems().get(1).getHints());
205     }
206 
207     @Test
testHasHints()208     public void testHasHints() {
209         assumeFalse(isSliceDisabled);
210         Uri uri = BASE_URI.buildUpon().appendPath("hints").build();
211         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
212 
213         assertTrue(s.getItems().get(0).hasHint(Slice.HINT_TITLE));
214         assertFalse(s.getItems().get(0).hasHint(Slice.HINT_LIST));
215     }
216 
217     @Test
testBundle()218     public void testBundle() {
219         assumeFalse(isSliceDisabled);
220         Uri uri = BASE_URI.buildUpon().appendPath("bundle").build();
221         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
222         assertEquals(uri, s.getUri());
223         assertEquals(1, s.getItems().size());
224 
225         SliceItem item = s.getItems().get(0);
226         assertEquals(SliceItem.FORMAT_BUNDLE, item.getFormat());
227         Bundle b = item.getBundle();
228         b.setClassLoader(getClass().getClassLoader());
229         assertEquals(new TestParcel(), b.getParcelable("a"));
230     }
231 
232     @Test
testGetDescendants()233     public void testGetDescendants() {
234         assumeFalse(isSliceDisabled);
235         Collection<Uri> allUris = mSliceManager.getSliceDescendants(BASE_URI);
236         assertEquals(SliceProvider.PATHS.length, allUris.size());
237         Iterator<Uri> it = allUris.iterator();
238         for (int i = 0; i < SliceProvider.PATHS.length; i++) {
239             assertEquals(SliceProvider.PATHS[i], it.next().getPath());
240         }
241 
242         assertEquals(0, mSliceManager.getSliceDescendants(
243                 BASE_URI.buildUpon().appendPath("/nothing").build()).size());
244     }
245 
246     @Test
testGetSliceSpec()247     public void testGetSliceSpec() {
248         assumeFalse(isSliceDisabled);
249         Uri uri = BASE_URI.buildUpon().appendPath("spec").build();
250         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
251         assertEquals(new SliceSpec(SliceProvider.SPEC_TYPE, SliceProvider.SPEC_REV), s.getSpec());
252     }
253 }
254