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 * 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 * <pre>
* app to open it. * |---------------------------------------------------------|
* If the given mime type is non-empty and anything other than "application/octet-stream", * | E X T E N S I O N |
* 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. * | .eml | known(.png) | unknown(.abc) | none |
* If the filename has an unrecognized extension, return "application/extension" * | M |-----------------------------------------------------------------------|
* Otherwise return "application/octet-stream". * | 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 fileName The given filename
* @param mimeType The given mime type * @param mimeType The given mime type
* @return A likely mime type for the attachment * @return A likely mime type for the attachment
*/ */
public static String inferMimeType(final String fileName, final String mimeType) { public static String inferMimeType(final String fileName, final String mimeType) {
String resultType = null;
// NOTE mime-types are case-*sensitive* on Android. String fileExtension = getFilenameExtension(fileName);
// Return values from this method MUST always in lowercase.
String result = null;
if (fileName != null && fileName.toLowerCase().endsWith(".eml")) {
result = "message/rfc822";
} else {
// If the given mime type appears to be non-empty and non-generic - return it
boolean isTextPlain = "text/plain".equalsIgnoreCase(mimeType); boolean isTextPlain = "text/plain".equalsIgnoreCase(mimeType);
if (!TextUtils.isEmpty(mimeType) &&
!"application/octet-stream".equalsIgnoreCase(mimeType) && !isTextPlain) { if ("eml".equals(fileExtension)) {
result = mimeType; resultType = "message/rfc822";
} else { } else {
// Try to find an extension in the filename boolean isGenericType =
if (!TextUtils.isEmpty(fileName)) { isTextPlain || "application/octet-stream".equalsIgnoreCase(mimeType);
String extension = getFilenameExtension(fileName); // If the given mime type is non-empty and non-generic, return it
if (!TextUtils.isEmpty(extension)) { if (isGenericType || TextUtils.isEmpty(mimeType)) {
// Extension found. Look up mime type, or synthesize if none found. if (!TextUtils.isEmpty(fileExtension)) {
result = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); // Otherwise, try to find a mime type based upon the file extension
if (TextUtils.isEmpty(result)) { resultType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
// If original mimetype is text/plain, us it; otherwise synthesize if (TextUtils.isEmpty(resultType)) {
result = isTextPlain ? mimeType : "application/" + extension; // Finally, if original mimetype is text/plain, use it; otherwise synthesize
} resultType = isTextPlain ? mimeType : "application/" + fileExtension;
} }
} }
} else {
resultType = mimeType;
} }
} }
if (TextUtils.isEmpty(result)) { // No good guess could be made; use an appropriate generic type
// Fallback case - no good guess could be made. if (TextUtils.isEmpty(resultType)) {
result = "application/octet-stream"; 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() * Test static inferMimeType()
* From the method doc: * From the method doc:
* If the file extension is ".eml", return "message/rfc822", which is necessary for the email *
* app to open it. * <pre>
* If the given mime type is non-empty and anything other than "application/octet-stream", * |---------------------------------------------------------|
* just return it. (This is the most common case.) * | E X T E N S I O N |
* 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" * | .eml | known(.png) | unknown(.abc) | none |
* Otherwise return "application/octet-stream". * | 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. * 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_MIX = "Application/Octet-stream";
final String DEFAULT_LOWER = DEFAULT_MIX.toLowerCase(); final String DEFAULT_LOWER = DEFAULT_MIX.toLowerCase();
final String TEXT_PLAIN = "text/plain"; 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_ABC = "myfile.false.aBc";
final String FILE_NO_EXT = "myfile"; final String FILE_NO_EXT = "myfile";
// If the given mime type is non-empty and anything other than "application/octet-stream", // .eml files always override mime type
// just return it. (This is the most common case.) 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(null, "Mime/TyPe"));
assertEquals("mime/type", AttachmentProvider.inferMimeType("", "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. // Recognizable file extension; return known type
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, null)); assertEquals("image/png", AttachmentProvider.inferMimeType(FILE_PNG, null));
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, "")); assertEquals("image/png", AttachmentProvider.inferMimeType(FILE_PNG, ""));
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, DEFAULT_MIX)); 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, null));
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, "")); assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, ""));
assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, DEFAULT_MIX)); 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, null));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, "")); assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, ""));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, DEFAULT_MIX)); assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, DEFAULT_MIX));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(null, null)); assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(null, null));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType("", "")); assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType("", ""));
// If mime type can be inferred, return it; otherwise return text/plain // Unrecognized or empty file extension, "text/plain" type; return "text/plain"
assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, TEXT_PLAIN));
assertEquals(DEFAULT_LOWER, AttachmentProvider.inferMimeType(FILE_NO_EXT, TEXT_PLAIN));
assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType(FILE_ABC, TEXT_PLAIN)); assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType(FILE_ABC, TEXT_PLAIN));
assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType(FILE_NO_EXT, TEXT_PLAIN));
// Test for eml files. assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType(null, TEXT_PLAIN));
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eMl", "Text/Plain")); assertEquals(TEXT_PLAIN, AttachmentProvider.inferMimeType("", TEXT_PLAIN));
assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eml", DEFAULT_MIX));
} }
/** /**