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 Context.RECEIVER_EXPORTED_UNAUDITED); 145 Uri uri = BASE_URI.buildUpon().appendPath("action").build(); 146 Slice s = mSliceManager.bindSlice(uri, Collections.emptySet()); 147 assertEquals(uri, s.getUri()); 148 assertEquals(1, s.getItems().size()); 149 150 SliceItem item = s.getItems().get(0); 151 assertEquals(SliceItem.FORMAT_ACTION, item.getFormat()); 152 try { 153 item.getAction().send(); 154 } catch (CanceledException e) { 155 } 156 157 try { 158 latch.await(100, TimeUnit.MILLISECONDS); 159 } catch (InterruptedException e) { 160 e.printStackTrace(); 161 } 162 assertTrue(sFlag); 163 mContext.unregisterReceiver(receiver); 164 } 165 166 @Test testInt()167 public void testInt() { 168 assumeFalse(isSliceDisabled); 169 Uri uri = BASE_URI.buildUpon().appendPath("int").build(); 170 Slice s = mSliceManager.bindSlice(uri, Collections.emptySet()); 171 assertEquals(uri, s.getUri()); 172 assertEquals(1, s.getItems().size()); 173 174 SliceItem item = s.getItems().get(0); 175 assertEquals(SliceItem.FORMAT_INT, item.getFormat()); 176 assertEquals(0xff121212, item.getInt()); 177 } 178 179 @Test testTimestamp()180 public void testTimestamp() { 181 assumeFalse(isSliceDisabled); 182 Uri uri = BASE_URI.buildUpon().appendPath("timestamp").build(); 183 Slice s = mSliceManager.bindSlice(uri, 184 Collections.emptySet()); 185 assertEquals(uri, s.getUri()); 186 assertEquals(1, s.getItems().size()); 187 188 SliceItem item = s.getItems().get(0); 189 assertEquals(SliceItem.FORMAT_LONG, item.getFormat()); 190 assertEquals(43, item.getLong()); 191 } 192 193 @Test testHints()194 public void testHints() { 195 assumeFalse(isSliceDisabled); 196 // Note this tests that hints are propagated through to the client but not that any specific 197 // hints have any effects. 198 Uri uri = BASE_URI.buildUpon().appendPath("hints").build(); 199 Slice s = mSliceManager.bindSlice(uri, Collections.emptySet()); 200 assertEquals(uri, s.getUri()); 201 202 assertEquals(Arrays.asList(Slice.HINT_LIST), s.getHints()); 203 assertEquals(Arrays.asList(Slice.HINT_TITLE), s.getItems().get(0).getHints()); 204 assertEquals(Arrays.asList(Slice.HINT_NO_TINT, Slice.HINT_LARGE), 205 s.getItems().get(1).getHints()); 206 } 207 208 @Test testHasHints()209 public void testHasHints() { 210 assumeFalse(isSliceDisabled); 211 Uri uri = BASE_URI.buildUpon().appendPath("hints").build(); 212 Slice s = mSliceManager.bindSlice(uri, Collections.emptySet()); 213 214 assertTrue(s.getItems().get(0).hasHint(Slice.HINT_TITLE)); 215 assertFalse(s.getItems().get(0).hasHint(Slice.HINT_LIST)); 216 } 217 218 @Test testBundle()219 public void testBundle() { 220 assumeFalse(isSliceDisabled); 221 Uri uri = BASE_URI.buildUpon().appendPath("bundle").build(); 222 Slice s = mSliceManager.bindSlice(uri, Collections.emptySet()); 223 assertEquals(uri, s.getUri()); 224 assertEquals(1, s.getItems().size()); 225 226 SliceItem item = s.getItems().get(0); 227 assertEquals(SliceItem.FORMAT_BUNDLE, item.getFormat()); 228 Bundle b = item.getBundle(); 229 b.setClassLoader(getClass().getClassLoader()); 230 assertEquals(new TestParcel(), b.getParcelable("a")); 231 } 232 233 @Test testGetDescendants()234 public void testGetDescendants() { 235 assumeFalse(isSliceDisabled); 236 Collection<Uri> allUris = mSliceManager.getSliceDescendants(BASE_URI); 237 assertEquals(SliceProvider.PATHS.length, allUris.size()); 238 Iterator<Uri> it = allUris.iterator(); 239 for (int i = 0; i < SliceProvider.PATHS.length; i++) { 240 assertEquals(SliceProvider.PATHS[i], it.next().getPath()); 241 } 242 243 assertEquals(0, mSliceManager.getSliceDescendants( 244 BASE_URI.buildUpon().appendPath("/nothing").build()).size()); 245 } 246 247 @Test testGetSliceSpec()248 public void testGetSliceSpec() { 249 assumeFalse(isSliceDisabled); 250 Uri uri = BASE_URI.buildUpon().appendPath("spec").build(); 251 Slice s = mSliceManager.bindSlice(uri, Collections.emptySet()); 252 assertEquals(new SliceSpec(SliceProvider.SPEC_TYPE, SliceProvider.SPEC_REV), s.getSpec()); 253 } 254 } 255