Uploaded image for project: 'Apache Cordova'
  1. Apache Cordova
  2. CB-10554

Media Capture: Null reference in low memory conditions

Details

    • Important

    Description

      I have been testing my app in low memory conditions by setting the android developer setting of "Don't keep Activities" which simulates low memory conditions. Every time I use the capture plugin for video when returning from the capture activity the app crashes. It appears that the state is not saved and on resume there are now null references such as the callbackContext and results array. It is fixed by using the onRestoreStateForActivityResult and onSaveInstanceState methods.

      Related Exception

      7 14:30:31.181 23432-24842/com.ionicframework.alto442183 E/AndroidRuntime: FATAL EXCEPTION: pool-3-thread-2
      Process: com.ionicframework.alto442183, PID: 23432
      java.lang.NullPointerException: Attempt to invoke virtual method 'void org.apache.cordova.CallbackContext.sendPluginResult(org.apache.cordova.PluginResult)' on a null object reference
      at org.apache.cordova.mediacapture.Capture$3.run(Capture.java:396)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
      at java.lang.Thread.run(Thread.java:818)

      Attachments

        Activity

          githubbot ASF GitHub Bot added a comment -

          Github user asfgit closed the pull request at:

          https://github.com/apache/cordova-plugin-media-capture/pull/60

          githubbot ASF GitHub Bot added a comment - Github user asfgit closed the pull request at: https://github.com/apache/cordova-plugin-media-capture/pull/60
          githubbot ASF GitHub Bot added a comment -

          Github user asfgit closed the pull request at:

          https://github.com/apache/cordova-plugin-media-capture/pull/51

          githubbot ASF GitHub Bot added a comment - Github user asfgit closed the pull request at: https://github.com/apache/cordova-plugin-media-capture/pull/51

          Commit b2e29fc88c548d5aadb7c49784e3498ae7d7213c in cordova-plugin-media-capture's branch refs/heads/master from Richard Knoll
          [ https://git-wip-us.apache.org/repos/asf?p=cordova-plugin-media-capture.git;h=b2e29fc ]

          CB-10554: Implementing plugin save/restore API for Android

          Adds two document events that can be subscribed to on
          Android to receive the results of callbacks that were
          pending when the webview was destroyed

          This closes #51, closes #60

          jira-bot ASF subversion and git services added a comment - Commit b2e29fc88c548d5aadb7c49784e3498ae7d7213c in cordova-plugin-media-capture's branch refs/heads/master from Richard Knoll [ https://git-wip-us.apache.org/repos/asf?p=cordova-plugin-media-capture.git;h=b2e29fc ] CB-10554 : Implementing plugin save/restore API for Android Adds two document events that can be subscribed to on Android to receive the results of callbacks that were pending when the webview was destroyed This closes #51, closes #60
          githubbot ASF GitHub Bot added a comment -

          Github user nikhilkh commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/60#issuecomment-217523808

          LGTM - Consider exposing these events on the capture object instead of `document`

          githubbot ASF GitHub Bot added a comment - Github user nikhilkh commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/60#issuecomment-217523808 LGTM - Consider exposing these events on the capture object instead of `document`
          githubbot ASF GitHub Bot added a comment -

          Github user riknoll commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/60#issuecomment-215216238

          @adamduren @nikhilkh @infil00p I'd appreciate some feedback.

          githubbot ASF GitHub Bot added a comment - Github user riknoll commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/60#issuecomment-215216238 @adamduren @nikhilkh @infil00p I'd appreciate some feedback.
          githubbot ASF GitHub Bot added a comment -

          GitHub user riknoll opened a pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/60

          CB-10554: Implementing plugin save/restore API for Android

          The purpose of this PR is to handle the case where the Webview gets destroyed in the background while a capture activity is in the foreground. #51 was invalidated by some updates that were recently made to the plugin to handle overlapping permission and activity requests.

          Also worth noting is that I did something different than the usual resume event API for getting pending plugin callback results. Instead of returning the native result to the javascript directly, this plugin needs to first wrap the results returned by the native code in a `MediaFile` object for those results to be useful. For that reason, I altered the plugin to expose two document events on Android that the user can subscribe to rather than the cordova-android generated resume event. These events directly return the wrapped result rather than the raw native one. It ends up looking like this:

          ```javascript
          function onDeviceReady() {
          // pendingcaptureresult is fired if the capture call is successful
          document.addEventListener('pendingcaptureresult', function(mediaFiles)

          { // Do something with result }

          );

          // pendingcaptureerror is fired if the capture call is unsuccessful
          document.addEventListener('pendingcaptureerror', function(error)

          { // Handle error case }

          );
          }
          document.addEventListener('deviceready', onDeviceReady);
          ```

          Whereas using the resume event directly would require us to expose a helper API on Android:

          ```javascript
          function onDeviceReady() {
          document.addEventListener(resume, function(event) {
          if(event.pendingResult && event.pendingResult.pluginServiceName === "Capture") {
          if(event.pendingResult.pluginStatus === "OK")

          { var rawMediaFiles = event.pendingResult.result; // Here, we would need to expose some weird helper function to deal with the native result var mediaFiles = capture.wrapMediaFiles(mediaFiles); // Do something with result }

          else

          { var error = event.pendingResult.result; // Handle the error case }

          }
          });
          }
          document.addEventListener('deviceready', onDeviceReady);
          ```

          I think this makes the API a bit cleaner and also opens the way for plugins that do much more heavy javascript work before returning callback results. This hasn't really come up before because the other two core plugins that had this issue (camera and contacts) could just pass the native result directly to the javascript.

          I'd appreciate some feedback on this API and if it seems okay I might update the Android plugin guide with an example so that other plugins can use this pattern.

          You can merge this pull request into a Git repository by running:

          $ git pull https://github.com/MSOpenTech/cordova-plugin-media-capture CB-10554

          Alternatively you can review and apply these changes as the patch at:

          https://github.com/apache/cordova-plugin-media-capture/pull/60.patch

          To close this pull request, make a commit to your master/trunk branch
          with (at least) the following in the commit message:

          This closes #60



          githubbot ASF GitHub Bot added a comment - GitHub user riknoll opened a pull request: https://github.com/apache/cordova-plugin-media-capture/pull/60 CB-10554 : Implementing plugin save/restore API for Android The purpose of this PR is to handle the case where the Webview gets destroyed in the background while a capture activity is in the foreground. #51 was invalidated by some updates that were recently made to the plugin to handle overlapping permission and activity requests. Also worth noting is that I did something different than the usual resume event API for getting pending plugin callback results. Instead of returning the native result to the javascript directly, this plugin needs to first wrap the results returned by the native code in a `MediaFile` object for those results to be useful. For that reason, I altered the plugin to expose two document events on Android that the user can subscribe to rather than the cordova-android generated resume event. These events directly return the wrapped result rather than the raw native one. It ends up looking like this: ```javascript function onDeviceReady() { // pendingcaptureresult is fired if the capture call is successful document.addEventListener('pendingcaptureresult', function(mediaFiles) { // Do something with result } ); // pendingcaptureerror is fired if the capture call is unsuccessful document.addEventListener('pendingcaptureerror', function(error) { // Handle error case } ); } document.addEventListener('deviceready', onDeviceReady); ``` Whereas using the resume event directly would require us to expose a helper API on Android: ```javascript function onDeviceReady() { document.addEventListener(resume, function(event) { if(event.pendingResult && event.pendingResult.pluginServiceName === "Capture") { if(event.pendingResult.pluginStatus === "OK") { var rawMediaFiles = event.pendingResult.result; // Here, we would need to expose some weird helper function to deal with the native result var mediaFiles = capture.wrapMediaFiles(mediaFiles); // Do something with result } else { var error = event.pendingResult.result; // Handle the error case } } }); } document.addEventListener('deviceready', onDeviceReady); ``` I think this makes the API a bit cleaner and also opens the way for plugins that do much more heavy javascript work before returning callback results. This hasn't really come up before because the other two core plugins that had this issue (camera and contacts) could just pass the native result directly to the javascript. I'd appreciate some feedback on this API and if it seems okay I might update the Android plugin guide with an example so that other plugins can use this pattern. You can merge this pull request into a Git repository by running: $ git pull https://github.com/MSOpenTech/cordova-plugin-media-capture CB-10554 Alternatively you can review and apply these changes as the patch at: https://github.com/apache/cordova-plugin-media-capture/pull/60.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #60
          githubbot ASF GitHub Bot added a comment -

          Github user riknoll commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-197549101

          @adamduren I've tested this and the save/restore stuff appears to work great! There is an issue, however, with the results that are returned in the resume event. They need to be wrapped in `MediaFile` objects before use. This was also an issue in the Contacts plugin where they needed to be wrapped in a `Contact` object and the solution was to just provide an example of how to do that in the README (see [here](https://github.com/apache/cordova-plugin-contacts#android-quirks)). In this plugin it is a little bit trickier because we need to decide how to expose the `MediaFile` object creation. Currently, it just happens in the `exec` callback [here](https://github.com/apache/cordova-plugin-media-capture/blob/0867898701c9f547dddd8448bfc0f46d6ae14008/www/capture.js#L34) without a public API. Thoughts? Maybe we should add a `MediaFile` constructor that encapsulates that `exec` callback? That at least would not be a breaking change.

          githubbot ASF GitHub Bot added a comment - Github user riknoll commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-197549101 @adamduren I've tested this and the save/restore stuff appears to work great! There is an issue, however, with the results that are returned in the resume event. They need to be wrapped in `MediaFile` objects before use. This was also an issue in the Contacts plugin where they needed to be wrapped in a `Contact` object and the solution was to just provide an example of how to do that in the README (see [here] ( https://github.com/apache/cordova-plugin-contacts#android-quirks )). In this plugin it is a little bit trickier because we need to decide how to expose the `MediaFile` object creation. Currently, it just happens in the `exec` callback [here] ( https://github.com/apache/cordova-plugin-media-capture/blob/0867898701c9f547dddd8448bfc0f46d6ae14008/www/capture.js#L34 ) without a public API. Thoughts? Maybe we should add a `MediaFile` constructor that encapsulates that `exec` callback? That at least would not be a breaking change.
          githubbot ASF GitHub Bot added a comment -

          Github user riknoll commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-197525596

          Testing this now

          githubbot ASF GitHub Bot added a comment - Github user riknoll commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-197525596 Testing this now
          githubbot ASF GitHub Bot added a comment -

          Github user riknoll commented on a diff in the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#discussion_r56393172

          — Diff: README.md —
          @@ -175,6 +175,14 @@ code.

              1. Android Quirks
          • The `duration` parameter is not supported. Recording lengths can't be limited programmatically.
            +- Android uses intents to launch the camera activity on the device to capture
            +images, and on phones with low memory, the Cordova activity may be killed. In this
            +scenario, the result from the plugin call will be delivered via the resume event.
            +See [the Android Lifecycle guide][android_lifecycle]
              • End diff –

          This is a reference style markdown link and I think you missed copying over the actual link definition at the bottom of the README. Should point to http://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html#lifecycle-guide

          githubbot ASF GitHub Bot added a comment - Github user riknoll commented on a diff in the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#discussion_r56393172 — Diff: README.md — @@ -175,6 +175,14 @@ code. Android Quirks The `duration` parameter is not supported. Recording lengths can't be limited programmatically. +- Android uses intents to launch the camera activity on the device to capture +images, and on phones with low memory, the Cordova activity may be killed. In this +scenario, the result from the plugin call will be delivered via the resume event. +See [the Android Lifecycle guide] [android_lifecycle] End diff – This is a reference style markdown link and I think you missed copying over the actual link definition at the bottom of the README. Should point to http://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html#lifecycle-guide
          githubbot ASF GitHub Bot added a comment -

          Github user adamduren commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-193344477

          @riknoll Sorry for the delay. I pulled the note from the cordova camera plugin. They should be the same.

          githubbot ASF GitHub Bot added a comment - Github user adamduren commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-193344477 @riknoll Sorry for the delay. I pulled the note from the cordova camera plugin. They should be the same.
          githubbot ASF GitHub Bot added a comment -

          Github user riknoll commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-192078564

          @adamduren any word on the README update? It just needs to be a short blurb pointing to the [Android lifecycle guide](http://cordova.apache.org/docs/en/latest/guide/platforms/android/lifecycle.html) really. Looking at the javascript code for this plugin, I don't really think there is any need for anything else. We just need to list the quirk and point to the documentation.

          githubbot ASF GitHub Bot added a comment - Github user riknoll commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-192078564 @adamduren any word on the README update? It just needs to be a short blurb pointing to the [Android lifecycle guide] ( http://cordova.apache.org/docs/en/latest/guide/platforms/android/lifecycle.html ) really. Looking at the javascript code for this plugin, I don't really think there is any need for anything else. We just need to list the quirk and point to the documentation.
          githubbot ASF GitHub Bot added a comment -

          Github user riknoll commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-189025565

          Thanks for doing this! LGTM, I just need to test it. Can you add a note to the README about this quirk? Something like https://github.com/apache/cordova-plugin-camera#android-quirks

          githubbot ASF GitHub Bot added a comment - Github user riknoll commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-189025565 Thanks for doing this! LGTM, I just need to test it. Can you add a note to the README about this quirk? Something like https://github.com/apache/cordova-plugin-camera#android-quirks
          githubbot ASF GitHub Bot added a comment -

          Github user nikhilkh commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-189000686

          @riknoll to review

          githubbot ASF GitHub Bot added a comment - Github user nikhilkh commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-189000686 @riknoll to review
          githubbot ASF GitHub Bot added a comment -

          Github user adamduren commented on the pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-188962549

          @stevengill What additional steps do I need to take to get this resolved?

          githubbot ASF GitHub Bot added a comment - Github user adamduren commented on the pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51#issuecomment-188962549 @stevengill What additional steps do I need to take to get this resolved?
          githubbot ASF GitHub Bot added a comment -

          GitHub user adamduren opened a pull request:

          https://github.com/apache/cordova-plugin-media-capture/pull/51

          CB-10554 Fix null reference in low memory conditions

          [Related Jira](https://issues.apache.org/jira/browse/CB-10554)
          State is lost when the activity is not kept as a result of low memory conditions. This causes a NullPointerException in multiple places. Save the state and restore it on resume.

          You can merge this pull request into a Git repository by running:

          $ git pull https://github.com/adamduren/cordova-plugin-media-capture patch-1

          Alternatively you can review and apply these changes as the patch at:

          https://github.com/apache/cordova-plugin-media-capture/pull/51.patch

          To close this pull request, make a commit to your master/trunk branch
          with (at least) the following in the commit message:

          This closes #51


          commit 7bbec803d8aa5585a7ce2a651c34c2d5db55ba09
          Author: Adam Duren <adamduren@gmail.com>
          Date: 2016-02-07T19:20:35Z

          Fix null reference in low memory conditions

          State is lost when the activity is not kept as a result of low memory conditions. This causes a NullPointerException in multiple places. Save the state and restore it on resume.


          githubbot ASF GitHub Bot added a comment - GitHub user adamduren opened a pull request: https://github.com/apache/cordova-plugin-media-capture/pull/51 CB-10554 Fix null reference in low memory conditions [Related Jira] ( https://issues.apache.org/jira/browse/CB-10554 ) State is lost when the activity is not kept as a result of low memory conditions. This causes a NullPointerException in multiple places. Save the state and restore it on resume. You can merge this pull request into a Git repository by running: $ git pull https://github.com/adamduren/cordova-plugin-media-capture patch-1 Alternatively you can review and apply these changes as the patch at: https://github.com/apache/cordova-plugin-media-capture/pull/51.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #51 commit 7bbec803d8aa5585a7ce2a651c34c2d5db55ba09 Author: Adam Duren <adamduren@gmail.com> Date: 2016-02-07T19:20:35Z Fix null reference in low memory conditions State is lost when the activity is not kept as a result of low memory conditions. This causes a NullPointerException in multiple places. Save the state and restore it on resume.

          People

            riknoll Richard B Knoll
            adamduren Adam Duren
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: