Merge "Use MatrixCursor instead of ArrayListCursor."

This commit is contained in:
Jeff Brown
2011-10-14 21:06:31 -07:00
committed by Android (Google) Code Review
3 changed files with 47 additions and 324 deletions

View File

@@ -16,17 +16,11 @@
package android.database;
import android.database.AbstractCursor;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.common.ArrayListCursor;
import android.database.CursorWindow;
import android.test.PerformanceTestCase;
import com.google.android.collect.Lists;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import junit.framework.TestCase;
@@ -40,48 +34,6 @@ public class CursorWindowTest extends TestCase implements PerformanceTestCase {
return 1;
}
@SmallTest
public void testWriteCursorToWindow() throws Exception {
// create cursor
String[] colNames = new String[]{"name", "number", "profit"};
int colsize = colNames.length;
ArrayList<ArrayList> list = createTestList(10, colsize);
AbstractCursor cursor = new ArrayListCursor(colNames, (ArrayList<ArrayList>) list);
// fill window
CursorWindow window = new CursorWindow(false);
cursor.fillWindow(0, window);
// read from cursor window
for (int i = 0; i < list.size(); i++) {
ArrayList<Integer> col = list.get(i);
for (int j = 0; j < colsize; j++) {
String s = window.getString(i, j);
int r2 = col.get(j);
int r1 = Integer.parseInt(s);
assertEquals(r2, r1);
}
}
// test cursor window handle startpos != 0
window.clear();
cursor.fillWindow(1, window);
// read from cursor from window
for (int i = 1; i < list.size(); i++) {
ArrayList<Integer> col = list.get(i);
for (int j = 0; j < colsize; j++) {
String s = window.getString(i, j);
int r2 = col.get(j);
int r1 = Integer.parseInt(s);
assertEquals(r2, r1);
}
}
// Clear the window and make sure it's empty
window.clear();
assertEquals(0, window.getNumRows());
}
@SmallTest
public void testValuesLocalWindow() {
doTestValues(new CursorWindow(true));
@@ -124,50 +76,4 @@ public class CursorWindowTest extends TestCase implements PerformanceTestCase {
assertTrue(window.putBlob(blob, 0, 6));
assertTrue(Arrays.equals(blob, window.getBlob(0, 6)));
}
@SmallTest
public void testNull() {
CursorWindow window = getOneByOneWindow();
// Put in a null value and read it back as various types
assertTrue(window.putNull(0, 0));
assertNull(window.getString(0, 0));
assertEquals(0, window.getLong(0, 0));
assertEquals(0.0, window.getDouble(0, 0));
assertNull(window.getBlob(0, 0));
}
@SmallTest
public void testEmptyString() {
CursorWindow window = getOneByOneWindow();
// put size 0 string and read it back as various types
assertTrue(window.putString("", 0, 0));
assertEquals("", window.getString(0, 0));
assertEquals(0, window.getLong(0, 0));
assertEquals(0.0, window.getDouble(0, 0));
}
private CursorWindow getOneByOneWindow() {
CursorWindow window = new CursorWindow(false);
assertTrue(window.setNumColumns(1));
assertTrue(window.allocRow());
return window;
}
private static ArrayList<ArrayList> createTestList(int rows, int cols) {
ArrayList<ArrayList> list = Lists.newArrayList();
Random generator = new Random();
for (int i = 0; i < rows; i++) {
ArrayList<Integer> col = Lists.newArrayList();
list.add(col);
for (int j = 0; j < cols; j++) {
// generate random number
Integer r = generator.nextInt();
col.add(r);
}
}
return list;
}
}

View File

@@ -16,11 +16,11 @@
package android.widget;
import com.android.common.ArrayListCursor;
import com.google.android.collect.Lists;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -52,14 +52,14 @@ public class SimpleCursorAdapterTest extends AndroidTestCase {
super.setUp();
// all the pieces needed for the various tests
mFrom = new String[]{"Column1", "Column2"};
mFrom = new String[]{"Column1", "Column2", "_id"};
mTo = new int[]{com.android.internal.R.id.text1, com.android.internal.R.id.text2};
mLayout = com.android.internal.R.layout.simple_list_item_2;
mContext = getContext();
// raw data for building a basic test cursor
mData2x2 = createTestList(2, 2);
mCursor2x2 = new ArrayListCursor(mFrom, mData2x2);
mCursor2x2 = createCursor(mFrom, mData2x2);
}
/**
@@ -77,6 +77,7 @@ public class SimpleCursorAdapterTest extends AndroidTestCase {
Integer r = generator.nextInt();
col.add(r);
}
col.add(i);
}
return list;
}
@@ -115,7 +116,7 @@ public class SimpleCursorAdapterTest extends AndroidTestCase {
// now put in a different cursor (5 rows)
ArrayList<ArrayList> data2 = createTestList(5, 2);
Cursor c2 = new ArrayListCursor(mFrom, data2);
Cursor c2 = createCursor(mFrom, data2);
ca.changeCursor(c2);
// Now see if we can pull 5 rows from the adapter
@@ -155,8 +156,8 @@ public class SimpleCursorAdapterTest extends AndroidTestCase {
assertEquals(columns[1], 1);
// Now make a new cursor with similar data but rearrange the columns
String[] swappedFrom = new String[]{"Column2", "Column1"};
Cursor c2 = new ArrayListCursor(swappedFrom, mData2x2);
String[] swappedFrom = new String[]{"Column2", "Column1", "_id"};
Cursor c2 = createCursor(swappedFrom, mData2x2);
ca.changeCursor(c2);
assertEquals(2, ca.getCount());
@@ -235,7 +236,15 @@ public class SimpleCursorAdapterTest extends AndroidTestCase {
assertEquals(1, viewIds.length);
assertEquals(com.android.internal.R.id.text2, viewIds[0]);
}
private static MatrixCursor createCursor(String[] columns, ArrayList<ArrayList> list) {
MatrixCursor cursor = new MatrixCursor(columns, list.size());
for (ArrayList row : list) {
cursor.addRow(row);
}
return cursor;
}
/**
* This is simply a way to sneak a look at the protected mFrom() array. A more API-
* friendly way to do this would be to mock out a View and a ViewBinder and exercise

View File

@@ -19,166 +19,20 @@ package com.android.internal.telephony;
import android.content.ContentProvider;
import android.content.UriMatcher;
import android.content.ContentValues;
import android.database.AbstractCursor;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.SystemProperties;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.IIccPhoneBook;
/**
* XXX old code -- should be replaced with MatrixCursor.
* @deprecated This is has been replaced by MatrixCursor.
*/
class ArrayListCursor extends AbstractCursor {
private String[] mColumnNames;
private ArrayList<Object>[] mRows;
@SuppressWarnings({"unchecked"})
public ArrayListCursor(String[] columnNames, ArrayList<ArrayList> rows) {
int colCount = columnNames.length;
boolean foundID = false;
// Add an _id column if not in columnNames
for (int i = 0; i < colCount; ++i) {
if (columnNames[i].compareToIgnoreCase("_id") == 0) {
mColumnNames = columnNames;
foundID = true;
break;
}
}
if (!foundID) {
mColumnNames = new String[colCount + 1];
System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
mColumnNames[colCount] = "_id";
}
int rowCount = rows.size();
mRows = new ArrayList[rowCount];
for (int i = 0; i < rowCount; ++i) {
mRows[i] = rows.get(i);
if (!foundID) {
mRows[i].add(i);
}
}
}
@Override
public void fillWindow(int position, CursorWindow window) {
if (position < 0 || position > getCount()) {
return;
}
window.acquireReference();
try {
int oldpos = mPos;
mPos = position - 1;
window.clear();
window.setStartPosition(position);
int columnNum = getColumnCount();
window.setNumColumns(columnNum);
while (moveToNext() && window.allocRow()) {
for (int i = 0; i < columnNum; i++) {
final Object data = mRows[mPos].get(i);
if (data != null) {
if (data instanceof byte[]) {
byte[] field = (byte[]) data;
if (!window.putBlob(field, mPos, i)) {
window.freeLastRow();
break;
}
} else {
String field = data.toString();
if (!window.putString(field, mPos, i)) {
window.freeLastRow();
break;
}
}
} else {
if (!window.putNull(mPos, i)) {
window.freeLastRow();
break;
}
}
}
}
mPos = oldpos;
} catch (IllegalStateException e){
// simply ignore it
} finally {
window.releaseReference();
}
}
@Override
public int getCount() {
return mRows.length;
}
@Override
public String[] getColumnNames() {
return mColumnNames;
}
@Override
public byte[] getBlob(int columnIndex) {
return (byte[]) mRows[mPos].get(columnIndex);
}
@Override
public String getString(int columnIndex) {
Object cell = mRows[mPos].get(columnIndex);
return (cell == null) ? null : cell.toString();
}
@Override
public short getShort(int columnIndex) {
Number num = (Number) mRows[mPos].get(columnIndex);
return num.shortValue();
}
@Override
public int getInt(int columnIndex) {
Number num = (Number) mRows[mPos].get(columnIndex);
return num.intValue();
}
@Override
public long getLong(int columnIndex) {
Number num = (Number) mRows[mPos].get(columnIndex);
return num.longValue();
}
@Override
public float getFloat(int columnIndex) {
Number num = (Number) mRows[mPos].get(columnIndex);
return num.floatValue();
}
@Override
public double getDouble(int columnIndex) {
Number num = (Number) mRows[mPos].get(columnIndex);
return num.doubleValue();
}
@Override
public boolean isNull(int columnIndex) {
return mRows[mPos].get(columnIndex) == null;
}
}
/**
* {@hide}
@@ -191,7 +45,8 @@ public class IccProvider extends ContentProvider {
private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
"name",
"number",
"emails"
"emails",
"_id"
};
private static final int ADN = 1;
@@ -213,70 +68,27 @@ public class IccProvider extends ContentProvider {
}
private boolean mSimulator;
@Override
public boolean onCreate() {
String device = SystemProperties.get("ro.product.device");
if (!TextUtils.isEmpty(device)) {
mSimulator = false;
} else {
// simulator
mSimulator = true;
}
return true;
}
@Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
ArrayList<ArrayList> results;
switch (URL_MATCHER.match(url)) {
case ADN:
return loadFromEf(IccConstants.EF_ADN);
if (!mSimulator) {
switch (URL_MATCHER.match(url)) {
case ADN:
results = loadFromEf(IccConstants.EF_ADN);
break;
case FDN:
return loadFromEf(IccConstants.EF_FDN);
case FDN:
results = loadFromEf(IccConstants.EF_FDN);
break;
case SDN:
return loadFromEf(IccConstants.EF_SDN);
case SDN:
results = loadFromEf(IccConstants.EF_SDN);
break;
default:
throw new IllegalArgumentException("Unknown URL " + url);
}
} else {
// Fake up some data for the simulator
results = new ArrayList<ArrayList>(4);
ArrayList<String> contact;
contact = new ArrayList<String>();
contact.add("Ron Stevens/H");
contact.add("512-555-5038");
results.add(contact);
contact = new ArrayList<String>();
contact.add("Ron Stevens/M");
contact.add("512-555-8305");
results.add(contact);
contact = new ArrayList<String>();
contact.add("Melissa Owens");
contact.add("512-555-8305");
results.add(contact);
contact = new ArrayList<String>();
contact.add("Directory Assistence");
contact.add("411");
results.add(contact);
default:
throw new IllegalArgumentException("Unknown URL " + url);
}
return new ArrayListCursor(ADDRESS_BOOK_COLUMN_NAMES, results);
}
@Override
@@ -473,12 +285,10 @@ public class IccProvider extends ContentProvider {
return 1;
}
private ArrayList<ArrayList> loadFromEf(int efType) {
ArrayList<ArrayList> results = new ArrayList<ArrayList>();
List<AdnRecord> adnRecords = null;
private MatrixCursor loadFromEf(int efType) {
if (DBG) log("loadFromEf: efType=" + efType);
List<AdnRecord> adnRecords = null;
try {
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
ServiceManager.getService("simphonebook"));
@@ -490,21 +300,21 @@ public class IccProvider extends ContentProvider {
} catch (SecurityException ex) {
if (DBG) log(ex.toString());
}
if (adnRecords != null) {
// Load the results
int N = adnRecords.size();
final int N = adnRecords.size();
final MatrixCursor cursor = new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES, N);
if (DBG) log("adnRecords.size=" + N);
for (int i = 0; i < N ; i++) {
loadRecord(adnRecords.get(i), results);
loadRecord(adnRecords.get(i), cursor, i);
}
return cursor;
} else {
// No results to load
Log.w(TAG, "Cannot load ADN records");
results.clear();
return new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES);
}
if (DBG) log("loadFromEf: return results");
return results;
}
private boolean
@@ -584,35 +394,33 @@ public class IccProvider extends ContentProvider {
}
/**
* Loads an AdnRecord into an ArrayList. Must be called with mLock held.
* Loads an AdnRecord into a MatrixCursor. Must be called with mLock held.
*
* @param record the ADN record to load from
* @param results the array list to put the results in
* @param cursor the cursor to receive the results
*/
private void loadRecord(AdnRecord record,
ArrayList<ArrayList> results) {
private void loadRecord(AdnRecord record, MatrixCursor cursor, int id) {
if (!record.isEmpty()) {
ArrayList<String> contact = new ArrayList<String>();
Object[] contact = new Object[4];
String alphaTag = record.getAlphaTag();
String number = record.getNumber();
String[] emails = record.getEmails();
if (DBG) log("loadRecord: " + alphaTag + ", " + number + ",");
contact.add(alphaTag);
contact.add(number);
StringBuilder emailString = new StringBuilder();
contact[0] = alphaTag;
contact[1] = number;
String[] emails = record.getEmails();
if (emails != null) {
StringBuilder emailString = new StringBuilder();
for (String email: emails) {
if (DBG) log("Adding email:" + email);
emailString.append(email);
emailString.append(",");
}
contact.add(emailString.toString());
} else {
contact.add(null);
contact[2] = emailString.toString();
}
results.add(contact);
contact[3] = id;
cursor.addRow(contact);
}
}