diff options
-rw-r--r-- | src/com/android/providers/contacts/CallLogProvider.java | 42 | ||||
-rw-r--r-- | tests/src/com/android/providers/contacts/CallLogProviderTest.java | 60 |
2 files changed, 97 insertions, 5 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java index 21a16f1..3480c79 100644 --- a/src/com/android/providers/contacts/CallLogProvider.java +++ b/src/com/android/providers/contacts/CallLogProvider.java @@ -123,15 +123,15 @@ public class CallLogProvider extends ContentProvider { @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(Tables.CALLS); qb.setProjectionMap(sCallsProjectionMap); qb.setStrict(true); - SelectionBuilder selectionBuilder = new SelectionBuilder(selection); + final SelectionBuilder selectionBuilder = new SelectionBuilder(selection); checkVoicemailPermissionAndAddRestriction(uri, selectionBuilder); - int match = sURIMatcher.match(uri); + final int match = sURIMatcher.match(uri); switch (match) { case CALLS: break; @@ -154,15 +154,47 @@ public class CallLogProvider extends ContentProvider { throw new IllegalArgumentException("Unknown URL " + uri); } + final int limit = getIntParam(uri, Calls.LIMIT_PARAM_KEY, 0); + final int offset = getIntParam(uri, Calls.OFFSET_PARAM_KEY, 0); + String limitClause = null; + if (limit > 0) { + limitClause = offset + "," + limit; + } + final SQLiteDatabase db = mDbHelper.getReadableDatabase(); - Cursor c = qb.query(db, projection, selectionBuilder.build(), selectionArgs, null, null, - sortOrder, null); + final Cursor c = qb.query(db, projection, selectionBuilder.build(), selectionArgs, null, + null, sortOrder, limitClause); if (c != null) { c.setNotificationUri(getContext().getContentResolver(), CallLog.CONTENT_URI); } return c; } + /** + * Gets an integer query parameter from a given uri. + * + * @param uri The uri to extract the query parameter from. + * @param key The query parameter key. + * @param defaultValue A default value to return if the query parameter does not exist. + * @return The value from the query parameter in the Uri. Or the default value if the parameter + * does not exist in the uri. + * @throws IllegalArgumentException when the value in the query parameter is not an integer. + */ + private int getIntParam(Uri uri, String key, int defaultValue) { + String valueString = uri.getQueryParameter(key); + if (valueString == null) { + return defaultValue; + } + + try { + return Integer.parseInt(valueString); + } catch (NumberFormatException e) { + String msg = "Integer required for " + key + " parameter but value '" + valueString + + "' was found instead."; + throw new IllegalArgumentException(msg, e); + } + } + @Override public String getType(Uri uri) { int match = sURIMatcher.match(uri); diff --git a/tests/src/com/android/providers/contacts/CallLogProviderTest.java b/tests/src/com/android/providers/contacts/CallLogProviderTest.java index 05f8c25..fc33e28 100644 --- a/tests/src/com/android/providers/contacts/CallLogProviderTest.java +++ b/tests/src/com/android/providers/contacts/CallLogProviderTest.java @@ -209,6 +209,66 @@ public class CallLogProviderTest extends BaseContactsProvider2Test { assertEquals(3, getCount(Calls.CONTENT_URI_WITH_VOICEMAIL, null, null)); } + public void testLimitParamReturnsCorrectLimit() { + for (int i=0; i<10; i++) { + insertCallRecord(); + } + Uri uri = Calls.CONTENT_URI.buildUpon() + .appendQueryParameter(Calls.LIMIT_PARAM_KEY, "4") + .build(); + assertEquals(4, getCount(uri, null, null)); + } + + public void testLimitAndOffsetParamReturnsCorrectEntries() { + for (int i=0; i<10; i++) { + mResolver.insert(Calls.CONTENT_URI, getDefaultValues(Calls.INCOMING_TYPE)); + } + for (int i=0; i<10; i++) { + mResolver.insert(Calls.CONTENT_URI, getDefaultValues(Calls.MISSED_TYPE)); + } + // Limit 4 records. Discard first 8. + Uri uri = Calls.CONTENT_URI.buildUpon() + .appendQueryParameter(Calls.LIMIT_PARAM_KEY, "4") + .appendQueryParameter(Calls.OFFSET_PARAM_KEY, "8") + .build(); + String[] projection = new String[] {Calls._ID, Calls.TYPE}; + Cursor c = mResolver.query(uri, projection, null, null, null); + try { + // First two should be incoming, next two should be missed. + for (int i = 0; i < 2; i++) { + c.moveToNext(); + assertEquals(Calls.INCOMING_TYPE, c.getInt(1)); + } + for (int i = 0; i < 2; i++) { + c.moveToNext(); + assertEquals(Calls.MISSED_TYPE, c.getInt(1)); + } + } finally { + c.close(); + } + } + + public void testUriWithBadLimitParamThrowsException() { + assertParamThrowsIllegalArgumentException(Calls.LIMIT_PARAM_KEY, "notvalid"); + } + + public void testUriWithBadOffsetParamThrowsException() { + assertParamThrowsIllegalArgumentException(Calls.OFFSET_PARAM_KEY, "notvalid"); + } + + private void assertParamThrowsIllegalArgumentException(String key, String value) { + Uri uri = Calls.CONTENT_URI.buildUpon() + .appendQueryParameter(key, value) + .build(); + try { + mResolver.query(uri, null, null, null, null); + fail(); + } catch (IllegalArgumentException e) { + assertTrue("Error does not contain value in question.", + e.toString().contains(value)); + } + } + // Test to check that none of the voicemail provider specific fields are // insertable through call_log provider. public void testCannotAccessVoicemailSpecificFields_Insert() { |