1 /* 2 * Copyright (C) 2019 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 17 package com.android.cts.usespermissiondiffcertapp; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNotNull; 21 import static org.junit.Assert.assertTrue; 22 import static org.junit.Assert.fail; 23 24 import android.content.ClipData; 25 import android.content.ContentResolver; 26 import android.content.ContentValues; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.UriPermission; 30 import android.database.Cursor; 31 import android.net.Uri; 32 33 import androidx.test.InstrumentationRegistry; 34 35 import java.io.IOException; 36 import java.util.List; 37 38 public class Asserts { getContext()39 private static Context getContext() { 40 return InstrumentationRegistry.getTargetContext(); 41 } 42 assertAccess(ClipData clip, int mode)43 static void assertAccess(ClipData clip, int mode) { 44 for (int i = 0; i < clip.getItemCount(); i++) { 45 ClipData.Item item = clip.getItemAt(i); 46 Uri uri = item.getUri(); 47 if (uri != null) { 48 assertAccess(uri, mode); 49 } else { 50 Intent intent = item.getIntent(); 51 uri = intent.getData(); 52 if (uri != null) { 53 assertAccess(uri, mode); 54 } 55 ClipData intentClip = intent.getClipData(); 56 if (intentClip != null) { 57 assertAccess(intentClip, mode); 58 } 59 } 60 } 61 } 62 assertAccess(Uri uri, int mode)63 static void assertAccess(Uri uri, int mode) { 64 if ((mode & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 65 assertReadingContentUriAllowed(uri); 66 } else { 67 assertReadingContentUriNotAllowed(uri, null); 68 } 69 if ((mode & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 70 assertWritingContentUriAllowed(uri); 71 } else { 72 assertWritingContentUriNotAllowed(uri, null); 73 } 74 } 75 assertReadingContentUriNotAllowed(Uri uri, String msg)76 static void assertReadingContentUriNotAllowed(Uri uri, String msg) { 77 try { 78 getContext().getContentResolver().query(uri, null, null, null, null); 79 fail("expected SecurityException reading " + uri + ": " + msg); 80 } catch (SecurityException expected) { 81 assertNotNull("security exception's error message.", expected.getMessage()); 82 } 83 } 84 assertReadingContentUriAllowed(Uri uri)85 static void assertReadingContentUriAllowed(Uri uri) { 86 try { 87 getContext().getContentResolver().query(uri, null, null, null, null); 88 } catch (SecurityException e) { 89 fail("unexpected SecurityException reading " + uri + ": " + e.getMessage()); 90 } 91 } 92 assertReadingClipNotAllowed(ClipData clip)93 static void assertReadingClipNotAllowed(ClipData clip) { 94 assertReadingClipNotAllowed(clip, null); 95 } 96 assertReadingClipNotAllowed(ClipData clip, String msg)97 static void assertReadingClipNotAllowed(ClipData clip, String msg) { 98 for (int i=0; i<clip.getItemCount(); i++) { 99 ClipData.Item item = clip.getItemAt(i); 100 Uri uri = item.getUri(); 101 if (uri != null) { 102 assertReadingContentUriNotAllowed(uri, msg); 103 } else { 104 Intent intent = item.getIntent(); 105 uri = intent.getData(); 106 if (uri != null) { 107 assertReadingContentUriNotAllowed(uri, msg); 108 } 109 ClipData intentClip = intent.getClipData(); 110 if (intentClip != null) { 111 assertReadingClipNotAllowed(intentClip, msg); 112 } 113 } 114 } 115 } 116 assertOpenFileDescriptorModeNotAllowed(Uri uri, String msg, String mode)117 static void assertOpenFileDescriptorModeNotAllowed(Uri uri, String msg, String mode) { 118 try { 119 getContext().getContentResolver().openFileDescriptor(uri, mode).close(); 120 fail("expected SecurityException writing " + uri + ": " + msg); 121 } catch (IOException e) { 122 throw new IllegalStateException(e); 123 } catch (SecurityException expected) { 124 assertNotNull("security exception's error message.", expected.getMessage()); 125 } 126 } 127 assertContentUriAllowed(Uri uri)128 static void assertContentUriAllowed(Uri uri) { 129 assertReadingContentUriAllowed(uri); 130 assertWritingContentUriAllowed(uri); 131 } 132 assertContentUriNotAllowed(Uri uri, String msg)133 static void assertContentUriNotAllowed(Uri uri, String msg) { 134 assertReadingContentUriNotAllowed(uri, msg); 135 assertWritingContentUriNotAllowed(uri, msg); 136 } 137 assertWritingContentUriNotAllowed(Uri uri, String msg)138 static void assertWritingContentUriNotAllowed(Uri uri, String msg) { 139 final ContentResolver resolver = getContext().getContentResolver(); 140 try { 141 resolver.insert(uri, new ContentValues()); 142 fail("expected SecurityException inserting " + uri + ": " + msg); 143 } catch (SecurityException expected) { 144 assertNotNull("security exception's error message.", expected.getMessage()); 145 } 146 147 try { 148 resolver.update(uri, new ContentValues(), null, null); 149 fail("expected SecurityException updating " + uri + ": " + msg); 150 } catch (SecurityException expected) { 151 assertNotNull("security exception's error message.", expected.getMessage()); 152 } 153 154 try { 155 resolver.delete(uri, null, null); 156 fail("expected SecurityException deleting " + uri + ": " + msg); 157 } catch (SecurityException expected) { 158 assertNotNull("security exception's error message.", expected.getMessage()); 159 } 160 161 try { 162 getContext().getContentResolver().openOutputStream(uri).close(); 163 fail("expected SecurityException writing " + uri + ": " + msg); 164 } catch (IOException e) { 165 throw new IllegalStateException(e); 166 } catch (SecurityException expected) { 167 assertNotNull("security exception's error message.", expected.getMessage()); 168 } 169 170 assertOpenFileDescriptorModeNotAllowed(uri, msg, "w"); 171 assertOpenFileDescriptorModeNotAllowed(uri, msg, "wt"); 172 assertOpenFileDescriptorModeNotAllowed(uri, msg, "wa"); 173 assertOpenFileDescriptorModeNotAllowed(uri, msg, "rw"); 174 assertOpenFileDescriptorModeNotAllowed(uri, msg, "rwt"); 175 } 176 assertWritingContentUriAllowed(Uri uri)177 static void assertWritingContentUriAllowed(Uri uri) { 178 final ContentResolver resolver = getContext().getContentResolver(); 179 try { 180 resolver.insert(uri, new ContentValues()); 181 resolver.update(uri, new ContentValues(), null, null); 182 resolver.delete(uri, null, null); 183 184 resolver.openOutputStream(uri).close(); 185 resolver.openFileDescriptor(uri, "w").close(); 186 resolver.openFileDescriptor(uri, "wt").close(); 187 resolver.openFileDescriptor(uri, "wa").close(); 188 resolver.openFileDescriptor(uri, "rw").close(); 189 resolver.openFileDescriptor(uri, "rwt").close(); 190 } catch (IOException e) { 191 fail("unexpected IOException writing " + uri + ": " + e.getMessage()); 192 } catch (SecurityException e) { 193 fail("unexpected SecurityException writing " + uri + ": " + e.getMessage()); 194 } 195 } 196 assertWritingClipNotAllowed(ClipData clip)197 static void assertWritingClipNotAllowed(ClipData clip) { 198 assertWritingClipNotAllowed(clip, null); 199 } 200 assertWritingClipNotAllowed(ClipData clip, String msg)201 static void assertWritingClipNotAllowed(ClipData clip, String msg) { 202 for (int i=0; i<clip.getItemCount(); i++) { 203 ClipData.Item item = clip.getItemAt(i); 204 Uri uri = item.getUri(); 205 if (uri != null) { 206 assertWritingContentUriNotAllowed(uri, msg); 207 } else { 208 Intent intent = item.getIntent(); 209 uri = intent.getData(); 210 if (uri != null) { 211 assertWritingContentUriNotAllowed(uri, msg); 212 } 213 ClipData intentClip = intent.getClipData(); 214 if (intentClip != null) { 215 assertWritingClipNotAllowed(intentClip, msg); 216 } 217 } 218 } 219 } 220 assertReadingClipAllowed(ClipData clip)221 static void assertReadingClipAllowed(ClipData clip) { 222 for (int i=0; i<clip.getItemCount(); i++) { 223 ClipData.Item item = clip.getItemAt(i); 224 Uri uri = item.getUri(); 225 if (uri != null) { 226 Cursor c = getContext().getContentResolver().query(uri, 227 null, null, null, null); 228 if (c != null) { 229 c.close(); 230 } 231 } else { 232 Intent intent = item.getIntent(); 233 uri = intent.getData(); 234 if (uri != null) { 235 Cursor c = getContext().getContentResolver().query(uri, 236 null, null, null, null); 237 if (c != null) { 238 c.close(); 239 } 240 } 241 ClipData intentClip = intent.getClipData(); 242 if (intentClip != null) { 243 assertReadingClipAllowed(intentClip); 244 } 245 } 246 } 247 } 248 assertWritingClipAllowed(ClipData clip)249 static void assertWritingClipAllowed(ClipData clip) { 250 for (int i=0; i<clip.getItemCount(); i++) { 251 ClipData.Item item = clip.getItemAt(i); 252 Uri uri = item.getUri(); 253 if (uri != null) { 254 getContext().getContentResolver().insert(uri, new ContentValues()); 255 } else { 256 Intent intent = item.getIntent(); 257 uri = intent.getData(); 258 if (uri != null) { 259 getContext().getContentResolver().insert(uri, new ContentValues()); 260 } 261 ClipData intentClip = intent.getClipData(); 262 if (intentClip != null) { 263 assertWritingClipAllowed(intentClip); 264 } 265 } 266 } 267 } 268 269 assertClipDataEquals(ClipData expected, ClipData actual)270 static void assertClipDataEquals(ClipData expected, ClipData actual) { 271 assertEquals(expected.getItemCount(), actual.getItemCount()); 272 for (int i = 0; i < expected.getItemCount(); i++) { 273 final ClipData.Item expectedItem = expected.getItemAt(i); 274 final ClipData.Item actualItem = actual.getItemAt(i); 275 assertEquals(expectedItem.getText(), actualItem.getText()); 276 assertEquals(expectedItem.getHtmlText(), actualItem.getHtmlText()); 277 assertEquals(expectedItem.getIntent(), actualItem.getIntent()); 278 assertEquals(expectedItem.getUri(), actualItem.getUri()); 279 } 280 } 281 assertNoPersistedUriPermission()282 static void assertNoPersistedUriPermission() { 283 assertPersistedUriPermission(null, 0, -1, -1); 284 } 285 assertPersistedUriPermission(Uri uri, int flags, long before, long after)286 static void assertPersistedUriPermission(Uri uri, int flags, long before, long after) { 287 // Assert local 288 final List<UriPermission> perms = getContext() 289 .getContentResolver().getPersistedUriPermissions(); 290 if (uri != null) { 291 assertEquals("expected exactly one permission", 1, perms.size()); 292 293 final UriPermission perm = perms.get(0); 294 assertEquals("unexpected uri", uri, perm.getUri()); 295 296 final long actual = perm.getPersistedTime(); 297 if (before != -1) { 298 assertTrue("found " + actual + " before " + before, actual >= before); 299 } 300 if (after != -1) { 301 assertTrue("found " + actual + " after " + after, actual <= after); 302 } 303 304 final boolean expectedRead = (flags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0; 305 final boolean expectedWrite = (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0; 306 assertEquals("unexpected read status", expectedRead, perm.isReadPermission()); 307 assertEquals("unexpected write status", expectedWrite, perm.isWritePermission()); 308 309 } else { 310 assertEquals("expected zero permissions", 0, perms.size()); 311 } 312 313 Utils.verifyOutgoingPersisted(uri); 314 } 315 } 316