1 /* 2 * Copyright (C) 2008 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 android.content.cts; 18 19 import com.android.cts.stub.R; 20 21 import dalvik.annotation.TestLevel; 22 import dalvik.annotation.TestTargetClass; 23 import dalvik.annotation.TestTargetNew; 24 import dalvik.annotation.TestTargets; 25 import dalvik.annotation.ToBeFixed; 26 27 import android.accounts.Account; 28 import android.content.ContentResolver; 29 import android.content.ContentValues; 30 import android.content.Context; 31 import android.content.res.AssetFileDescriptor; 32 import android.database.ContentObserver; 33 import android.database.Cursor; 34 import android.net.Uri; 35 import android.os.Bundle; 36 import android.os.ParcelFileDescriptor; 37 import android.test.AndroidTestCase; 38 import android.view.animation.cts.DelayedCheck; 39 40 import java.io.FileNotFoundException; 41 import java.io.IOException; 42 import java.io.InputStream; 43 import java.io.OutputStream; 44 45 @TestTargetClass(ContentResolver.class) 46 public class ContentResolverTest extends AndroidTestCase { 47 private final static String COLUMN_ID_NAME = "_id"; 48 private final static String COLUMN_KEY_NAME = "key"; 49 private final static String COLUMN_VALUE_NAME = "value"; 50 51 private static final String AUTHORITY = "ctstest"; 52 private static final Uri TABLE1_URI = Uri.parse("content://" + AUTHORITY + "/testtable1/"); 53 private static final Uri TABLE2_URI = Uri.parse("content://" + AUTHORITY + "/testtable2/"); 54 55 private static final Account ACCOUNT = new Account("cts", "cts"); 56 57 private static final String KEY1 = "key1"; 58 private static final String KEY2 = "key2"; 59 private static final String KEY3 = "key3"; 60 private static final int VALUE1 = 1; 61 private static final int VALUE2 = 2; 62 private static final int VALUE3 = 3; 63 64 private static final String TEST_PACKAGE_NAME = "com.android.cts.stub"; 65 66 private Context mContext; 67 private ContentResolver mContentResolver; 68 private Cursor mCursor; 69 70 @Override 71 protected void setUp() throws Exception { 72 super.setUp(); 73 74 mContext = getContext(); 75 mContentResolver = mContext.getContentResolver(); 76 77 // add three rows to database when every test case start. 78 ContentValues values = new ContentValues(); 79 80 values.put(COLUMN_KEY_NAME, KEY1); 81 values.put(COLUMN_VALUE_NAME, VALUE1); 82 mContentResolver.insert(TABLE1_URI, values); 83 84 values.put(COLUMN_KEY_NAME, KEY2); 85 values.put(COLUMN_VALUE_NAME, VALUE2); 86 mContentResolver.insert(TABLE1_URI, values); 87 88 values.put(COLUMN_KEY_NAME, KEY3); 89 values.put(COLUMN_VALUE_NAME, VALUE3); 90 mContentResolver.insert(TABLE1_URI, values); 91 } 92 93 @Override 94 protected void tearDown() throws Exception { 95 mContentResolver.delete(TABLE1_URI, null, null); 96 if ( null != mCursor && !mCursor.isClosed() ) { 97 mCursor.close(); 98 } 99 super.tearDown(); 100 } 101 102 @TestTargetNew( 103 level = TestLevel.COMPLETE, 104 method = "ContentResolver", 105 args = {android.content.Context.class} 106 ) 107 @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete") 108 public void testConstructor() { 109 assertNotNull(mContentResolver); 110 } 111 112 @TestTargetNew( 113 level = TestLevel.COMPLETE, 114 method = "getType", 115 args = {android.net.Uri.class} 116 ) 117 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 118 "ContentResolver#getType(Uri) when the input Uri is null") 119 public void testGetType() { 120 String type1 = mContentResolver.getType(TABLE1_URI); 121 assertTrue(type1.startsWith(ContentResolver.CURSOR_DIR_BASE_TYPE, 0)); 122 123 String type2 = mContentResolver.getType(TABLE2_URI); 124 assertTrue(type2.startsWith(ContentResolver.CURSOR_DIR_BASE_TYPE, 0)); 125 126 Uri invalidUri = Uri.parse("abc"); 127 assertNull(mContentResolver.getType(invalidUri)); 128 129 try { 130 mContentResolver.getType(null); 131 fail("did not throw NullPointerException when Uri is null."); 132 } catch (NullPointerException e) { 133 //expected. 134 } 135 } 136 137 @TestTargetNew( 138 level = TestLevel.COMPLETE, 139 method = "query", 140 args = {android.net.Uri.class, java.lang.String[].class, java.lang.String.class, 141 java.lang.String[].class, java.lang.String.class} 142 ) 143 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 144 "ContentResolver#query(Uri, String[], String, String[], String) when the input " + 145 "param Uri is null") 146 public void testQuery() { 147 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 148 149 assertNotNull(mCursor); 150 assertEquals(3, mCursor.getCount()); 151 assertEquals(3, mCursor.getColumnCount()); 152 153 mCursor.moveToLast(); 154 assertEquals(3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 155 assertEquals(KEY3, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 156 assertEquals(VALUE3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 157 158 mCursor.moveToPrevious(); 159 assertEquals(2, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 160 assertEquals(KEY2, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 161 assertEquals(VALUE2, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 162 mCursor.close(); 163 164 String selection = COLUMN_ID_NAME + "=1"; 165 mCursor = mContentResolver.query(TABLE1_URI, null, selection, null, null); 166 assertNotNull(mCursor); 167 assertEquals(1, mCursor.getCount()); 168 assertEquals(3, mCursor.getColumnCount()); 169 170 mCursor.moveToFirst(); 171 assertEquals(1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 172 assertEquals(KEY1, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 173 assertEquals(VALUE1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 174 mCursor.close(); 175 176 selection = COLUMN_KEY_NAME + "=\"" + KEY3 + "\""; 177 mCursor = mContentResolver.query(TABLE1_URI, null, selection, null, null); 178 assertNotNull(mCursor); 179 assertEquals(1, mCursor.getCount()); 180 assertEquals(3, mCursor.getColumnCount()); 181 182 mCursor.moveToFirst(); 183 assertEquals(3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 184 assertEquals(KEY3, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 185 assertEquals(VALUE3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 186 mCursor.close(); 187 188 try { 189 mContentResolver.query(null, null, null, null, null); 190 fail("did not throw NullPointerException when uri is null."); 191 } catch (NullPointerException e) { 192 //expected. 193 } 194 } 195 196 @TestTargetNew( 197 level = TestLevel.COMPLETE, 198 method = "openInputStream", 199 args = {android.net.Uri.class} 200 ) 201 public void testOpenInputStream() throws IOException { 202 final Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + 203 "://" + TEST_PACKAGE_NAME + "/" + R.drawable.pass); 204 205 InputStream is = mContentResolver.openInputStream(uri); 206 assertNotNull(is); 207 is.close(); 208 209 final Uri invalidUri = Uri.parse("abc"); 210 try { 211 mContentResolver.openInputStream(invalidUri); 212 fail("did not throw FileNotFoundException when uri is invalid."); 213 } catch (FileNotFoundException e) { 214 //expected. 215 } 216 } 217 218 @TestTargets({ 219 @TestTargetNew( 220 level = TestLevel.COMPLETE, 221 method = "openOutputStream", 222 args = {android.net.Uri.class} 223 ), 224 @TestTargetNew( 225 level = TestLevel.COMPLETE, 226 method = "openOutputStream", 227 args = {android.net.Uri.class, java.lang.String.class} 228 ) 229 }) 230 public void testOpenOutputStream() throws IOException { 231 Uri uri = Uri.parse(ContentResolver.SCHEME_FILE + "://" + 232 getContext().getCacheDir().getAbsolutePath() + 233 "/temp.jpg"); 234 OutputStream os = mContentResolver.openOutputStream(uri); 235 assertNotNull(os); 236 os.close(); 237 238 os = mContentResolver.openOutputStream(uri, "wa"); 239 assertNotNull(os); 240 os.close(); 241 242 uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + 243 "://" + TEST_PACKAGE_NAME + "/" + R.raw.testimage); 244 try { 245 mContentResolver.openOutputStream(uri); 246 fail("did not throw FileNotFoundException when scheme is not accepted."); 247 } catch (FileNotFoundException e) { 248 //expected. 249 } 250 251 try { 252 mContentResolver.openOutputStream(uri, "w"); 253 fail("did not throw FileNotFoundException when scheme is not accepted."); 254 } catch (FileNotFoundException e) { 255 //expected. 256 } 257 258 Uri invalidUri = Uri.parse("abc"); 259 try { 260 mContentResolver.openOutputStream(invalidUri); 261 fail("did not throw FileNotFoundException when uri is invalid."); 262 } catch (FileNotFoundException e) { 263 //expected. 264 } 265 266 try { 267 mContentResolver.openOutputStream(invalidUri, "w"); 268 fail("did not throw FileNotFoundException when uri is invalid."); 269 } catch (FileNotFoundException e) { 270 //expected. 271 } 272 } 273 274 @TestTargetNew( 275 level = TestLevel.COMPLETE, 276 method = "openAssetFileDescriptor", 277 args = {android.net.Uri.class, java.lang.String.class} 278 ) 279 public void testOpenAssetFileDescriptor() throws IOException { 280 Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + 281 "://" + TEST_PACKAGE_NAME + "/" + R.raw.testimage); 282 283 AssetFileDescriptor afd = mContentResolver.openAssetFileDescriptor(uri, "r"); 284 assertNotNull(afd); 285 afd.close(); 286 287 try { 288 mContentResolver.openAssetFileDescriptor(uri, "d"); 289 fail("did not throw FileNotFoundException when mode is unknown."); 290 } catch (FileNotFoundException e) { 291 //expected. 292 } 293 294 Uri invalidUri = Uri.parse("abc"); 295 try { 296 mContentResolver.openAssetFileDescriptor(invalidUri, "r"); 297 fail("did not throw FileNotFoundException when uri is invalid."); 298 } catch (FileNotFoundException e) { 299 //expected. 300 } 301 } 302 303 @TestTargetNew( 304 level = TestLevel.COMPLETE, 305 method = "openFileDescriptor", 306 args = {android.net.Uri.class, java.lang.String.class} 307 ) 308 public void testOpenFileDescriptor() throws IOException { 309 Uri uri = Uri.parse(ContentResolver.SCHEME_FILE + "://" + 310 getContext().getCacheDir().getAbsolutePath() + 311 "/temp.jpg"); 312 ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(uri, "w"); 313 assertNotNull(pfd); 314 pfd.close(); 315 316 try { 317 mContentResolver.openFileDescriptor(uri, "d"); 318 fail("did not throw FileNotFoundException when mode is unknown."); 319 } catch (FileNotFoundException e) { 320 //expected. 321 } 322 323 Uri invalidUri = Uri.parse("abc"); 324 try { 325 mContentResolver.openFileDescriptor(invalidUri, "w"); 326 fail("did not throw FileNotFoundException when uri is invalid."); 327 } catch (FileNotFoundException e) { 328 //expected. 329 } 330 331 uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + 332 "://" + TEST_PACKAGE_NAME + "/" + R.raw.testimage); 333 try { 334 mContentResolver.openFileDescriptor(uri, "w"); 335 fail("did not throw FileNotFoundException when scheme is not accepted."); 336 } catch (FileNotFoundException e) { 337 //expected. 338 } 339 } 340 341 @TestTargetNew( 342 level = TestLevel.COMPLETE, 343 method = "insert", 344 args = {android.net.Uri.class, android.content.ContentValues.class} 345 ) 346 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 347 "ContentResolver#insert(Uri, ContentValues) when the input Uri are null") 348 public void testInsert() { 349 String key4 = "key4"; 350 String key5 = "key5"; 351 int value4 = 4; 352 int value5 = 5; 353 String key4Selection = COLUMN_KEY_NAME + "=\"" + key4 + "\""; 354 355 mCursor = mContentResolver.query(TABLE1_URI, null, key4Selection, null, null); 356 assertEquals(0, mCursor.getCount()); 357 mCursor.close(); 358 359 ContentValues values = new ContentValues(); 360 values.put(COLUMN_KEY_NAME, key4); 361 values.put(COLUMN_VALUE_NAME, value4); 362 Uri uri = mContentResolver.insert(TABLE1_URI, values); 363 assertNotNull(uri); 364 365 mCursor = mContentResolver.query(TABLE1_URI, null, key4Selection, null, null); 366 assertNotNull(mCursor); 367 assertEquals(1, mCursor.getCount()); 368 369 mCursor.moveToFirst(); 370 assertEquals(4, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 371 assertEquals(key4, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 372 assertEquals(value4, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 373 mCursor.close(); 374 375 values.put(COLUMN_KEY_NAME, key5); 376 values.put(COLUMN_VALUE_NAME, value5); 377 uri = mContentResolver.insert(TABLE1_URI, values); 378 assertNotNull(uri); 379 380 // check returned uri 381 mCursor = mContentResolver.query(uri, null, null, null, null); 382 assertNotNull(mCursor); 383 assertEquals(1, mCursor.getCount()); 384 385 mCursor.moveToLast(); 386 assertEquals(5, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 387 assertEquals(key5, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 388 assertEquals(value5, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 389 mCursor.close(); 390 391 try { 392 mContentResolver.insert(null, values); 393 fail("did not throw NullPointerException when uri is null."); 394 } catch (NullPointerException e) { 395 //expected. 396 } 397 } 398 399 @TestTargetNew( 400 level = TestLevel.COMPLETE, 401 method = "bulkInsert", 402 args = {android.net.Uri.class, android.content.ContentValues[].class} 403 ) 404 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 405 "ContentResolver#bulkInsert(Uri, ContentValues[]) when the input Uri are null") 406 public void testBulkInsert() { 407 String key4 = "key4"; 408 String key5 = "key5"; 409 int value4 = 4; 410 int value5 = 5; 411 412 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 413 assertNotNull(mCursor); 414 assertEquals(3, mCursor.getCount()); 415 mCursor.close(); 416 417 ContentValues[] cvs = new ContentValues[2]; 418 cvs[0] = new ContentValues(); 419 cvs[0].put(COLUMN_KEY_NAME, key4); 420 cvs[0].put(COLUMN_VALUE_NAME, value4); 421 422 cvs[1] = new ContentValues(); 423 cvs[1].put(COLUMN_KEY_NAME, key5); 424 cvs[1].put(COLUMN_VALUE_NAME, value5); 425 426 assertEquals(2, mContentResolver.bulkInsert(TABLE1_URI, cvs)); 427 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 428 assertNotNull(mCursor); 429 assertEquals(5, mCursor.getCount()); 430 431 mCursor.moveToLast(); 432 assertEquals(5, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 433 assertEquals(key5, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 434 assertEquals(value5, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 435 436 mCursor.moveToPrevious(); 437 assertEquals(4, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 438 assertEquals(key4, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 439 assertEquals(value4, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 440 mCursor.close(); 441 442 try { 443 mContentResolver.bulkInsert(null, cvs); 444 fail("did not throw NullPointerException when uri is null."); 445 } catch (NullPointerException e) { 446 //expected. 447 } 448 } 449 450 @TestTargetNew( 451 level = TestLevel.COMPLETE, 452 method = "delete", 453 args = {android.net.Uri.class, java.lang.String.class, java.lang.String[].class} 454 ) 455 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 456 "ContentResolver#delete(Uri, String, String[]) when the input Uri are null") 457 public void testDelete() { 458 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 459 assertNotNull(mCursor); 460 assertEquals(3, mCursor.getCount()); 461 mCursor.close(); 462 463 assertEquals(3, mContentResolver.delete(TABLE1_URI, null, null)); 464 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 465 assertNotNull(mCursor); 466 assertEquals(0, mCursor.getCount()); 467 mCursor.close(); 468 469 // add three rows to database. 470 ContentValues values = new ContentValues(); 471 values.put(COLUMN_KEY_NAME, KEY1); 472 values.put(COLUMN_VALUE_NAME, VALUE1); 473 mContentResolver.insert(TABLE1_URI, values); 474 475 values.put(COLUMN_KEY_NAME, KEY2); 476 values.put(COLUMN_VALUE_NAME, VALUE2); 477 mContentResolver.insert(TABLE1_URI, values); 478 479 values.put(COLUMN_KEY_NAME, KEY3); 480 values.put(COLUMN_VALUE_NAME, VALUE3); 481 mContentResolver.insert(TABLE1_URI, values); 482 483 // test delete row using selection 484 String selection = COLUMN_ID_NAME + "=2"; 485 assertEquals(1, mContentResolver.delete(TABLE1_URI, selection, null)); 486 487 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 488 assertNotNull(mCursor); 489 assertEquals(2, mCursor.getCount()); 490 491 mCursor.moveToFirst(); 492 assertEquals(1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 493 assertEquals(KEY1, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 494 assertEquals(VALUE1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 495 496 mCursor.moveToNext(); 497 assertEquals(3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 498 assertEquals(KEY3, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 499 assertEquals(VALUE3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 500 mCursor.close(); 501 502 selection = COLUMN_VALUE_NAME + "=3"; 503 assertEquals(1, mContentResolver.delete(TABLE1_URI, selection, null)); 504 505 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 506 assertNotNull(mCursor); 507 assertEquals(1, mCursor.getCount()); 508 509 mCursor.moveToFirst(); 510 assertEquals(1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 511 assertEquals(KEY1, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 512 assertEquals(VALUE1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 513 mCursor.close(); 514 515 selection = COLUMN_KEY_NAME + "=\"" + KEY1 + "\""; 516 assertEquals(1, mContentResolver.delete(TABLE1_URI, selection, null)); 517 518 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 519 assertNotNull(mCursor); 520 assertEquals(0, mCursor.getCount()); 521 mCursor.close(); 522 523 try { 524 mContentResolver.delete(null, null, null); 525 fail("did not throw NullPointerException when uri is null."); 526 } catch (NullPointerException e) { 527 //expected. 528 } 529 } 530 531 @TestTargetNew( 532 level = TestLevel.COMPLETE, 533 method = "update", 534 args = {android.net.Uri.class, android.content.ContentValues.class, 535 java.lang.String.class, java.lang.String[].class} 536 ) 537 @ToBeFixed(bug = "1695243", explanation = "The javadoc says \"return the URL of the " + 538 "newly created row\", but actually it return an integer.") 539 public void testUpdate() { 540 ContentValues values = new ContentValues(); 541 String key10 = "key10"; 542 String key20 = "key20"; 543 int value10 = 10; 544 int value20 = 20; 545 546 values.put(COLUMN_KEY_NAME, key10); 547 values.put(COLUMN_VALUE_NAME, value10); 548 549 // test update all the rows. 550 assertEquals(3, mContentResolver.update(TABLE1_URI, values, null, null)); 551 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 552 assertNotNull(mCursor); 553 assertEquals(3, mCursor.getCount()); 554 555 mCursor.moveToFirst(); 556 assertEquals(1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 557 assertEquals(key10, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 558 assertEquals(value10, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 559 560 mCursor.moveToNext(); 561 assertEquals(2, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 562 assertEquals(key10, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 563 assertEquals(value10, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 564 565 mCursor.moveToLast(); 566 assertEquals(3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 567 assertEquals(key10, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 568 assertEquals(value10, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 569 mCursor.close(); 570 571 // test update one row using selection. 572 String selection = COLUMN_ID_NAME + "=1"; 573 values.put(COLUMN_KEY_NAME, key20); 574 values.put(COLUMN_VALUE_NAME, value20); 575 576 assertEquals(1, mContentResolver.update(TABLE1_URI, values, selection, null)); 577 mCursor = mContentResolver.query(TABLE1_URI, null, null, null, null); 578 assertNotNull(mCursor); 579 assertEquals(3, mCursor.getCount()); 580 581 mCursor.moveToFirst(); 582 assertEquals(1, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 583 assertEquals(key20, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 584 assertEquals(value20, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 585 586 mCursor.moveToNext(); 587 assertEquals(2, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 588 assertEquals(key10, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 589 assertEquals(value10, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 590 591 mCursor.moveToLast(); 592 assertEquals(3, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_ID_NAME))); 593 assertEquals(key10, mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_KEY_NAME))); 594 assertEquals(value10, mCursor.getInt(mCursor.getColumnIndexOrThrow(COLUMN_VALUE_NAME))); 595 mCursor.close(); 596 597 try { 598 mContentResolver.update(null, values, null, null); 599 fail("did not throw NullPointerException when uri is null."); 600 } catch (NullPointerException e) { 601 //expected. 602 } 603 604 // javadoc says it will throw NullPointerException when values are null, 605 // but actually, it throws IllegalArgumentException here. 606 try { 607 mContentResolver.update(TABLE1_URI, null, null, null); 608 fail("did not throw IllegalArgumentException when values are null."); 609 } catch (IllegalArgumentException e) { 610 //expected. 611 } 612 } 613 614 @TestTargets({ 615 @TestTargetNew( 616 level = TestLevel.COMPLETE, 617 method = "registerContentObserver", 618 args = {android.net.Uri.class, boolean.class, android.database.ContentObserver.class} 619 ), 620 @TestTargetNew( 621 level = TestLevel.COMPLETE, 622 method = "unregisterContentObserver", 623 args = {android.database.ContentObserver.class} 624 ) 625 }) 626 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 627 "ContentResolver#registerContentObserver(Uri, boolean, ContentObserver) and " + 628 "ContentResolver#unregisterContentObserver(ContentObserver) when the input " + 629 "params are null") 630 public void testRegisterContentObserver() { 631 final MockContentObserver mco = new MockContentObserver(); 632 633 mContentResolver.registerContentObserver(TABLE1_URI, true, mco); 634 assertFalse(mco.hadOnChanged()); 635 636 ContentValues values = new ContentValues(); 637 values.put(COLUMN_KEY_NAME, "key10"); 638 values.put(COLUMN_VALUE_NAME, 10); 639 mContentResolver.update(TABLE1_URI, values, null, null); 640 new DelayedCheck() { 641 @Override 642 protected boolean check() { 643 return mco.hadOnChanged(); 644 } 645 }.run(); 646 647 mco.reset(); 648 mContentResolver.unregisterContentObserver(mco); 649 assertFalse(mco.hadOnChanged()); 650 mContentResolver.update(TABLE1_URI, values, null, null); 651 652 assertFalse(mco.hadOnChanged()); 653 654 try { 655 mContentResolver.registerContentObserver(null, false, mco); 656 fail("did not throw NullPointerException or IllegalArgumentException when uri is null."); 657 } catch (NullPointerException e) { 658 //expected. 659 } catch (IllegalArgumentException e) { 660 // also expected 661 } 662 663 try { 664 mContentResolver.registerContentObserver(TABLE1_URI, false, null); 665 fail("did not throw NullPointerException when register null content observer."); 666 } catch (NullPointerException e) { 667 //expected. 668 } 669 670 try { 671 mContentResolver.unregisterContentObserver(null); 672 fail("did not throw NullPointerException when unregister null content observer."); 673 } catch (NullPointerException e) { 674 //expected. 675 } 676 } 677 678 @TestTargetNew( 679 level = TestLevel.COMPLETE, 680 method = "notifyChange", 681 args = {android.net.Uri.class, android.database.ContentObserver.class} 682 ) 683 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 684 "ContentResolver#notifyChange(Uri, ContentObserver) when uri is null") 685 public void testNotifyChange1() { 686 final MockContentObserver mco = new MockContentObserver(); 687 688 mContentResolver.registerContentObserver(TABLE1_URI, true, mco); 689 assertFalse(mco.hadOnChanged()); 690 691 mContentResolver.notifyChange(TABLE1_URI, mco); 692 new DelayedCheck() { 693 @Override 694 protected boolean check() { 695 return mco.hadOnChanged(); 696 } 697 }.run(); 698 699 mContentResolver.unregisterContentObserver(mco); 700 } 701 702 @TestTargetNew( 703 level = TestLevel.COMPLETE, 704 method = "notifyChange", 705 args = {android.net.Uri.class, android.database.ContentObserver.class, boolean.class} 706 ) 707 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 708 "ContentResolver#notifyChange(Uri, ContentObserver, boolean) when uri is null ") 709 public void testNotifyChange2() { 710 final MockContentObserver mco = new MockContentObserver(); 711 712 mContentResolver.registerContentObserver(TABLE1_URI, true, mco); 713 assertFalse(mco.hadOnChanged()); 714 715 mContentResolver.notifyChange(TABLE1_URI, mco, false); 716 new DelayedCheck() { 717 @Override 718 protected boolean check() { 719 return mco.hadOnChanged(); 720 } 721 }.run(); 722 723 mContentResolver.unregisterContentObserver(mco); 724 } 725 726 @TestTargets({ 727 @TestTargetNew( 728 level = TestLevel.NOT_FEASIBLE, 729 method = "startSync", 730 args = {android.net.Uri.class, android.os.Bundle.class} 731 ), 732 @TestTargetNew( 733 level = TestLevel.NOT_FEASIBLE, 734 method = "cancelSync", 735 args = {android.net.Uri.class} 736 ) 737 }) 738 @ToBeFixed(bug = "1400231", explanation = "the key is SyncObserver class is deleted" + 739 " under currently enviroment(but still exists in doc)") 740 public void testStartCancelSync() { 741 Bundle extras = new Bundle(); 742 743 extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); 744 745 ContentResolver.requestSync(ACCOUNT, AUTHORITY, extras); 746 //FIXME: how to get the result to assert. 747 748 ContentResolver.cancelSync(ACCOUNT, AUTHORITY); 749 //FIXME: how to assert. 750 } 751 752 @TestTargetNew( 753 level = TestLevel.COMPLETE, 754 method = "startSync", 755 args = {android.net.Uri.class, android.os.Bundle.class} 756 ) 757 @ToBeFixed(bug = "1695243", explanation = "should add @throws clause into javadoc of " + 758 "ContentResolver#startSync(Uri, Bundle) when extras is null") 759 public void testStartSyncFailure() { 760 try { 761 ContentResolver.requestSync(null, null, null); 762 fail("did not throw IllegalArgumentException when extras is null."); 763 } catch (IllegalArgumentException e) { 764 //expected. 765 } 766 } 767 768 @TestTargetNew( 769 level = TestLevel.COMPLETE, 770 method = "validateSyncExtrasBundle", 771 args = {android.os.Bundle.class} 772 ) 773 public void testValidateSyncExtrasBundle() { 774 Bundle extras = new Bundle(); 775 extras.putInt("Integer", 20); 776 extras.putLong("Long", 10l); 777 extras.putBoolean("Boolean", true); 778 extras.putFloat("Float", 5.5f); 779 extras.putDouble("Double", 2.5); 780 extras.putString("String", "cts"); 781 extras.putCharSequence("CharSequence", null); 782 783 ContentResolver.validateSyncExtrasBundle(extras); 784 785 extras.putChar("Char", 'a'); // type Char is invalid 786 try { 787 ContentResolver.validateSyncExtrasBundle(extras); 788 fail("did not throw IllegalArgumentException when extras is invalide."); 789 } catch (IllegalArgumentException e) { 790 //expected. 791 } 792 } 793 794 private class MockContentObserver extends ContentObserver { 795 private boolean mHadOnChanged = false; 796 797 public MockContentObserver() { 798 super(null); 799 } 800 801 @Override 802 public boolean deliverSelfNotifications() { 803 return true; 804 } 805 806 @Override 807 public synchronized void onChange(boolean selfChange) { 808 super.onChange(selfChange); 809 mHadOnChanged = true; 810 } 811 812 public synchronized boolean hadOnChanged() { 813 return mHadOnChanged; 814 } 815 816 public synchronized void reset() { 817 mHadOnChanged = false; 818 } 819 } 820 } 821