hwsecurity-openpgp / de.cotech.hw.openpgp.util / ParcelFileDescriptorUtil /


open class ParcelFileDescriptorUtil

Utility class for loading streamed data into a seekable ParcelFileDescriptor.

This covers the use case of passing streaming data via an ACTION_SEND or similar Intent, without caching to a file. This is especially useful for encrypted files, e.g. from a DecryptingFileInputStream.

Unlike ParcelFileDescriptors obtained from a createPipe, this method returns a seekable ParcelFileDescriptor. In practice, virtually all receivers of Intents with streamed data require seekable file descriptors. android.content.ContentProvider

ParcelFileDescriptor openFile(Uri uri, String mode) {
    try {
        File file = database.getEncryptedFilenameForUri(uri);
        int plaintextLength = getPlaintextLengthForUri(uri);
        return parcelFileDescriptorCompat.loadToParcelFileDescriptor(file, plaintextLength);
    } catch (e: IOException) {
        throw new FileNotFoundException(e.getMessage());

Internally, this uses one of two mechanisms:

  • On Android O (sdk 26) or higher, it uses a android.os.ProxyFileDescriptorCallback backed by a reference-counted android.os.MemoryFile.
  • On earlier Android versions, it falls back to a mechanism based on ephemeral file descriptors. To this end, it creates a file on storage that is deleted immediately after opening a couple of file descriptors. These file descriptors are cached and used for any subsequent access. Note that this method does **not** keep data strictly in-memory, but it's as close as we could get.

Note: in our tests, the technique of extracting the internal file descriptor of a MemoryFile using reflection did not actually yield a seekable ParcelFileDescriptor that worked as intended.


Name Summary
ParcelFileDescriptorUtil open fun ParcelFileDescriptorUtil(context: Context)


Name Summary

interface InputStreamProvider

Simple interface for obtaining an InputStream.


Name Summary

open fun loadToParcelFileDescriptor(inputStreamProvider: ParcelFileDescriptorUtil.InputStreamProvider, cacheId: String): ParcelFileDescriptor

This method

open fun loadToParcelFileDescriptor(inputStreamProvider: ParcelFileDescriptorUtil.InputStreamProvider, cacheId: String, fileSize: Int): ParcelFileDescriptor