Add notification table shared preference

The notifiaction table will be used by the updated notification controller.
The table stores the key and the associated last notified message key and
message count.

Change-Id: I037b5374ab51620f1cffc8b41391db858cfd3a2d
This commit is contained in:
Todd Kennedy 2011-05-10 10:57:45 -07:00
parent a17ee57c7f
commit 2f371e8553
3 changed files with 233 additions and 35 deletions

View File

@ -23,6 +23,7 @@ import android.content.SharedPreferences;
import android.net.Uri;
import android.util.Log;
import java.util.HashMap;
import java.util.UUID;
public class Preferences {
@ -44,6 +45,7 @@ public class Preferences {
private static final String AUTO_ADVANCE_DIRECTION = "autoAdvance";
private static final String TEXT_ZOOM = "textZoom";
private static final String BACKGROUND_ATTACHMENTS = "backgroundAttachments";
private static final String MESSAGE_NOTIFICATION_TABLE = "messageNotificationTable";
public static final int AUTO_ADVANCE_NEWER = 0;
public static final int AUTO_ADVANCE_OLDER = 1;
@ -249,6 +251,55 @@ public class Preferences {
mSharedPreferences.edit().putBoolean(BACKGROUND_ATTACHMENTS, allowed).apply();
}
public HashMap<Long, long[]> getMessageNotificationTable() {
HashMap<Long, long[]> table = new HashMap<Long, long[]>();
// The table is encoded as a string with the following format:
// K:V1,V2;K:V1,V2;...
// Where 'K' is the table key and 'V1' and 'V2' are the array values associated with the key
// Multiple key/value pairs are separated from one another by a ';'.
String preference = mSharedPreferences.getString(MESSAGE_NOTIFICATION_TABLE, "");
String[] entries = preference.split(";");
for (String entry : entries) {
try {
String hash[] = entry.split(":");
if (hash.length != 2) continue;
String stringValues[] = hash[1].split(",");
if (stringValues.length != 2) continue;
long key = Long.parseLong(hash[0]);
long[] value = new long[2];
value[0] = Long.parseLong(stringValues[0]);
value[1] = Long.parseLong(stringValues[1]);
table.put(key, value);
} catch (NumberFormatException e) {
Log.w(Logging.LOG_TAG, "notification table preference corrupt");
continue;
}
}
return table;
}
/**
* Sets the message notification table.
* @throws IllegalArgumentException if the given table is null or any of the value arrays do
* not have exactly 2 elements.
*/
public void setMessageNotificationTable(HashMap<Long, long[]> notificationTable) {
StringBuffer sb = new StringBuffer();
boolean first = true;
if (notificationTable == null) throw new IllegalArgumentException("table cannot be null");
for (Long key : notificationTable.keySet()) {
if (!first) {
sb.append(';');
}
long[] value = notificationTable.get(key);
if (value == null || value.length != 2) {
throw new IllegalArgumentException("value array must contain 2 elements");
}
sb.append(key).append(':').append(value[0]).append(',').append(value[1]);
first = false;
}
mSharedPreferences.edit().putString(MESSAGE_NOTIFICATION_TABLE, sb.toString()).apply();
}
public void save() {
}

View File

@ -26,6 +26,7 @@ import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.database.Cursor;
@ -200,6 +201,11 @@ public final class DBTestHelper {
public Theme getTheme() {
return mRealContext.getTheme();
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return new MockSharedPreferences();
}
}
/**

View File

@ -16,13 +16,16 @@
package com.android.email;
import android.content.Context;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import java.util.HashMap;
/**
* This is a series of unit tests for the Preferences class.
*
*
* Technically these are functional because they use the underlying preferences framework. It
* would be a really good idea if we could inject our own underlying preferences storage, to better
* test cases like zero accounts behavior (right now, we have to allow for any number of accounts
@ -32,66 +35,204 @@ import android.test.suitebuilder.annotation.SmallTest;
public class PreferencesUnitTests extends AndroidTestCase {
private Preferences mPreferences;
private Account mAccount;
private Context mMockContext;
@Override
protected void setUp() throws Exception {
super.setUp();
mPreferences = Preferences.getPreferences(getContext());
mMockContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(mContext);
mPreferences = Preferences.getPreferences(mMockContext);
}
/**
* Delete any dummy accounts we set up for this test
*/
@Override
protected void tearDown() throws Exception {
super.tearDown();
if (mAccount != null && mPreferences != null) {
mAccount.delete(mPreferences);
/** Just because this does exist anywhere else */
private void assertEquals(long[] expected, long[] actual) {
assertNotNull(actual);
assertEquals(expected.length, actual.length);
for (int i = expected.length - 1; i >= 0; i--) {
if (expected[i] != actual[i]) {
fail("expected array element[" + i + "]:<"
+ expected[i] + "> but was:<" + actual[i] + '>');
}
}
}
private void assertEquals(HashMap<Long, long[]> expected, HashMap<Long, long[]> actual) {
assertNotNull(actual);
assertEquals(expected.size(), actual.size());
for (Long key : expected.keySet()) {
assertTrue(actual.containsKey(key));
long[] expectedArray = expected.get(key);
long[] actualArray = actual.get(key);
assertEquals(expectedArray, actualArray);
}
}
/**
* Test the new getAccountByContentUri() API. This should return null if no
* accounts are configured, or the Uri doesn't match, and it should return a desired account
* otherwise.
*
*
* TODO: Not actually testing the no-accounts case
*/
public void testGetAccountByContentUri() {
// Create a dummy account
createTestAccount();
Account account = new Account(mMockContext);
account.save(mPreferences);
// test sunny-day lookup by Uri
Uri testAccountUri = mAccount.getContentUri();
Uri testAccountUri = account.getContentUri();
Account lookup = mPreferences.getAccountByContentUri(testAccountUri);
assertEquals(mAccount, lookup);
assertEquals(account, lookup);
// now make it a bogus Uri - bad scheme, good path, good UUID
testAccountUri = Uri.parse("bogus://accounts/" + mAccount.getUuid());
testAccountUri = Uri.parse("bogus://accounts/" + account.getUuid());
lookup = mPreferences.getAccountByContentUri(testAccountUri);
assertNull(lookup);
// now make it a bogus Uri - good scheme, bad path, good UUID
testAccountUri = Uri.parse("content://bogus/" + mAccount.getUuid());
testAccountUri = Uri.parse("content://bogus/" + account.getUuid());
lookup = mPreferences.getAccountByContentUri(testAccountUri);
assertNull(lookup);
// now make it a bogus Uri - good scheme/path, bad UUID
testAccountUri = Uri.parse("content://accounts/" + mAccount.getUuid() + "-bogus");
testAccountUri = Uri.parse("content://accounts/" + account.getUuid() + "-bogus");
lookup = mPreferences.getAccountByContentUri(testAccountUri);
assertNull(lookup);
}
/**
* Create a dummy account with minimal fields
*/
private void createTestAccount() {
mAccount = new Account(getContext());
mAccount.save(mPreferences);
public void testSetMessageNotificationTable() {
HashMap<Long, long[]> testTable = new HashMap<Long, long[]>();
String testString;
// One account
testTable.clear();
testTable.put(5L, new long[] { 2L, 3L });
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "value_unset").apply();
mPreferences.setMessageNotificationTable(testTable);
testString = mPreferences.mSharedPreferences.getString("messageNotificationTable", null);
assertEquals("5:2,3", testString);
// Multiple accounts
// NOTE: This assumes a very specific order in the hash map and is fragile; if the hash
// map is ever changed, this may break unexpectedly.
testTable.clear();
testTable.put(5L, new long[] { 2L, 3L });
testTable.put(3L, new long[] { 1L, 8L });
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "value_unset").apply();
mPreferences.setMessageNotificationTable(testTable);
testString = mPreferences.mSharedPreferences.getString("messageNotificationTable", null);
assertEquals("5:2,3;3:1,8", testString);
// Wrong number of elements in the array
// NOTE: This assumes a very specific order in the hash map and is fragile; if the hash
// map is ever changed, this may break unexpectedly.
testTable.clear();
testTable.put(5L, new long[] { 2L, 3L, 8L }); // too many
testTable.put(3L, new long[] { 1L, 8L });
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "value_unset_1").apply();
try {
mPreferences.setMessageNotificationTable(testTable);
fail("expected an IllegalArgumentException");
} catch (IllegalArgumentException e) {
}
testString = mPreferences.mSharedPreferences.getString("messageNotificationTable", null);
assertEquals("value_unset_1", testString);
testTable.clear();
testTable.put(5L, new long[] { 2L }); // too few
testTable.put(3L, new long[] { 1L, 8L });
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "value_unset_2").apply();
try {
mPreferences.setMessageNotificationTable(testTable);
fail("expected an IllegalArgumentException");
} catch (IllegalArgumentException e) {
}
testString = mPreferences.mSharedPreferences.getString("messageNotificationTable", null);
assertEquals("value_unset_2", testString);
// Nulls in strange places
testTable.clear();
testTable.put(5L, null); // no array
testTable.put(3L, new long[] { 1L, 8L });
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "value_unset_3").apply();
try {
mPreferences.setMessageNotificationTable(testTable);
fail("expected an IllegalArgumentException");
} catch (IllegalArgumentException e) {
}
testString = mPreferences.mSharedPreferences.getString("messageNotificationTable", null);
assertEquals("value_unset_3", testString);
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "value_unset_4").apply();
try {
mPreferences.setMessageNotificationTable(null); // no table
fail("expected an IllegalArgumentException");
} catch (IllegalArgumentException e) {
}
testString = mPreferences.mSharedPreferences.getString("messageNotificationTable", null);
assertEquals("value_unset_4", testString);
}
public void testGetMessageNotificationTable() {
HashMap<Long, long[]> testTable;
HashMap<Long, long[]> expectedTable = new HashMap<Long, long[]>();
// Test initial condition
assertFalse(mPreferences.mSharedPreferences.contains("messageNotificationTable"));
// One account
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "5:2,3").apply();
testTable = mPreferences.getMessageNotificationTable();
expectedTable.clear();
expectedTable.put(5L, new long[] { 2L, 3L });
assertEquals(expectedTable, testTable);
// Multiple accounts
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "5:2,3;3:1,8;6:5,3").apply();
testTable = mPreferences.getMessageNotificationTable();
expectedTable.clear();
expectedTable.put(5L, new long[] { 2L, 3L });
expectedTable.put(3L, new long[] { 1L, 8L });
expectedTable.put(6L, new long[] { 5L, 3L });
assertEquals(expectedTable, testTable);
// Empty account
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "5:2,3;").apply();
testTable = mPreferences.getMessageNotificationTable();
expectedTable.clear();
expectedTable.put(5L, new long[] { 2L, 3L });
assertEquals(expectedTable, testTable);
// Empty fields
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "5:2,3;3:").apply();
testTable = mPreferences.getMessageNotificationTable();
expectedTable.clear();
expectedTable.put(5L, new long[] { 2L, 3L });
assertEquals(expectedTable, testTable);
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "5:2,3;3:1,").apply();
testTable = mPreferences.getMessageNotificationTable();
expectedTable.clear();
expectedTable.put(5L, new long[] { 2L, 3L });
assertEquals(expectedTable, testTable);
// Garbage
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "blahblahblah").apply();
testTable = mPreferences.getMessageNotificationTable();
expectedTable.clear();
assertEquals(expectedTable, testTable); // empty table
mPreferences.mSharedPreferences.edit()
.putString("messageNotificationTable", "5:2,3;blahblahblah").apply();
testTable = mPreferences.getMessageNotificationTable();
expectedTable.clear();
expectedTable.put(5L, new long[] { 2L, 3L });
assertEquals(expectedTable, testTable);
}
}