Convert AttachmentProvider to use new Provider db.
* Rewrite internals to use EmailProvider instead of raw db access * Minor changes to APIs as necessary (and scattered changes to follow) * Convert unit tests and check them
This commit is contained in:
parent
63b2ad5bfb
commit
3d25a519ab
|
@ -1322,7 +1322,7 @@ public class MessageView extends Activity
|
||||||
String text = MimeUtility.getTextFromPart(part);
|
String text = MimeUtility.getTextFromPart(part);
|
||||||
if (part.getMimeType().equalsIgnoreCase("text/html")) {
|
if (part.getMimeType().equalsIgnoreCase("text/html")) {
|
||||||
text = EmailHtmlUtil.resolveInlineImage(
|
text = EmailHtmlUtil.resolveInlineImage(
|
||||||
getContentResolver(), mAccount, text, mOldMessage, 0);
|
getContentResolver(), mAccount.mId, text, mOldMessage, 0);
|
||||||
} else {
|
} else {
|
||||||
// And also escape special character, such as "<>&",
|
// And also escape special character, such as "<>&",
|
||||||
// to HTML escape sequence.
|
// to HTML escape sequence.
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class EmailHtmlUtil {
|
||||||
* @return html text in which src attribute of img tag may be replaced with content uri
|
* @return html text in which src attribute of img tag may be replaced with content uri
|
||||||
*/
|
*/
|
||||||
public static String resolveInlineImage(
|
public static String resolveInlineImage(
|
||||||
ContentResolver resolver, EmailContent.Account account, String text, Part part, int depth)
|
ContentResolver resolver, long accountId, String text, Part part, int depth)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
// avoid too deep recursive call.
|
// avoid too deep recursive call.
|
||||||
if (depth >= 10 || text == null) {
|
if (depth >= 10 || text == null) {
|
||||||
|
@ -60,8 +60,10 @@ public class EmailHtmlUtil {
|
||||||
contentId != null &&
|
contentId != null &&
|
||||||
part instanceof LocalAttachmentBodyPart) {
|
part instanceof LocalAttachmentBodyPart) {
|
||||||
LocalAttachmentBodyPart attachment = (LocalAttachmentBodyPart)part;
|
LocalAttachmentBodyPart attachment = (LocalAttachmentBodyPart)part;
|
||||||
Uri contentUri = AttachmentProvider.resolveAttachmentIdToContentUri(
|
Uri attachmentUri =
|
||||||
resolver, AttachmentProvider.getAttachmentUri(account, attachment.getAttachmentId()));
|
AttachmentProvider.getAttachmentUri(accountId, attachment.getAttachmentId());
|
||||||
|
Uri contentUri =
|
||||||
|
AttachmentProvider.resolveAttachmentIdToContentUri(resolver, attachmentUri);
|
||||||
// Regexp which matches ' src="cid:contentId"'.
|
// Regexp which matches ' src="cid:contentId"'.
|
||||||
String contentIdRe = "\\s+(?i)src=\"cid(?-i):\\Q" + contentId + "\\E\"";
|
String contentIdRe = "\\s+(?i)src=\"cid(?-i):\\Q" + contentId + "\\E\"";
|
||||||
// Replace all occurrences of src attribute with ' src="content://contentUri"'.
|
// Replace all occurrences of src attribute with ' src="content://contentUri"'.
|
||||||
|
@ -71,7 +73,7 @@ public class EmailHtmlUtil {
|
||||||
if (part.getBody() instanceof Multipart) {
|
if (part.getBody() instanceof Multipart) {
|
||||||
Multipart mp = (Multipart)part.getBody();
|
Multipart mp = (Multipart)part.getBody();
|
||||||
for (int i = 0; i < mp.getCount(); i++) {
|
for (int i = 0; i < mp.getCount(); i++) {
|
||||||
text = resolveInlineImage(resolver, account, text, mp.getBodyPart(i), depth + 1);
|
text = resolveInlineImage(resolver, accountId, text, mp.getBodyPart(i), depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1375,9 +1375,10 @@ public class LocalStore extends Store implements PersistentDataCallbacks {
|
||||||
if (tempAttachmentFile != null) {
|
if (tempAttachmentFile != null) {
|
||||||
File attachmentFile = new File(mAttachmentsDir, Long.toString(attachmentId));
|
File attachmentFile = new File(mAttachmentsDir, Long.toString(attachmentId));
|
||||||
tempAttachmentFile.renameTo(attachmentFile);
|
tempAttachmentFile.renameTo(attachmentFile);
|
||||||
contentUri = AttachmentProvider.getAttachmentUri(
|
// Doing this requires knowing the account id
|
||||||
new File(mPath).getName(),
|
// contentUri = AttachmentProvider.getAttachmentUri(
|
||||||
attachmentId);
|
// new File(mPath).getName(),
|
||||||
|
// attachmentId);
|
||||||
attachment.setBody(new LocalAttachmentBody(contentUri, mContext));
|
attachment.setBody(new LocalAttachmentBody(contentUri, mContext));
|
||||||
ContentValues cv = new ContentValues();
|
ContentValues cv = new ContentValues();
|
||||||
cv.put("content_uri", contentUri != null ? contentUri.toString() : null);
|
cv.put("content_uri", contentUri != null ? contentUri.toString() : null);
|
||||||
|
|
|
@ -17,13 +17,15 @@
|
||||||
package com.android.email.provider;
|
package com.android.email.provider;
|
||||||
|
|
||||||
import com.android.email.mail.internet.MimeUtility;
|
import com.android.email.mail.internet.MimeUtility;
|
||||||
|
import com.android.email.provider.EmailContent.Attachment;
|
||||||
|
import com.android.email.provider.EmailContent.AttachmentColumns;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.ContentUris;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.MatrixCursor;
|
import android.database.MatrixCursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -38,6 +40,12 @@ import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A simple ContentProvider that allows file access to Email's attachments.
|
* A simple ContentProvider that allows file access to Email's attachments.
|
||||||
|
*
|
||||||
|
* The URI scheme is as follows. For raw file access:
|
||||||
|
* content://com.android.email.attachmentprovider/acct#/attach#/RAW
|
||||||
|
*
|
||||||
|
* And for access to thumbnails:
|
||||||
|
* content://com.android.email.attachmentprovider/acct#/attach#/THUMBNAIL/width#/height#
|
||||||
*/
|
*/
|
||||||
public class AttachmentProvider extends ContentProvider {
|
public class AttachmentProvider extends ContentProvider {
|
||||||
|
|
||||||
|
@ -54,9 +62,13 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
public static final String SIZE = "_size";
|
public static final String SIZE = "_size";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri getAttachmentUri(EmailContent.Account account, long id) {
|
private String[] PROJECTION_MIME_TYPE = new String[] { AttachmentColumns.MIME_TYPE };
|
||||||
|
private String[] PROJECTION_QUERY = new String[] { AttachmentColumns.FILENAME,
|
||||||
|
AttachmentColumns.SIZE, AttachmentColumns.CONTENT_URI };
|
||||||
|
|
||||||
|
public static Uri getAttachmentUri(long accountId, long id) {
|
||||||
return CONTENT_URI.buildUpon()
|
return CONTENT_URI.buildUpon()
|
||||||
.appendPath(account.getUuid() + ".db")
|
.appendPath(Long.toString(accountId))
|
||||||
.appendPath(Long.toString(id))
|
.appendPath(Long.toString(id))
|
||||||
.appendPath(FORMAT_RAW)
|
.appendPath(FORMAT_RAW)
|
||||||
.build();
|
.build();
|
||||||
|
@ -65,7 +77,7 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
public static Uri getAttachmentThumbnailUri(EmailContent.Account account, long id,
|
public static Uri getAttachmentThumbnailUri(EmailContent.Account account, long id,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
return CONTENT_URI.buildUpon()
|
return CONTENT_URI.buildUpon()
|
||||||
.appendPath(account.getUuid() + ".db")
|
.appendPath(Long.toString(account.mId))
|
||||||
.appendPath(Long.toString(id))
|
.appendPath(Long.toString(id))
|
||||||
.appendPath(FORMAT_THUMBNAIL)
|
.appendPath(FORMAT_THUMBNAIL)
|
||||||
.appendPath(Integer.toString(width))
|
.appendPath(Integer.toString(width))
|
||||||
|
@ -73,14 +85,6 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri getAttachmentUri(String db, long id) {
|
|
||||||
return CONTENT_URI.buildUpon()
|
|
||||||
.appendPath(db)
|
|
||||||
.appendPath(Long.toString(id))
|
|
||||||
.appendPath(FORMAT_RAW)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
/*
|
/*
|
||||||
|
@ -106,42 +110,23 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
@Override
|
@Override
|
||||||
public String getType(Uri uri) {
|
public String getType(Uri uri) {
|
||||||
List<String> segments = uri.getPathSegments();
|
List<String> segments = uri.getPathSegments();
|
||||||
String dbName = segments.get(0);
|
String accountId = segments.get(0);
|
||||||
String id = segments.get(1);
|
String id = segments.get(1);
|
||||||
String format = segments.get(2);
|
String format = segments.get(2);
|
||||||
if (FORMAT_THUMBNAIL.equals(format)) {
|
if (FORMAT_THUMBNAIL.equals(format)) {
|
||||||
return "image/png";
|
return "image/png";
|
||||||
}
|
} else {
|
||||||
else {
|
uri = ContentUris.withAppendedId(Attachment.CONTENT_URI, Long.parseLong(id));
|
||||||
String path = getContext().getDatabasePath(dbName).getAbsolutePath();
|
Cursor c = getContext().getContentResolver().query(uri, PROJECTION_MIME_TYPE,
|
||||||
SQLiteDatabase db = null;
|
null, null, null);
|
||||||
Cursor cursor = null;
|
|
||||||
try {
|
try {
|
||||||
db = SQLiteDatabase.openDatabase(path, null, 0);
|
if (c.moveToFirst()) {
|
||||||
cursor = db.query(
|
return c.getString(0);
|
||||||
"attachments",
|
|
||||||
new String[] { "mime_type" },
|
|
||||||
"id = ?",
|
|
||||||
new String[] { id },
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null);
|
|
||||||
cursor.moveToFirst();
|
|
||||||
String type = cursor.getString(0);
|
|
||||||
cursor.close();
|
|
||||||
db.close();
|
|
||||||
return type;
|
|
||||||
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
}
|
||||||
if (db != null) {
|
} finally {
|
||||||
db.close();
|
c.close();
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,23 +144,25 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
@Override
|
@Override
|
||||||
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
|
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
|
||||||
List<String> segments = uri.getPathSegments();
|
List<String> segments = uri.getPathSegments();
|
||||||
String dbName = segments.get(0);
|
String accountId = segments.get(0);
|
||||||
String id = segments.get(1);
|
String id = segments.get(1);
|
||||||
String format = segments.get(2);
|
String format = segments.get(2);
|
||||||
if (FORMAT_THUMBNAIL.equals(format)) {
|
if (FORMAT_THUMBNAIL.equals(format)) {
|
||||||
int width = Integer.parseInt(segments.get(3));
|
int width = Integer.parseInt(segments.get(3));
|
||||||
int height = Integer.parseInt(segments.get(4));
|
int height = Integer.parseInt(segments.get(4));
|
||||||
String filename = "thmb_" + dbName + "_" + id;
|
String filename = "thmb_" + accountId + "_" + id;
|
||||||
File dir = getContext().getCacheDir();
|
File dir = getContext().getCacheDir();
|
||||||
File file = new File(dir, filename);
|
File file = new File(dir, filename);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
Uri attachmentUri = getAttachmentUri(dbName, Long.parseLong(id));
|
Uri attachmentUri = getAttachmentUri(Long.parseLong(accountId), Long.parseLong(id));
|
||||||
Cursor c = query(attachmentUri,
|
Cursor c = query(attachmentUri,
|
||||||
new String[] { AttachmentProviderColumns.DATA }, null, null, null);
|
new String[] { AttachmentProviderColumns.DATA }, null, null, null);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
try {
|
try {
|
||||||
if (c.moveToFirst()) {
|
if (c.moveToFirst()) {
|
||||||
attachmentUri = Uri.parse(c.getString(0));
|
attachmentUri = Uri.parse(c.getString(0));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.close();
|
c.close();
|
||||||
|
@ -200,7 +187,7 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return ParcelFileDescriptor.open(
|
return ParcelFileDescriptor.open(
|
||||||
new File(getContext().getDatabasePath(dbName + "_att"), id),
|
new File(getContext().getDatabasePath(accountId + ".db_att"), id),
|
||||||
ParcelFileDescriptor.MODE_READ_ONLY);
|
ParcelFileDescriptor.MODE_READ_ONLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,9 +208,6 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
*
|
*
|
||||||
* Supports REST Uri only, for a single row - selection, selection args, and sortOrder are
|
* Supports REST Uri only, for a single row - selection, selection args, and sortOrder are
|
||||||
* ignored (non-null values should probably throw an exception....)
|
* ignored (non-null values should probably throw an exception....)
|
||||||
*
|
|
||||||
* TODO: Throws an SQLite exception on a missing DB file (e.g. unknown URI) instead of just
|
|
||||||
* returning null, as it should.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
||||||
|
@ -237,39 +221,26 @@ public class AttachmentProvider extends ContentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> segments = uri.getPathSegments();
|
List<String> segments = uri.getPathSegments();
|
||||||
String dbName = segments.get(0);
|
String accountId = segments.get(0);
|
||||||
String id = segments.get(1);
|
String id = segments.get(1);
|
||||||
String format = segments.get(2);
|
String format = segments.get(2);
|
||||||
String path = getContext().getDatabasePath(dbName).getAbsolutePath();
|
|
||||||
String name = null;
|
String name = null;
|
||||||
int size = -1;
|
int size = -1;
|
||||||
String contentUri = null;
|
String contentUri = null;
|
||||||
SQLiteDatabase db = null;
|
|
||||||
Cursor cursor = null;
|
uri = ContentUris.withAppendedId(Attachment.CONTENT_URI, Long.parseLong(id));
|
||||||
|
Cursor c = getContext().getContentResolver().query(uri, PROJECTION_QUERY,
|
||||||
|
null, null, null);
|
||||||
try {
|
try {
|
||||||
db = SQLiteDatabase.openDatabase(path, null, 0);
|
if (c.moveToFirst()) {
|
||||||
cursor = db.query(
|
name = c.getString(0);
|
||||||
"attachments",
|
size = c.getInt(1);
|
||||||
new String[] { "name", "size", "content_uri" },
|
contentUri = c.getString(2);
|
||||||
"id = ?",
|
} else {
|
||||||
new String[] { id },
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null);
|
|
||||||
if (!cursor.moveToFirst()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
name = cursor.getString(0);
|
} finally {
|
||||||
size = cursor.getInt(1);
|
c.close();
|
||||||
contentUri = cursor.getString(2);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
if (db != null) {
|
|
||||||
db.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixCursor ret = new MatrixCursor(projection);
|
MatrixCursor ret = new MatrixCursor(projection);
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class MessageTestUtils {
|
||||||
* @return AttachmentProvider content URI
|
* @return AttachmentProvider content URI
|
||||||
*/
|
*/
|
||||||
public static Uri contentUri(long attachmentId, EmailContent.Account account) {
|
public static Uri contentUri(long attachmentId, EmailContent.Account account) {
|
||||||
return AttachmentProvider.getAttachmentUri(account, attachmentId);
|
return AttachmentProvider.getAttachmentUri(account.mId, attachmentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,6 +32,12 @@ import android.test.suitebuilder.annotation.MediumTest;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests of the Email HTML utils.
|
||||||
|
*
|
||||||
|
* You can run this entire test case with:
|
||||||
|
* runtest -c com.android.email.mail.internet.EmailHtmlUtilTest email
|
||||||
|
*/
|
||||||
@MediumTest
|
@MediumTest
|
||||||
public class EmailHtmlUtilTest extends AndroidTestCase {
|
public class EmailHtmlUtilTest extends AndroidTestCase {
|
||||||
private EmailContent.Account mAccount;
|
private EmailContent.Account mAccount;
|
||||||
|
@ -74,13 +80,13 @@ public class EmailHtmlUtilTest extends AndroidTestCase {
|
||||||
.build();
|
.build();
|
||||||
// Simple case.
|
// Simple case.
|
||||||
final String actual1 = EmailHtmlUtil.resolveInlineImage(
|
final String actual1 = EmailHtmlUtil.resolveInlineImage(
|
||||||
getContext().getContentResolver(), mAccount, text1, msg1, 0);
|
getContext().getContentResolver(), mAccount.mId, text1, msg1, 0);
|
||||||
assertEquals("one content id reference is not resolved",
|
assertEquals("one content id reference is not resolved",
|
||||||
expected1, actual1);
|
expected1, actual1);
|
||||||
|
|
||||||
// Exceed recursive limit.
|
// Exceed recursive limit.
|
||||||
final String actual0 = EmailHtmlUtil.resolveInlineImage(
|
final String actual0 = EmailHtmlUtil.resolveInlineImage(
|
||||||
getContext().getContentResolver(), mAccount, text1, msg1, 10);
|
getContext().getContentResolver(), mAccount.mId, text1, msg1, 10);
|
||||||
assertEquals("recursive call limit may exceeded",
|
assertEquals("recursive call limit may exceeded",
|
||||||
text1, actual0);
|
text1, actual0);
|
||||||
|
|
||||||
|
@ -100,7 +106,7 @@ public class EmailHtmlUtilTest extends AndroidTestCase {
|
||||||
.build();
|
.build();
|
||||||
// cid1 is not replaced
|
// cid1 is not replaced
|
||||||
final String actual2 = EmailHtmlUtil.resolveInlineImage(
|
final String actual2 = EmailHtmlUtil.resolveInlineImage(
|
||||||
getContext().getContentResolver(), mAccount, text1 + text2, msg2, 0);
|
getContext().getContentResolver(), mAccount.mId, text1 + text2, msg2, 0);
|
||||||
assertEquals("only one of two content id is resolved",
|
assertEquals("only one of two content id is resolved",
|
||||||
text1 + expected2, actual2);
|
text1 + expected2, actual2);
|
||||||
|
|
||||||
|
@ -114,7 +120,7 @@ public class EmailHtmlUtilTest extends AndroidTestCase {
|
||||||
.build();
|
.build();
|
||||||
// cid1 and cid2 are replaced
|
// cid1 and cid2 are replaced
|
||||||
final String actual3 = EmailHtmlUtil.resolveInlineImage(
|
final String actual3 = EmailHtmlUtil.resolveInlineImage(
|
||||||
getContext().getContentResolver(), mAccount, text2 + text1, msg3, 0);
|
getContext().getContentResolver(), mAccount.mId, text2 + text1, msg3, 0);
|
||||||
assertEquals("two content ids are resolved correctly",
|
assertEquals("two content ids are resolved correctly",
|
||||||
expected2 + expected1, actual3);
|
expected2 + expected1, actual3);
|
||||||
|
|
||||||
|
@ -133,13 +139,13 @@ public class EmailHtmlUtilTest extends AndroidTestCase {
|
||||||
.build();
|
.build();
|
||||||
// cid1 and cid2 are replaced
|
// cid1 and cid2 are replaced
|
||||||
final String actual4 = EmailHtmlUtil.resolveInlineImage(
|
final String actual4 = EmailHtmlUtil.resolveInlineImage(
|
||||||
getContext().getContentResolver(), mAccount, text2 + text1, msg4, 0);
|
getContext().getContentResolver(), mAccount.mId, text2 + text1, msg4, 0);
|
||||||
assertEquals("two content ids in deep multipart level are resolved",
|
assertEquals("two content ids in deep multipart level are resolved",
|
||||||
expected2 + expected1, actual4);
|
expected2 + expected1, actual4);
|
||||||
|
|
||||||
// No crash on null text
|
// No crash on null text
|
||||||
final String actual5 = EmailHtmlUtil.resolveInlineImage(getContext().getContentResolver(),
|
final String actual5 = EmailHtmlUtil.resolveInlineImage(getContext().getContentResolver(),
|
||||||
mAccount, null, msg4, 0);
|
mAccount.mId, null, msg4, 0);
|
||||||
assertNull(actual5);
|
assertNull(actual5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ import android.content.Context;
|
||||||
import android.content.res.AssetFileDescriptor;
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteException;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -54,7 +53,7 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
* "old" LocalStore model to the "new" provider model. After the transition is complete,
|
* "old" LocalStore model to the "new" provider model. After the transition is complete,
|
||||||
* this flag (and its associated code) can be removed.
|
* this flag (and its associated code) can be removed.
|
||||||
*/
|
*/
|
||||||
private final boolean USE_LOCALSTORE = true;
|
private final boolean USE_LOCALSTORE = false;
|
||||||
LocalStore mLocalStore = null;
|
LocalStore mLocalStore = null;
|
||||||
|
|
||||||
EmailProvider mEmailProvider;
|
EmailProvider mEmailProvider;
|
||||||
|
@ -118,18 +117,13 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
// attachment we add will be id=1 and the 2nd will have id=2. This could fail on
|
// attachment we add will be id=1 and the 2nd will have id=2. This could fail on
|
||||||
// a legitimate implementation. Asserts below will catch this and fail the test
|
// a legitimate implementation. Asserts below will catch this and fail the test
|
||||||
// if necessary.
|
// if necessary.
|
||||||
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1, attachment1Id);
|
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
|
||||||
Uri attachment2Uri = AttachmentProvider.getAttachmentUri(account1, attachment2Id);
|
Uri attachment2Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
|
||||||
Uri attachment3Uri = AttachmentProvider.getAttachmentUri(account1, attachment3Id);
|
Uri attachment3Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
|
||||||
|
|
||||||
// Test with no attached database - should return null, but throws SQLiteException
|
// Test with no attached database - should return null
|
||||||
Cursor c;
|
Cursor c = mMockResolver.query(attachment1Uri, (String[])null, null, (String[])null, null);
|
||||||
try {
|
assertNull(c);
|
||||||
c = mMockResolver.query(attachment1Uri, (String[])null, null, (String[])null, null);
|
|
||||||
fail("Should throw an exception on a bad URI");
|
|
||||||
} catch (SQLiteException sqe) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with an attached database, but no attachment found - should return null
|
// Test with an attached database, but no attachment found - should return null
|
||||||
setupAttachmentDatabase(account1);
|
setupAttachmentDatabase(account1);
|
||||||
|
@ -141,26 +135,26 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
Attachment newAttachment1 = ProviderTestUtils.setupAttachment(message1Id, "file1", 100,
|
Attachment newAttachment1 = ProviderTestUtils.setupAttachment(message1Id, "file1", 100,
|
||||||
false, mMockContext);
|
false, mMockContext);
|
||||||
newAttachment1.mContentUri =
|
newAttachment1.mContentUri =
|
||||||
AttachmentProvider.getAttachmentUri(account1, attachment1Id).toString();
|
AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id).toString();
|
||||||
attachment1Id = addAttachmentToDb(account1, newAttachment1);
|
attachment1Id = addAttachmentToDb(account1, newAttachment1);
|
||||||
assertEquals("Broken test: Unexpected id assignment", 1, attachment1Id);
|
assertEquals("Broken test: Unexpected id assignment", 1, attachment1Id);
|
||||||
|
|
||||||
Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message1Id, "file2", 200,
|
Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message1Id, "file2", 200,
|
||||||
false, mMockContext);
|
false, mMockContext);
|
||||||
newAttachment2.mContentUri =
|
newAttachment2.mContentUri =
|
||||||
AttachmentProvider.getAttachmentUri(account1, attachment2Id).toString();
|
AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id).toString();
|
||||||
attachment2Id = addAttachmentToDb(account1, newAttachment2);
|
attachment2Id = addAttachmentToDb(account1, newAttachment2);
|
||||||
assertEquals("Broken test: Unexpected id assignment", 2, attachment2Id);
|
assertEquals("Broken test: Unexpected id assignment", 2, attachment2Id);
|
||||||
|
|
||||||
Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message1Id, "file3", 300,
|
Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message1Id, "file3", 300,
|
||||||
false, mMockContext);
|
false, mMockContext);
|
||||||
newAttachment3.mContentUri =
|
newAttachment3.mContentUri =
|
||||||
AttachmentProvider.getAttachmentUri(account1, attachment3Id).toString();
|
AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id).toString();
|
||||||
attachment3Id = addAttachmentToDb(account1, newAttachment3);
|
attachment3Id = addAttachmentToDb(account1, newAttachment3);
|
||||||
assertEquals("Broken test: Unexpected id assignment", 3, attachment3Id);
|
assertEquals("Broken test: Unexpected id assignment", 3, attachment3Id);
|
||||||
|
|
||||||
// Return a row with all columns specified
|
// Return a row with all columns specified
|
||||||
attachment2Uri = AttachmentProvider.getAttachmentUri(account1, attachment2Id);
|
attachment2Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
|
||||||
c = mMockResolver.query(
|
c = mMockResolver.query(
|
||||||
attachment2Uri,
|
attachment2Uri,
|
||||||
new String[] { AttachmentProviderColumns._ID, AttachmentProviderColumns.DATA,
|
new String[] { AttachmentProviderColumns._ID, AttachmentProviderColumns.DATA,
|
||||||
|
@ -175,7 +169,7 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
assertEquals(200, c.getInt(3)); // size
|
assertEquals(200, c.getInt(3)); // size
|
||||||
|
|
||||||
// Return a row with permuted columns
|
// Return a row with permuted columns
|
||||||
attachment3Uri = AttachmentProvider.getAttachmentUri(account1, attachment3Id);
|
attachment3Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
|
||||||
c = mMockResolver.query(
|
c = mMockResolver.query(
|
||||||
attachment3Uri,
|
attachment3Uri,
|
||||||
new String[] { AttachmentProviderColumns.SIZE,
|
new String[] { AttachmentProviderColumns.SIZE,
|
||||||
|
@ -204,7 +198,7 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
long attachment2Id = 2;
|
long attachment2Id = 2;
|
||||||
long attachment3Id = 3;
|
long attachment3Id = 3;
|
||||||
|
|
||||||
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1, attachment1Id);
|
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
|
||||||
|
|
||||||
// Test with no attached database - should return null
|
// Test with no attached database - should return null
|
||||||
String type = mMockResolver.getType(attachment1Uri);
|
String type = mMockResolver.getType(attachment1Uri);
|
||||||
|
@ -224,14 +218,14 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
|
|
||||||
Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message1Id, "file3", 100,
|
Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message1Id, "file3", 100,
|
||||||
false, mMockContext);
|
false, mMockContext);
|
||||||
newAttachment2.mMimeType = "text/plain";
|
newAttachment3.mMimeType = "text/plain";
|
||||||
attachment3Id = addAttachmentToDb(account1, newAttachment2);
|
attachment3Id = addAttachmentToDb(account1, newAttachment3);
|
||||||
|
|
||||||
// Check the returned filetypes
|
// Check the returned filetypes
|
||||||
Uri uri = AttachmentProvider.getAttachmentUri(account1, attachment2Id);
|
Uri uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
|
||||||
type = mMockResolver.getType(uri);
|
type = mMockResolver.getType(uri);
|
||||||
assertEquals("image/jpg", type);
|
assertEquals("image/jpg", type);
|
||||||
uri = AttachmentProvider.getAttachmentUri(account1, attachment3Id);
|
uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
|
||||||
type = mMockResolver.getType(uri);
|
type = mMockResolver.getType(uri);
|
||||||
assertEquals("text/plain", type);
|
assertEquals("text/plain", type);
|
||||||
|
|
||||||
|
@ -261,8 +255,8 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
// attachment we add will be id=1 and the 2nd will have id=2. This could fail on
|
// attachment we add will be id=1 and the 2nd will have id=2. This could fail on
|
||||||
// a legitimate implementation. Asserts below will catch this and fail the test
|
// a legitimate implementation. Asserts below will catch this and fail the test
|
||||||
// if necessary.
|
// if necessary.
|
||||||
Uri file1Uri = AttachmentProvider.getAttachmentUri(account1, attachment1Id);
|
Uri file1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
|
||||||
Uri file2Uri = AttachmentProvider.getAttachmentUri(account1, attachment2Id);
|
Uri file2Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
|
||||||
|
|
||||||
// Test with no attached database - should throw an exception
|
// Test with no attached database - should throw an exception
|
||||||
AssetFileDescriptor afd;
|
AssetFileDescriptor afd;
|
||||||
|
@ -302,7 +296,7 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
false, mMockContext);
|
false, mMockContext);
|
||||||
newAttachment2.mContentId = null;
|
newAttachment2.mContentId = null;
|
||||||
newAttachment2.mContentUri =
|
newAttachment2.mContentUri =
|
||||||
AttachmentProvider.getAttachmentUri(account1, attachment2Id).toString();
|
AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id).toString();
|
||||||
newAttachment2.mMimeType = "image/png";
|
newAttachment2.mMimeType = "image/png";
|
||||||
attachment2Id = addAttachmentToDb(account1, newAttachment2);
|
attachment2Id = addAttachmentToDb(account1, newAttachment2);
|
||||||
assertEquals("Broken test: Unexpected id assignment", 2, attachment2Id);
|
assertEquals("Broken test: Unexpected id assignment", 2, attachment2Id);
|
||||||
|
@ -340,17 +334,13 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
Uri thumb2Uri = AttachmentProvider.getAttachmentThumbnailUri(account1, attachment2Id,
|
Uri thumb2Uri = AttachmentProvider.getAttachmentThumbnailUri(account1, attachment2Id,
|
||||||
62, 62);
|
62, 62);
|
||||||
|
|
||||||
// Test with no attached database - should throw an exception
|
// Test with no attached database - should return null (used to throw SQLiteException)
|
||||||
try {
|
AssetFileDescriptor afd = mMockResolver.openAssetFileDescriptor(thumb1Uri, "r");
|
||||||
/* AssetFileDescriptor afd = */ mMockResolver.openAssetFileDescriptor(thumb1Uri, "r");
|
assertNull(afd);
|
||||||
fail("Should throw an exception on a bad URI");
|
|
||||||
} catch (SQLiteException sqe) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with an attached database, but no attachment found
|
// Test with an attached database, but no attachment found
|
||||||
setupAttachmentDatabase(account1);
|
setupAttachmentDatabase(account1);
|
||||||
AssetFileDescriptor afd = mMockResolver.openAssetFileDescriptor(thumb1Uri, "r");
|
afd = mMockResolver.openAssetFileDescriptor(thumb1Uri, "r");
|
||||||
assertNull(afd);
|
assertNull(afd);
|
||||||
|
|
||||||
// Add an attachment (but no associated file)
|
// Add an attachment (but no associated file)
|
||||||
|
@ -369,7 +359,7 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
false, mMockContext);
|
false, mMockContext);
|
||||||
newAttachment2.mContentId = null;
|
newAttachment2.mContentId = null;
|
||||||
newAttachment2.mContentUri =
|
newAttachment2.mContentUri =
|
||||||
AttachmentProvider.getAttachmentUri(account1, attachment2Id).toString();
|
AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id).toString();
|
||||||
newAttachment2.mMimeType = "image/png";
|
newAttachment2.mMimeType = "image/png";
|
||||||
attachment2Id = addAttachmentToDb(account1, newAttachment2);
|
attachment2Id = addAttachmentToDb(account1, newAttachment2);
|
||||||
assertEquals("Broken test: Unexpected id assignment", 2, attachment2Id);
|
assertEquals("Broken test: Unexpected id assignment", 2, attachment2Id);
|
||||||
|
@ -397,20 +387,16 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
// attachment we add will be id=1 and the 2nd will have id=2. This could fail on
|
// attachment we add will be id=1 and the 2nd will have id=2. This could fail on
|
||||||
// a legitimate implementation. Asserts below will catch this and fail the test
|
// a legitimate implementation. Asserts below will catch this and fail the test
|
||||||
// if necessary.
|
// if necessary.
|
||||||
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1, attachment1Id);
|
Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
|
||||||
|
|
||||||
// Test with no attached database - should return null, but throws SQLiteException
|
// Test with no attached database - should return input
|
||||||
try {
|
Uri result = AttachmentProvider.resolveAttachmentIdToContentUri(
|
||||||
Uri result = AttachmentProvider.resolveAttachmentIdToContentUri(
|
|
||||||
mMockResolver, attachment1Uri);
|
mMockResolver, attachment1Uri);
|
||||||
fail("Expected an exception on a bad URI");
|
assertEquals(attachment1Uri, result);
|
||||||
} catch (SQLiteException sqe) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with an attached database, but no attachment found - should return input
|
// Test with an attached database, but no attachment found - should return input
|
||||||
setupAttachmentDatabase(account1);
|
setupAttachmentDatabase(account1);
|
||||||
Uri result = AttachmentProvider.resolveAttachmentIdToContentUri(
|
result = AttachmentProvider.resolveAttachmentIdToContentUri(
|
||||||
mMockResolver, attachment1Uri);
|
mMockResolver, attachment1Uri);
|
||||||
assertEquals(attachment1Uri, result);
|
assertEquals(attachment1Uri, result);
|
||||||
|
|
||||||
|
@ -451,7 +437,7 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
String localStoreUri = "local://localhost/" + dbName(forAccount);
|
String localStoreUri = "local://localhost/" + dbName(forAccount);
|
||||||
mLocalStore = (LocalStore) LocalStore.newInstance(localStoreUri, mMockContext, null);
|
mLocalStore = (LocalStore) LocalStore.newInstance(localStoreUri, mMockContext, null);
|
||||||
} else {
|
} else {
|
||||||
throw new java.lang.UnsupportedOperationException();
|
// Nothing to do - EmailProvider is already available for us
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,7 +468,8 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new java.lang.UnsupportedOperationException();
|
newAttachment.save(mMockContext);
|
||||||
|
attachmentId = newAttachment.mId;
|
||||||
}
|
}
|
||||||
return attachmentId;
|
return attachmentId;
|
||||||
}
|
}
|
||||||
|
@ -507,7 +494,11 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
|
||||||
return new File(mMockContext.getDatabasePath(forAccount.mCompatibilityUuid + ".db_att"),
|
return new File(mMockContext.getDatabasePath(forAccount.mCompatibilityUuid + ".db_att"),
|
||||||
idString);
|
idString);
|
||||||
} else {
|
} else {
|
||||||
throw new java.lang.UnsupportedOperationException();
|
File attachmentsDir = mMockContext.getDatabasePath(forAccount.mId + ".db_att");
|
||||||
|
if (!attachmentsDir.exists()) {
|
||||||
|
attachmentsDir.mkdirs();
|
||||||
|
}
|
||||||
|
return new File(attachmentsDir, idString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue