Fix attachment mime type unit tests

Attachments with no extension and mime type of text/plain need to return the
mime type of "text/plain" instead of "application/octet-stream"

bug 3428076

Change-Id: I00452c908ac0672879d42f4ed9ee574e376eac9f
This commit is contained in:
Todd Kennedy 2011-02-08 09:43:34 -08:00
parent 6e4df4de7a
commit 8586532f3e
2 changed files with 81 additions and 57 deletions

View File

@ -182,54 +182,62 @@ public class AttachmentProvider extends ContentProvider {
/**
* Helper to convert unknown or unmapped attachments to something useful based on filename
* extensions. Imperfect, but helps.
* extensions. The mime type is inferred based upon the table below. It's not perfect, but
* it helps.
*
* If the file extension is ".eml", return "message/rfc822", which is necessary for the email
* app to open it.
* If the given mime type is non-empty and anything other than "application/octet-stream",
* just return it. (This is the most common case.)
* If the filename has a recognizable extension and it converts to a mime type, return that.
* If the filename has an unrecognized extension, return "application/extension"
* Otherwise return "application/octet-stream".
* <pre>
* |---------------------------------------------------------|
* | E X T E N S I O N |
* |---------------------------------------------------------|
* | .eml | known(.png) | unknown(.abc) | none |
* | M |-----------------------------------------------------------------------|
* | I | none | msg/rfc822 | image/png | app/abc | app/oct-str |
* | M |-------------| (always | | | |
* | E | app/oct-str | overrides | | | |
* | T |-------------| | |-----------------------------|
* | Y | text/plain | | | text/plain |
* | P |-------------| |-------------------------------------------|
* | E | any/type | | any/type |
* |---|-----------------------------------------------------------------------|
* </pre>
*
* NOTE: Since mime types on Android are case-*sensitive*, return values are always in
* lower case.
*
* @param fileName The given filename
* @param mimeType The given mime type
* @return A likely mime type for the attachment
*/
public static String inferMimeType(final String fileName, final String mimeType) {
String resultType = null;
String fileExtension = getFilenameExtension(fileName);
boolean isTextPlain = "text/plain".equalsIgnoreCase(mimeType);
// NOTE mime-types are case-*sensitive* on Android.
// Return values from this method MUST always in lowercase.
String result = null;
if (fileName != null && fileName.toLowerCase().endsWith(".eml")) {
result = "message/rfc822";
if ("eml".equals(fileExtension)) {
resultType = "message/rfc822";
} else {
// If the given mime type appears to be non-empty and non-generic - return it
boolean isTextPlain = "text/plain".equalsIgnoreCase(mimeType);
if (!TextUtils.isEmpty(mimeType) &&
!"application/octet-stream".equalsIgnoreCase(mimeType) && !isTextPlain) {
result = mimeType;
} else {
// Try to find an extension in the filename
if (!TextUtils.isEmpty(fileName)) {
String extension = getFilenameExtension(fileName);
if (!TextUtils.isEmpty(extension)) {
// Extension found. Look up mime type, or synthesize if none found.
result = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (TextUtils.isEmpty(result)) {
// If original mimetype is text/plain, us it; otherwise synthesize
result = isTextPlain ? mimeType : "application/" + extension;
}
boolean isGenericType =
isTextPlain || "application/octet-stream".equalsIgnoreCase(mimeType);
// If the given mime type is non-empty and non-generic, return it
if (isGenericType || TextUtils.isEmpty(mimeType)) {
if (!TextUtils.isEmpty(fileExtension)) {
// Otherwise, try to find a mime type based upon the file extension
resultType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
if (TextUtils.isEmpty(resultType)) {
// Finally, if original mimetype is text/plain, use it; otherwise synthesize
resultType = isTextPlain ? mimeType : "application/" + fileExtension;
}
}
} else {
resultType = mimeType;
}
}
if (TextUtils.isEmpty(result)) {
// Fallback case - no good guess could be made.
result = "application/octet-stream";
// No good guess could be made; use an appropriate generic type
if (TextUtils.isEmpty(resultType)) {
resultType = isTextPlain ? "text/plain" : "application/octet-stream";
}
return result.toLowerCase();
return resultType.toLowerCase();
}
/**

View File

@ -326,13 +326,22 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
/**
* Test static inferMimeType()
* From the method doc:
* If the file extension is ".eml", return "message/rfc822", which is necessary for the email
* app to open it.
* If the given mime type is non-empty and anything other than "application/octet-stream",
* just return it. (This is the most common case.)
* If the filename has a recognizable extension and it converts to a mime type, return that.
* If the filename has an unrecognized extension, return "application/extension"
* Otherwise return "application/octet-stream".
*
* <pre>
* |---------------------------------------------------------|
* | E X T E N S I O N |
* |---------------------------------------------------------|
* | .eml | known(.png) | unknown(.abc) | none |
* | M |-----------------------------------------------------------------------|
* | I | none | msg/rfc822 | image/png | app/abc | app/oct-str |
* | M |-------------| (always | | | |
* | E | app/oct-str | overrides | | | |
* | T |-------------| | |-----------------------------|
* | Y | text/plain | | | text/plain |
* | P |-------------| |-------------------------------------------|
* | E | any/type | | any/type |
* |---|-----------------------------------------------------------------------|
* </pre>
*
* Also, all results should be in lowercase.
*/
@ -340,41 +349,48 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
final String DEFAULT_MIX = "Application/Octet-stream";
final String DEFAULT_LOWER = DEFAULT_MIX.toLowerCase();
final String TEXT_PLAIN = "text/plain";
final String FILE_PDF = "myfile.false.pDf";
final String TYPE_IMG_PNG = "image/png";
final String FILE_PNG = "myfile.false.pNg";
final String FILE_ABC = "myfile.false.aBc";
final String FILE_NO_EXT = "myfile";
// If the given mime type is non-empty and anything other than "application/octet-stream",
// just return it. (This is the most common case.)
// .eml files always override mime type
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eml", null));
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eml", ""));
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eml", DEFAULT_LOWER));
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eMl", TEXT_PLAIN));
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eml", TYPE_IMG_PNG));
// Non-generic, non-empty mime type; return it
assertEquals("mime/type", AttachmentProvider.inferMimeType(FILE_PNG, "Mime/TyPe"));
assertEquals("mime/type", AttachmentProvider.inferMimeType(FILE_ABC, "Mime/TyPe"));
assertEquals("mime/type", AttachmentProvider.inferMimeType(FILE_NO_EXT, "Mime/TyPe"));
assertEquals("mime/type", AttachmentProvider.inferMimeType(null, "Mime/TyPe"));
assertEquals("mime/type", AttachmentProvider.inferMimeType("", "Mime/TyPe"));
assertEquals("mime/type", AttachmentProvider.inferMimeType(FILE_PDF, "Mime/TyPe"));
// If the filename has a recognizable extension and it converts to a mime type, return that.
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, null));
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, ""));
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, DEFAULT_MIX));
// Recognizable file extension; return known type
assertEquals("image/png", AttachmentProvider.inferMimeType(FILE_PNG, null));
assertEquals("image/png", AttachmentProvider.inferMimeType(FILE_PNG, ""));
assertEquals("image/png", AttachmentProvider.inferMimeType(FILE_PNG, DEFAULT_MIX));
assertEquals("image/png", AttachmentProvider.inferMimeType(FILE_PNG, TEXT_PLAIN));
// If the filename has an unrecognized extension, return "application/extension"
// Unrecognized and non-empty file extension, non-"text/plain" type; generate mime type
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, null));
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, ""));
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, DEFAULT_MIX));
// Otherwise return "application/octet-stream".
// Unrecognized and empty file extension, non-"text/plain" type; return "app/octet-stream"
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, null));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, ""));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, DEFAULT_MIX));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(null, null));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType("", ""));
// If mime type can be inferred, return it; otherwise return text/plain
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, TEXT_PLAIN));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, TEXT_PLAIN));
// Unrecognized or empty file extension, "text/plain" type; return "text/plain"
assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType(FILE_ABC, TEXT_PLAIN));
// Test for eml files.
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eMl", "Text/Plain"));
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eml", DEFAULT_MIX));
assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType(FILE_NO_EXT, TEXT_PLAIN));
assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType(null, TEXT_PLAIN));
assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType("", TEXT_PLAIN));
}
/**