apache / cordova-plugin-camera

Apache Cordova Plugin camera
https://cordova.apache.org/
Apache License 2.0
966 stars 1.55k forks source link

App Crash on capture #917

Open jdevuono54 opened 2 weeks ago

jdevuono54 commented 2 weeks ago

Bug Report

Problem

What is expected to happen?

The camera should open, capture a high-quality photo, and return the captured image URI to the application without causing an out-of-memory (OOM) crash.

What does actually happen?

On a Redmi 9A device, the application crashes right after pressing the capture button in the camera interface, before reaching onActivityResult. The crash log indicates an OOM error.

Information

Log Output:

2024-11-06 11:21:18.432 29632-29784 cr_ChildProcessConn     [APP_NAME]                   W  onServiceDisconnected (crash or killed by oom): pid=29786 bindings:W  S
2024-11-06 11:21:18.671 29632-29632 chromium                [APP_NAME]                   E  [ERROR:aw_browser_terminator.cc(165)] Renderer process (29786) crash detected (code -1).

Command or Code

return new Promise((resolve, reject) => {
            navigator.camera.getPicture(path => {
                Filesystem.resolveUrl(path).then(resolve, reject);
            }, error => {

                if (error === 'No Image Selected'){ return resolve(null); }

                reject(error);
            }, {
                destinationType: Camera.DestinationType.FILE_URI,
                sourceType: Camera.PictureSourceType.CAMERA,
                quality: 100,
                allowEdit: false,
                correctOrientation: true,
                saveToPhotoAlbum: true,
                encodingType: Camera.EncodingType.JPEG,
                mediaType: Camera.MediaType.PICTURE
            });
        }) as unknown as Promise<Entry>;

Environment, Platform, Device

Version information

Checklist

breautek commented 2 weeks ago

Can you share a full stacktrace or logcat logs for your app starting approximately from the getPicture call?

Are you sure that the activity simply isn't being closed (which is an documented behaviour and should be expected)? If this the case, the camera app should work properly and it will write the result to disk. When the camera activity closes and returns to your app, the app's activity needs to be recreated, which means the webview needs to be recreated and reloaded. When this happen the result will be supplied in the resume event.

2024-11-06 11:21:18.432 29632-29784 cr_ChildProcessConn     [APP_NAME]                   W  onServiceDisconnected (crash or killed by oom): pid=29786 bindings:W  S
2024-11-06 11:21:18.671 29632-29632 chromium                [APP_NAME]                   E  [ERROR:aw_browser_terminator.cc(165)] Renderer process (29786) crash detected (code -1).

Could just be a side effect of the activity closing.

jdevuono54 commented 2 weeks ago

Thank you for your response !

I’ve added some extra logging to track the process more closely, especially around the getPicture call. I’m sharing the exported log file as an attachment so you can see the full trace of what’s happening from that point onward. It appears that the activity might indeed be closing, as you mentioned, potentially due to memory constraints.

Xiaomi-M2006C3LG-Android-10_2024-11-07_152402.txt

Let me know if there’s anything specific you’d like me to test or if there’s further information needed.

breautek commented 2 weeks ago

I'm pretty confident the "crash" is a red herring. It might be triggering the crash callback from the OS killing the activity, even though that's an expected behaviour when working with intents.

While using an intent it's not guaranteed for the app to stop but the OS reserves the right to kill it if it deems it necessary. If you enable the developer options on Android, you can enable the Don't Keep Activities option which will skip whatever logic Android has and always kill the activity when the OS switches to another activity. In android, activity basically refers to an application.

I glanced through the logs and I see:

{
      "header": {
        "logLevel": "DEBUG",
        "pid": 17356,
        "tid": 17356,
        "applicationId": "com.xxx.xxx",
        "processName": "com.xxx.xxx",
        "tag": "CordovaActivity",
        "timestamp": {
          "seconds": 1730989421,
          "nanos": 918000000
        }
      },
      "message": "Stopped the activity."
    },

Note the timestamp: 1730989421

Few seconds later:

{
      "header": {
        "logLevel": "ERROR",
        "pid": 17356,
        "tid": 17356,
        "applicationId": "com.xxx.xxx",
        "processName": "com.xxx.xxx",
        "tag": "WebviewCrashesHandler",
        "timestamp": {
          "seconds": 1730989427,
          "nanos": 360000000
        }
      },
      "message": "La Webview a été tuée par le système"
    },

We see this, but this is to be expected since the activity is stopped and/or stopping.

Fast forward a bit:

{
      "header": {
        "logLevel": "DEBUG",
        "pid": 17356,
        "tid": 17530,
        "applicationId": "com.xxx.xxx",
        "processName": "com.xxx.xxx",
        "tag": "SERVER",
        "timestamp": {
          "seconds": 1730989427,
          "nanos": 477000000
        }
      },
      "message": "Handling local request: https://kwap/index.html#/home"
    },

here the activity has restarted, since the webview is requesting presumably your home/content src page.

It's a bit hard to visualise what the app is doing from the logcat logs but I suspect that after the picture is taken and accepted, the app does come back to the Cordova webview view, just that perhaps your state has been reset? If so then that's the activity being killed and recreated when the camera's activity is done, and the resume event should have the camera result stored in the resume event.

window.document.addEventListener('resume', (e) => {
    console.log(e.pendingResult);
});

Again this flow can be tested when using the "Don't Keep Activities" developer option in the Android developer settings