Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to access session_database.key before it is created #2846

Closed
tonkku107 opened this issue May 14, 2024 · 4 comments · Fixed by #2853
Closed

Trying to access session_database.key before it is created #2846

tonkku107 opened this issue May 14, 2024 · 4 comments · Fixed by #2853
Labels
O-Uncommon Most users are unlikely to come across this or unexpected workflow S-Critical Prevents work, causes data loss and/or has no workaround T-Defect Something isn't working: bugs, crashes, hangs and other reported problems

Comments

@tonkku107
Copy link
Contributor

Steps to reproduce

  1. Fresh install on an Android 6 emulator
  2. Launch the app

Outcome

What did you expect?

App to start successfully

What happened instead?

App crashes immediately with the following exception

FATAL EXCEPTION: main
Process: io.element.android.x.debug, PID: 4020
java.lang.RuntimeException: Unable to create application io.element.android.x.ElementXApplication: androidx.startup.StartupException: java.io.FileNotFoundException: /data/user/0/io.element.android.x.debug/databases/session_database.key: open failed: ENOENT (No such file or directory)
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4710)
	at android.app.ActivityThread.-wrap1(ActivityThread.java)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
	at android.os.Handler.dispatchMessage(Handler.java:102)
	at android.os.Looper.loop(Looper.java:148)
	at android.app.ActivityThread.main(ActivityThread.java:5417)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: androidx.startup.StartupException: java.io.FileNotFoundException: /data/user/0/io.element.android.x.debug/databases/session_database.key: open failed: ENOENT (No such file or directory)
	at androidx.startup.AppInitializer.doInitialize(AppInitializer.java:187)
	at androidx.startup.AppInitializer.doInitialize(AppInitializer.java:138)
	at androidx.startup.AppInitializer.initializeComponent(AppInitializer.java:117)
	at io.element.android.x.ElementXApplication.onCreate(ElementXApplication.kt:36)
	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707)
	at android.app.ActivityThread.-wrap1(ActivityThread.java) 
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) 
	at android.os.Handler.dispatchMessage(Handler.java:102) 
	at android.os.Looper.loop(Looper.java:148) 
	at android.app.ActivityThread.main(ActivityThread.java:5417) 
	at java.lang.reflect.Method.invoke(Native Method) 
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: java.io.FileNotFoundException: /data/user/0/io.element.android.x.debug/databases/session_database.key: open failed: ENOENT (No such file or directory)
	at libcore.io.IoBridge.open(IoBridge.java:452)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
	at androidx.security.crypto.EncryptedFile.openFileOutput(EncryptedFile.java:262)
	at io.element.encrypteddb.passphrase.RandomSecretPassphraseProvider.getPassphrase(RandomSecretPassphraseProvider.kt:40)
	at io.element.encrypteddb.SqlCipherDriverFactory.create(SqlCipherDriverFactory.kt:41)
	at io.element.android.libraries.sessionstorage.impl.di.SessionStorageModule.provideMatrixDatabase(SessionStorageModule.kt:40)
	at io.element.android.libraries.sessionstorage.impl.di.SessionStorageModule_ProvideMatrixDatabaseFactory$Companion.provideMatrixDatabase(SessionStorageModule_ProvideMatrixDatabaseFactory.kt:32)
	at io.element.android.libraries.sessionstorage.impl.di.SessionStorageModule_ProvideMatrixDatabaseFactory.get(SessionStorageModule_ProvideMatrixDatabaseFactory.kt:23)
	at io.element.android.libraries.sessionstorage.impl.di.SessionStorageModule_ProvideMatrixDatabaseFactory.get(SessionStorageModule_ProvideMatrixDatabaseFactory.kt:20)
	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
	at io.element.android.libraries.sessionstorage.impl.DatabaseSessionStore_Factory.get(DatabaseSessionStore_Factory.kt:21)
	at io.element.android.libraries.sessionstorage.impl.DatabaseSessionStore_Factory.get(DatabaseSessionStore_Factory.kt:17)
	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
	at io.element.android.features.rageshake.impl.reporter.DefaultBugReporter_Factory.get(DefaultBugReporter_Factory.kt:40)
	at io.element.android.features.rageshake.impl.reporter.DefaultBugReporter_Factory.get(DefaultBugReporter_Factory.kt:26)
	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
	at io.element.android.x.di.DaggerAppComponent$AppComponentImpl.bugReporter(DaggerAppComponent.java:2969)
	at io.element.android.x.initializer.TracingInitializer.create(TracingInitializer.kt:37)
	at io.element.android.x.initializer.TracingInitializer.create(TracingInitializer.kt:33)
	at androidx.startup.AppInitializer.doInitialize(AppInitializer.java:180)
	at androidx.startup.AppInitializer.doInitialize(AppInitializer.java:138) 
	at androidx.startup.AppInitializer.initializeComponent(AppInitializer.java:117) 
	at io.element.android.x.ElementXApplication.onCreate(ElementXApplication.kt:36) 
	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013) 
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707) 
	at android.app.ActivityThread.-wrap1(ActivityThread.java) 
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) 
	at android.os.Handler.dispatchMessage(Handler.java:102) 
	at android.os.Looper.loop(Looper.java:148) 
	at android.app.ActivityThread.main(ActivityThread.java:5417) 
	at java.lang.reflect.Method.invoke(Native Method) 
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
	at libcore.io.Posix.open(Native Method)
	at libcore

Your phone model

Android studio emulator

Operating system version

Android 6

Application version and app store

Built from develop (4f74dd4)

Homeserver

N/A

Will you send logs?

Yes

Are you willing to provide a PR?

No

@tonkku107 tonkku107 added the T-Defect Something isn't working: bugs, crashes, hangs and other reported problems label May 14, 2024
@jmartinesp
Copy link
Member

It seems like an issue with androidx.security.crypto.EncryptedFile which was the official way to use this but it was deprecated not long ago.

We'll have to create our own alternative. In the meantime don't bother testing on Android 6.

@jmartinesp jmartinesp added S-Critical Prevents work, causes data loss and/or has no workaround O-Uncommon Most users are unlikely to come across this or unexpected workflow labels May 15, 2024
@jmartinesp
Copy link
Member

jmartinesp commented May 15, 2024

To ellaborate a bit, the failing code is:

if (mFile.exists()) {
    throw new IOException("output file already exists, please use a new file: "
            + mFile.getName());
}
FileOutputStream fileOutputStream = new FileOutputStream(mFile); // Crash here with FileNotFoundException

So if we pass an existing file it will throw an exception but if we pass a non existing one (the current case) it fails on Android 6 for some reason. I wonder how it worked before and why it's failing now.

@tonkku107
Copy link
Contributor Author

Testing on a branch based off of e95d24d didn't cause this error. Since then 5c59f6c looks like the only commit that has anything to do with the session store

@jmartinesp
Copy link
Member

Ok, I think I found the root cause: on modern Android versions apparently creating a FileOutputStream and using it will create the file, including all the dirs in its path if they don't exist, either that or some other feature of the app creates the parent directory.

On Android 6 this parent directory doesn't exist when we try to do the migration added in the commit you mentioned above if the app was just installed, so we need to create it ourselves. I'll create a PR with a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-Uncommon Most users are unlikely to come across this or unexpected workflow S-Critical Prevents work, causes data loss and/or has no workaround T-Defect Something isn't working: bugs, crashes, hangs and other reported problems
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants