Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ section the body of the GitHub release, and refuses a version without one. `scri

## Unreleased

- Word, Excel and PowerPoint files that a mail or file app labels the old way offer to open
in the app again.

## 4.21.0

- Spreadsheet cells can be formatted: fill, bold, italic, underline, strikethrough,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,28 @@ class SupportedFormatsTest {
}
}

/**
* A spelling the core does not name, but a mail or file app sends, reaches us on both sides.
*/
@Test
fun anAliasSpellingReachesUs() {
for ((alias, named) in SupportedDocumentTypes.MIME_ALIASES) {
Assert.assertTrue(
"the app does not offer for $alias",
SupportedDocumentTypes.isSupported(alias, null),
)
Assert.assertTrue(
"the manifest does not offer for $alias",
resolvesToUs(alias, "document"),
)
Assert.assertEquals(
"$alias is not read as $named",
SupportedDocumentTypes.canonicalMimeType(named),
SupportedDocumentTypes.canonicalMimeType(alias),
)
}
}

/** And the same route stays shut for what the app does not claim. */
@Test
fun aFileWithNoMimeTypeAndAnUnrelatedExtensionReachesNobody() {
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,23 @@
<data android:mimeType="application/x-iwork-numbers-sffnumbers" />
<data android:mimeType="application/vnd.apple.keynote" />
<data android:mimeType="application/x-iwork-keynote-sffkey" />
<!--
spellings odrcore does not name, which SupportedDocumentTypes.MIME_ALIASES
maps to ones it does. the two lists have to match.
-->
<data android:mimeType="application/x-msword" />
<data android:mimeType="application/doc" />
<data android:mimeType="application/x-doc" />
<data android:mimeType="application/vnd.msword" />
<data android:mimeType="application/word" />
<data android:mimeType="application/x-msexcel" />
<data android:mimeType="application/x-ms-excel" />
<data android:mimeType="application/x-excel" />
<data android:mimeType="application/excel" />
<data android:mimeType="application/vnd.msexcel" />
<data android:mimeType="application/x-mspowerpoint" />
<data android:mimeType="application/powerpoint" />
<data android:mimeType="application/x-powerpoint" />
<!--
the octet-stream a provider volunteers when it knows nothing better.
only the filename can answer for it - the pathPattern filter below.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,30 @@ object SupportedDocumentTypes {
/** Every mime type spelling odrcore accepts for a format [CoreLoader] renders. */
private val CORE_MIME_TYPES: Set<String> by lazy { mimeTypesOf(CORE_FILE_TYPES) }

/**
* Spellings of the binary office formats that mail and file apps send and odrcore does not
* name, each mapped to one it does. The manifest claims them as well; the bytes decide once the
* file is cached.
*/
internal val MIME_ALIASES =
mapOf(
"application/x-msword" to "application/msword",
"application/doc" to "application/msword",
"application/x-doc" to "application/msword",
"application/vnd.msword" to "application/msword",
"application/word" to "application/msword",
"application/x-msexcel" to "application/vnd.ms-excel",
"application/x-ms-excel" to "application/vnd.ms-excel",
"application/x-excel" to "application/vnd.ms-excel",
"application/excel" to "application/vnd.ms-excel",
"application/vnd.msexcel" to "application/vnd.ms-excel",
"application/x-mspowerpoint" to "application/vnd.ms-powerpoint",
"application/powerpoint" to "application/vnd.ms-powerpoint",
"application/x-powerpoint" to "application/vnd.ms-powerpoint",
)

/** The same for everything the app offers itself for. */
val MIME_TYPES: Set<String> by lazy { mimeTypesOf(CLAIMED_FILE_TYPES) }
val MIME_TYPES: Set<String> by lazy { mimeTypesOf(CLAIMED_FILE_TYPES) + MIME_ALIASES.keys }

/**
* The extension fallback, for the `application/octet-stream` providers regularly volunteer and
Expand All @@ -83,12 +105,14 @@ object SupportedDocumentTypes {
return null
}

val fileType = Odr.fileTypeByMimetype(mimeType) ?: return mimeType
val named = MIME_ALIASES[mimeType.lowercase()] ?: mimeType

val fileType = Odr.fileTypeByMimetype(named) ?: return named
if (fileType == FileType.UNKNOWN) {
return mimeType
return named
}

return Odr.mimetypeByFileType(fileType) ?: mimeType
return Odr.mimetypeByFileType(fileType) ?: named
}

/** Whether [CoreLoader] is expected to render this - see [CORE_FILE_TYPES]. */
Expand Down
Loading