Skip to content

Weird unpacking behavior on Android #2051

Description

@treeFromHell

I am using the Vosk API in Android Studio on a virtual Fairphone 5. I want to use multiple models in my app, although not at the same time. So at launch I check whether models have already been loaded into internal storage or whether I need to unpack them first.
If they do not exist already, I unpack all of them by calling:

Method 1:
StorageService.unpack(this, "english-model", "vosk-english-model", ...)
StorageService.unpack(this, "german-model", "vosk-german-model", ...)
StorageService.unpack(this, "russian-model", "vosk-russian-model", ...)

I tested this at least 10 times sometimes before clearing the internal storage and sometimes not.
The behavior is consistent and as expected. If the models exist they are recognized, otherwise they are unpacked.
No issues.

But I noticed the method does not just copy the contents of the source directory into the target directory, but it also copies the source directory itself. In the file explorer I get:
Android / data / package.name / files / vosk-english-model / english-model / actual content
and similarly for the other two models.
The "vosk-english-model" directory and the "english-model" directory are doing the exact same thing, there is no point in having both.

So I tried instead calling:

Method 2:
StorageService.unpack(this, "english-model", "vosk-models", ...)
StorageService.unpack(this, "german-model", "vosk-models", ...)
StorageService.unpack(this, "russian-model", "vosk-models", ...)

or

Method 3:
StorageService.unpack(this, "english-model", "", ...)
StorageService.unpack(this, "german-model", "", ...)
StorageService.unpack(this, "russian-model", "", ...)

One or two of the models succesfully unpacks, but at least one of them always fails for one of the following reasons at first launch:

java.io.FileNotFoundException: /storage/emulated/0/Android/data/package.name/files/vosk-models/language-model/README: open failed: ENOENT (No such file or directory)

java.io.FileNotFoundException: /storage/emulated/0/Android/data/package.name/files/vosk-models/language-model/COPYING: open failed: ENOENT (No such file or directory)

java.io.FileNotFoundException: /storage/emulated/0/Android/data/package.name/files/vosk-models/language-model/am/tree: open failed: ENOENT (No such file or directory)

These files are existent in the assets before unpacking btw and this error NEVER appears when I use method 1.

I tested all methods extensively dozens of times and wiped the internal storage in between attempts and the result is consistently this:

Method 1 always works without issues

Method 2 or Method 3 always fails with a random FileNotFoundException for at least one of the models, for a file that does exist in the source assets and is found in other attempts.

There is one exception to these findings:
Exactly one of the dozens of test runs has ended in method 3 succesfully unpacking all 3 models.

This must be a bug in the implementation of the API. There should be no race condition in a sensible implementation, because the different unpack invocations do not touch the same files. Each invocation should logically just create a directory for the model it wants to unpack and then work inside of there independently of the other invocations. It should not matter whether this newly created directory is neighboring the newly created directories of the other invocations.

Also the documentation of the API is severly lacking. For example, it is unclear whether Model.close() releases all the memory hogged by a model and in what state the object is left behind.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions