[TIMOB-28190] Android: App randomly crashes when selecting the image in Ti.Media.showCamera
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Critical |
Status | Open |
Resolution | Unresolved |
Affected Version/s | Release 9.3.0, Release 9.2.1 |
Fix Version/s | n/a |
Components | Android |
Labels | n/a |
Reporter | Hans Knöchel |
Assignee | Unknown |
Created | 2020-10-13T11:30:35.000+0000 |
Updated | 2020-10-14T14:18:55.000+0000 |
Description
When selecting the image that was taken by a Ti.Media.showCamera call, the app sometimes crashes (not even always and not on all devices). Here is the stack:
2020-10-13 12:41:19.961 1568-2601/? W/ActivityManager: Permission Denial: opening provider org.appcelerator.titanium.io.TiFileProvider from ProcessRecord{f2b359c 20305:com.android.camera/u0a57} (pid=20305, uid=10057) that is not exported from UID 10559
2020-10-13 12:41:19.967 20305-20305/? E/CAM_Camera2Module: Exception when doAttach:
java.lang.SecurityException: Permission Denial: opening provider org.appcelerator.titanium.io.TiFileProvider from ProcessRecord{f2b359c 20305:com.android.camera/u0a57} (pid=20305, uid=10057) that is not exported from UID 10559
at android.os.Parcel.createException(Parcel.java:2074)
at android.os.Parcel.readException(Parcel.java:2042)
at android.os.Parcel.readException(Parcel.java:1990)
at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:5283)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:6723)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2749)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:2133)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1520)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:1242)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:1218)
at com.android.camera.module.Camera2Module.doAttach(Camera2Module.java:8)
at com.android.camera.module.Camera2Module.onReviewDoneClicked(Camera2Module.java:1)
at com.android.camera.fragment.FragmentBottomIntentDone.onClick(FragmentBottomIntentDone.java:4)
at android.view.View.performClick(View.java:7250)
at android.view.View.performClickInternal(View.java:7227)
at android.view.View.access$3500(View.java:819)
at android.view.View$PerformClick.run(View.java:27749)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7562)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.am.ActivityManagerService.getContentProviderImpl(ActivityManagerService.java:7182)
at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7525)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2179)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2799)
at android.os.Binder.execTransactInternal(Binder.java:1021)
Attachments
File | Date | Size |
---|---|---|
CameraPhotoExternalTest.js | 2020-10-13T23:39:30.000+0000 | 984 |
CameraPhotoInternalTest.js | 2020-10-14T00:03:00.000+0000 | 1465 |
I'm only able to reproduce this issue by force-quitting the app while the camera displayed. Afterwards, when you take the photo, I'll get this exact same exception. This makes sense because Titanium grants the camera app temporary permission to the sandboxed file using the Titanium app's process UID, but since the app has been terminated that process UID is no longer valid. Subsequent launches of the app use a new process UID. So, I'm thinking the Android OS is running low on memory and is force-quitting the Titanium app once the camera app is displayed. That would explain why this happens randomly. Looking at the
adb logcat
should reveal this. In Titanium, we "could" add intent [FLAG_GRANT_PERSISTABLE_URI_PERMISSION](https://developer.android.com/reference/android/content/Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION) to our code [here](https://github.com/appcelerator/titanium_mobile/blob/9137732c31d9c52f97fc88ed4f7f681a70f25b9d/android/modules/media/src/java/ti/modules/titanium/media/MediaModule.java#L307) which "might" avoid the security exception, but there will still be an issue where the Titanium app will effectively be restarted (because it was force-quit) and you'll not receive the photo because of this. So, ultimately this wouldn't solve anything. _(Normally, Android would temporarily destroy the Titanium app's activity windows instead of killing the app process and then restore the activity windows when returning from the camera. This doesn't appear to be happening in your case.)_ The only work-arounds I can think of are: * Reduce the memory footprint of the app. Particularly if a window is displaying full sized photos. * Use theshowCamera()
method's "overlay" property which display a camera in-app as show in [^CameraPhotoInternalTest.js] .Unfortunately this is not satisfying for us. We have to indicators that point to an issue in the SDK instead of the app itself:
The app did not crash in earlier Titanium releases (SDK 8.x)
The camera (Android Camera2 API) works when built in a native app (which likely has a lighter footprint, I agree)
We will now try to replace the Ti.Media.showCamera() call with another native library (either CameraKit or the JetPack CameraX API - which Titanium should use anyways btw). It's sad to see there is nothing else to be done here. *EDIT*: The overlay workaround worked for us. There are no crashes remaining. It again indicates an issue with the SDK, but we are at least unblocked. Thank you for the hints Josh! *EDIT 2: This causes another blocker (TIMOB-28194), which may be easier to resolve than this one!