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

Share target: sharing to cordova app makes the app open but crashes afterwards

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Not A Problem
    • Affects Version/s: 4.4.2
    • Fix Version/s: None
    • Component/s: cordova-windows
    • Labels:
    • Environment:

      Windows 10, cordova cli 6.1.1, affects cordova platform 4.4.2, also current 4.5.0 dev branch.

      Description

      Steps to reproduce:
      ========================

      cordova create shareTargetTest
      cd shareTargetTest
      cordova platform add https://github.com/apache/cordova-windows
      

      In manifest, add Share Target of type URI, leading to the following XML:

            <Extensions>
              <uap:Extension Category="windows.shareTarget">
                <uap:ShareTarget>
                  <uap:DataFormat>URI</uap:DataFormat>
                </uap:ShareTarget>
              </uap:Extension>
            </Extensions>
      

      Run Windows 10 emulator (also crashed on HP Elite X3 device)

      Open Edge browser on any page, and share page to HelloCordova app.

      The HelloCordova app opens, and after some seconds, the emulator crashes (WWAHost.exe fails with code = -1: don't know how to get more details unfortunatly)

      --------------------------------------------------------------------------

      Expected result:
      ========================

      I don't know if this has ever been done by anyone on a Cordova app, but I want to share a Edge link to my application. For Android/iOS, this means that the app should open, or resume itself, and call some JS callback.

      I tried to follow these Windows8 tutorials that still look relevant for Windows10 app, with no success.
      https://msdn.microsoft.com/en-us/library/windows/apps/hh758301.aspx

      It seems the "activated" callback never fires (weither it's declared in my app, or in cordova.js, at least I don't see anything in the console logs I've put everywhere).

      Can you tell me if I do anything wrong to achieve this usecase? thanks

        Issue Links

          Activity

          Hide
          sebastienlorber Sebastien Lorber added a comment -

          Hi,

          I'm sorry to ask again but can someone give me any early feedback on this issue? Even if it's a first unqualified impression I'll take it!

          I'm participating a Microsoft/HP hackaton for the launch of HP Elite X3 and have to ship my app in 2 days to qualify. This feature is very important for us and I can't make it work. I'm supposed to get support from Microsoft but I'm not sure they expected us to have a Cordova app so couldn't get much help.
          I know it's not really cool to ask people doing OS to fix my own problems when I can do it myself, but I don't have any other solution here

          I'm following Microsoft / Cordova docs, using latest code I find and master branches, also trying to read/modify source code. Any hint so that I can fix the problem myself (and contribute back) would be helpful because I'm not a Windows Phone expert and won't have time to become one in 2 days :'(

          My current test code is based on the Cordova template project, on which I only modified the index.js file:

          var app = {
              initialize: function() {
                  this.bindEvents();
              },
              bindEvents: function() {
                  document.addEventListener('deviceready', this.onDeviceReady, false);
              },
              onDeviceReady: function() {
                  app.receivedEvent('deviceready');
                  setupShareTarget();
              },
              receivedEvent: function(id) {
                  var parentElement = document.getElementById(id);
                  var listeningElement = parentElement.querySelector('.listening');
                  var receivedElement = parentElement.querySelector('.received');
          
                  listeningElement.setAttribute('style', 'display:none;');
                  receivedElement.setAttribute('style', 'display:block;');
                  console.log('Received Event: ' + id);
              }
          };
          
          app.initialize();
          
          
          
          function setupShareTarget() {
              console.debug("setupShareTarget");
              
              var shareOperation = null;
              function shareReady(args) {
                  console.debug("shareReady");
                  if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.uri)) {
                      console.debug("shareOperation");
                      shareOperation.data.getUriAsync().done(function (uri) {
                          console.debug("getUriAsync");
                      });
                  }
              }
          
              WinJS.Application.onactivated = function (args) {
                  console.debug("onactivated");
                  if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
                      console.debug("launch");
                      args.setPromise(WinJS.UI.processAll());
                  }
                  else if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
                      console.debug("share target");
                      args.setPromise(WinJS.UI.processAll());
                      shareOperation = args.detail.shareOperation;
                      WinJS.Application.addEventListener("shareready", shareReady, false);
                      WinJS.Application.queueEvent({ type: "shareready" });
                  }
                  else {
                      console.debug("else");
                  }
              };
          }
          

          https://gist.github.com/slorber/ea1e77f78192eb2832f4ce9fdd5eb7bc

          onactivated is triggered when app start and is reopened, but does not trigger when we share a browser link (+ emulator crashing)

          Any idea of anything I could be doing wrong?

          Thanks

          Show
          sebastienlorber Sebastien Lorber added a comment - Hi, I'm sorry to ask again but can someone give me any early feedback on this issue? Even if it's a first unqualified impression I'll take it! I'm participating a Microsoft/HP hackaton for the launch of HP Elite X3 and have to ship my app in 2 days to qualify. This feature is very important for us and I can't make it work. I'm supposed to get support from Microsoft but I'm not sure they expected us to have a Cordova app so couldn't get much help. I know it's not really cool to ask people doing OS to fix my own problems when I can do it myself, but I don't have any other solution here I'm following Microsoft / Cordova docs, using latest code I find and master branches, also trying to read/modify source code. Any hint so that I can fix the problem myself (and contribute back) would be helpful because I'm not a Windows Phone expert and won't have time to become one in 2 days :'( My current test code is based on the Cordova template project, on which I only modified the index.js file: var app = { initialize: function() { this .bindEvents(); }, bindEvents: function() { document.addEventListener('deviceready', this .onDeviceReady, false ); }, onDeviceReady: function() { app.receivedEvent('deviceready'); setupShareTarget(); }, receivedEvent: function(id) { var parentElement = document.getElementById(id); var listeningElement = parentElement.querySelector('.listening'); var receivedElement = parentElement.querySelector('.received'); listeningElement.setAttribute('style', 'display:none;'); receivedElement.setAttribute('style', 'display:block;'); console.log('Received Event: ' + id); } }; app.initialize(); function setupShareTarget() { console.debug( "setupShareTarget" ); var shareOperation = null ; function shareReady(args) { console.debug( "shareReady" ); if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.uri)) { console.debug( "shareOperation" ); shareOperation.data.getUriAsync().done(function (uri) { console.debug( "getUriAsync" ); }); } } WinJS.Application.onactivated = function (args) { console.debug( "onactivated" ); if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) { console.debug( "launch" ); args.setPromise(WinJS.UI.processAll()); } else if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) { console.debug( "share target" ); args.setPromise(WinJS.UI.processAll()); shareOperation = args.detail.shareOperation; WinJS.Application.addEventListener( "shareready" , shareReady, false ); WinJS.Application.queueEvent({ type: "shareready" }); } else { console.debug( " else " ); } }; } https://gist.github.com/slorber/ea1e77f78192eb2832f4ce9fdd5eb7bc onactivated is triggered when app start and is reopened, but does not trigger when we share a browser link (+ emulator crashing) Any idea of anything I could be doing wrong? Thanks
          Hide
          sebastienlorber Sebastien Lorber added a comment -

          Sergey Shakhnazarov it seems you are the main maintainer of Windows platform. Any hot feedback on this would be really helpful!

          Show
          sebastienlorber Sebastien Lorber added a comment - Sergey Shakhnazarov it seems you are the main maintainer of Windows platform. Any hot feedback on this would be really helpful!
          Hide
          daserge Sergey Shakhnazarov added a comment -

          Sebastien Lorber, args.setPromise(WinJS.UI.processAll()); - are you including WinJS/ui.js in the HTML?
          It would be helpful if you could share a project to reproduce without platforms and plugins folders, archived.

          Show
          daserge Sergey Shakhnazarov added a comment - Sebastien Lorber , args.setPromise(WinJS.UI.processAll()); - are you including WinJS/ui.js in the HTML? It would be helpful if you could share a project to reproduce without platforms and plugins folders, archived.
          Hide
          sebastienlorber Sebastien Lorber added a comment -

          Sergey Shakhnazarov thanks for your response.

          I'll make a project as soon as I can, but I'm not sure to understand why you ask for an archived project.
          The tests I've done are based on the following, which is basically the empty cordova project:

          cordova create shareTargetTest
          cd shareTargetTest
          cordova platform add https://github.com/apache/cordova-windows
          

          If you type the 3 following commands, you will have exactly the same setting as me (using cordova cli 6.3.1): it's the hello world cordova, empty project with most simple html/js code at all. From there, replace content of the generated file `www/js/index.js` with the code I pasted above (it just adds and call the method setupShareTarget() after cordova is initialized)

          About

          args.setPromise(WinJS.UI.processAll());

          I'm not using any WinJS framework but I can tell by using remove webview debugging that WinJS.UI.processAll() function is not undefined, so I guess it has been loaded automatically by default.

          Also note that I'm following this tutorial, which is initially for Windows8 (and the link pointing to Windows 10 doc seems broken): https://msdn.microsoft.com/fr-fr/library/windows/apps/hh758301.aspx

          What I'm trying to do: write the most simple code I can, on an empty Cordova project, that succeed at sharing an Edge link to my App. So far, without modifying initial cordova template (ie no WinJS usage at all) with most recent windows platform, just adding a share target of type URI and sharing from Edge to my app makes the emulator crash (also tested by checking checkbox saying my app receives any kind of data, doesn't work either)

          Show
          sebastienlorber Sebastien Lorber added a comment - Sergey Shakhnazarov thanks for your response. I'll make a project as soon as I can, but I'm not sure to understand why you ask for an archived project. The tests I've done are based on the following, which is basically the empty cordova project: cordova create shareTargetTest cd shareTargetTest cordova platform add https: //github.com/apache/cordova-windows If you type the 3 following commands, you will have exactly the same setting as me (using cordova cli 6.3.1): it's the hello world cordova, empty project with most simple html/js code at all. From there, replace content of the generated file `www/js/index.js` with the code I pasted above (it just adds and call the method setupShareTarget() after cordova is initialized) About args.setPromise(WinJS.UI.processAll()); I'm not using any WinJS framework but I can tell by using remove webview debugging that WinJS.UI.processAll() function is not undefined, so I guess it has been loaded automatically by default. Also note that I'm following this tutorial, which is initially for Windows8 (and the link pointing to Windows 10 doc seems broken): https://msdn.microsoft.com/fr-fr/library/windows/apps/hh758301.aspx What I'm trying to do: write the most simple code I can, on an empty Cordova project, that succeed at sharing an Edge link to my App. So far, without modifying initial cordova template (ie no WinJS usage at all) with most recent windows platform, just adding a share target of type URI and sharing from Edge to my app makes the emulator crash (also tested by checking checkbox saying my app receives any kind of data, doesn't work either)
          Hide
          sebastienlorber Sebastien Lorber added a comment -

          Sergey Shakhnazarov I have made some progess so far:

          1) I've finally understood that when we share a link to our app, it actually does not "resume" our app,but rather open a new view on top of the source app. This is not so obvious on mobile, but for desktop we can clearly see it's a right sharing flyout that kicks in. As far as I understand, it's possible to specify a different html file than the default index.html one through manifest, but it also works if the share view opens regular index.html

          2) As it's not really the deployed app that is launched during the share operation, the console logs are nt displayed on Visual Studio by default. I have to use a special setting "Do not launch, but debug my code when it starts" so that the debugger can attach to my app share view (see https://dzone.com/articles/debugging-share-target)

          3) Maybe this is a bug, but this was confusing to me: it seems impossible to catch the WinJS activated event after the deviceready cordova event has fired. Is this expected? I have to register the activationHandler before deviceready, which seems counterintuitive regarding cordova documentation.

          4) The emulator crashes, but I noted it also crashes when I try to choose to share to another app when using the emulator. Doing the share operation on UWP on my local desktop computer does not crash, so I suspect it's an emulator issue. I'll have to do some tests on the device to confirm that (don't own any :s), but surprisingly I got issue on HP Elite X3 as far as I remember.

          Here's a github project with sample code that seems to work (except emulator crashes): https://github.com/slorber/cordova-windows-share-target

          Show
          sebastienlorber Sebastien Lorber added a comment - Sergey Shakhnazarov I have made some progess so far: 1) I've finally understood that when we share a link to our app, it actually does not "resume" our app,but rather open a new view on top of the source app. This is not so obvious on mobile, but for desktop we can clearly see it's a right sharing flyout that kicks in. As far as I understand, it's possible to specify a different html file than the default index.html one through manifest, but it also works if the share view opens regular index.html 2) As it's not really the deployed app that is launched during the share operation, the console logs are nt displayed on Visual Studio by default. I have to use a special setting "Do not launch, but debug my code when it starts" so that the debugger can attach to my app share view (see https://dzone.com/articles/debugging-share-target ) 3) Maybe this is a bug, but this was confusing to me: it seems impossible to catch the WinJS activated event after the deviceready cordova event has fired. Is this expected? I have to register the activationHandler before deviceready, which seems counterintuitive regarding cordova documentation. 4) The emulator crashes, but I noted it also crashes when I try to choose to share to another app when using the emulator. Doing the share operation on UWP on my local desktop computer does not crash, so I suspect it's an emulator issue. I'll have to do some tests on the device to confirm that (don't own any :s), but surprisingly I got issue on HP Elite X3 as far as I remember. Here's a github project with sample code that seems to work (except emulator crashes): https://github.com/slorber/cordova-windows-share-target
          Hide
          sebastienlorber Sebastien Lorber added a comment -

          Sergey Shakhnazarov I have been able to make my usecase work.

          I've documented everything here: https://github.com/slorber/cordova-windows-share-target

          I suspect maybe the emulator crashed because of not calling shareOperation.reportCompleted() (not sure)

          I was able to launch my main app immediately from the share view using a protocol activation

          I created a custom html file for receiving the share view.
          Note I have to include myself base.js of WinJS to make it work: https://github.com/slorber/cordova-windows-share-target/blob/master/www/windowsShareTarget.html
          Quite related to your recent PR I guess: https://github.com/apache/cordova-windows/pull/191

          Still, it seems important to register WinJS activationHandler before deviceready which seems a bit weird.

          Maybe this issue can be closed as I've found a solution to my problems.
          However I think it would be nice to document a bit how Cordova apps can make use of WinJS.

          Hope my github repo will be helpful for futur developers.

          Show
          sebastienlorber Sebastien Lorber added a comment - Sergey Shakhnazarov I have been able to make my usecase work. I've documented everything here: https://github.com/slorber/cordova-windows-share-target I suspect maybe the emulator crashed because of not calling shareOperation.reportCompleted() (not sure) I was able to launch my main app immediately from the share view using a protocol activation I created a custom html file for receiving the share view. Note I have to include myself base.js of WinJS to make it work: https://github.com/slorber/cordova-windows-share-target/blob/master/www/windowsShareTarget.html Quite related to your recent PR I guess: https://github.com/apache/cordova-windows/pull/191 Still, it seems important to register WinJS activationHandler before deviceready which seems a bit weird. Maybe this issue can be closed as I've found a solution to my problems. However I think it would be nice to document a bit how Cordova apps can make use of WinJS. Hope my github repo will be helpful for futur developers.
          Hide
          githubbot ASF GitHub Bot added a comment -

          GitHub user daserge opened a pull request:

          https://github.com/apache/cordova-docs/pull/650

          CB-11924 Share target: sharing to cordova app makes the app open but …

          …crashes afterwards

          <!--
          Please make sure the checklist boxes are all checked before submitting the PR. The checklist
          is intended as a quick reference, for complete details please see our Contributor Guidelines:

          http://cordova.apache.org/contribute/contribute_guidelines.html

          Thanks!
          -->

              1. Platforms affected
                Windows
              1. What does this PR do?
                Documents the activated event can be fired before deviceready
              1. What testing has been done on this change?
              1. Checklist
          • [x] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database
          • [x] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
          • [ ] Added automated test coverage as appropriate for this change.

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

          $ git pull https://github.com/daserge/cordova-docs CB-11924

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

          https://github.com/apache/cordova-docs/pull/650.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 #650


          commit 91f56827fdadc65e96e188a4bbbff1d76ba7e835
          Author: daserge <v-seshak@microsoft.com>
          Date: 2016-10-17T13:53:01Z

          CB-11924 Share target: sharing to cordova app makes the app open but crashes afterwards

          Documents the activated event can be fired before deviceready


          Show
          githubbot ASF GitHub Bot added a comment - GitHub user daserge opened a pull request: https://github.com/apache/cordova-docs/pull/650 CB-11924 Share target: sharing to cordova app makes the app open but … …crashes afterwards <!-- Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines: http://cordova.apache.org/contribute/contribute_guidelines.html Thanks! --> Platforms affected Windows What does this PR do? Documents the activated event can be fired before deviceready What testing has been done on this change? Checklist [x] [Reported an issue] ( http://cordova.apache.org/contribute/issues.html ) in the JIRA database [x] Commit message follows the format: " CB-3232 : (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected. [ ] Added automated test coverage as appropriate for this change. You can merge this pull request into a Git repository by running: $ git pull https://github.com/daserge/cordova-docs CB-11924 Alternatively you can review and apply these changes as the patch at: https://github.com/apache/cordova-docs/pull/650.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 #650 commit 91f56827fdadc65e96e188a4bbbff1d76ba7e835 Author: daserge <v-seshak@microsoft.com> Date: 2016-10-17T13:53:01Z CB-11924 Share target: sharing to cordova app makes the app open but crashes afterwards Documents the activated event can be fired before deviceready
          Hide
          daserge Sergey Shakhnazarov added a comment -

          Sebastien Lorber, thanks for reporting!
          I've tested this and the following approach works for me:

          var app = {
          ...
              // Bind Event Listeners
              //
              // Bind any events that are required on startup. Common events are:
              // 'load', 'deviceready', 'offline', and 'online'.
              bindEvents: function() {
                  document.addEventListener('deviceready', this.onDeviceReady, false);
                  document.addEventListener('activated', this.onActivated, false);
              },
              onActivated: function (args) {
                  console.log('onActivated');
                  app.activated = true;
                  app.activatedArgs = args;
                  // Sometimes onActivated fires before deviceready, so plugins might not be ready
                  navigator && navigator.notification && navigator.notification.alert && navigator.notification.alert('onActivated: ' + JSON.stringify(args));
                  // ^ this happens on Windows Anniversary
              },
              // deviceready Event Handler
              //
              // The scope of 'this' is the event. In order to call the 'receivedEvent'
              // function, we must explicitly call 'app.receivedEvent(...);'
              onDeviceReady: function() {
                  app.receivedEvent('deviceready');
          
                  if (app.activated) {
                      // Sometimes onActivated fires before deviceready, so plugins might not be ready
                      navigator && navigator.notification && navigator.notification.alert && navigator.notification.alert('onDeviceReady, onActivated (from the past): ' + JSON.stringify(app.activatedArgs));
                  }
              },
          ...
          

          I.e. we are able to receive shared uri in activated event handler - it just might fire before deviceready so activation args should be stored in the app context - I've send a PR for the docs update.

          Show
          daserge Sergey Shakhnazarov added a comment - Sebastien Lorber , thanks for reporting! I've tested this and the following approach works for me: var app = { ... // Bind Event Listeners // // Bind any events that are required on startup. Common events are: // 'load', 'deviceready', 'offline', and 'online'. bindEvents: function() { document.addEventListener('deviceready', this .onDeviceReady, false ); document.addEventListener('activated', this .onActivated, false ); }, onActivated: function (args) { console.log('onActivated'); app.activated = true ; app.activatedArgs = args; // Sometimes onActivated fires before deviceready, so plugins might not be ready navigator && navigator.notification && navigator.notification.alert && navigator.notification.alert('onActivated: ' + JSON.stringify(args)); // ^ this happens on Windows Anniversary }, // deviceready Event Handler // // The scope of ' this ' is the event. In order to call the 'receivedEvent' // function, we must explicitly call 'app.receivedEvent(...);' onDeviceReady: function() { app.receivedEvent('deviceready'); if (app.activated) { // Sometimes onActivated fires before deviceready, so plugins might not be ready navigator && navigator.notification && navigator.notification.alert && navigator.notification.alert('onDeviceReady, onActivated (from the past): ' + JSON.stringify(app.activatedArgs)); } }, ... I.e. we are able to receive shared uri in activated event handler - it just might fire before deviceready so activation args should be stored in the app context - I've send a PR for the docs update.
          Hide
          sebastienlorber Sebastien Lorber added a comment -

          Yes this worked for me too. I store the share target uri in a temporary variable until deviceready is fired.

          About the crashes I'm not sure but I think it's related to the debugger and my app being very heavy. Building my app in production mode, without sourcemaps, seems to work fine in the end. Also, the share target page opens the main app with a protocol launch immediately so I have a quite specific setting, but it works fine.

          Show
          sebastienlorber Sebastien Lorber added a comment - Yes this worked for me too. I store the share target uri in a temporary variable until deviceready is fired. About the crashes I'm not sure but I think it's related to the debugger and my app being very heavy. Building my app in production mode, without sourcemaps, seems to work fine in the end. Also, the share target page opens the main app with a protocol launch immediately so I have a quite specific setting, but it works fine.
          Hide
          daserge Sergey Shakhnazarov added a comment -

          Sebastien Lorber, thanks for the update!

          Show
          daserge Sergey Shakhnazarov added a comment - Sebastien Lorber , thanks for the update!
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 5f50c7c065a91ecd07e9ee281e0de33c07482dd7 in cordova-docs's branch refs/heads/master from Sergey Shakhnazarov
          [ https://git-wip-us.apache.org/repos/asf?p=cordova-docs.git;h=5f50c7c ]

          CB-11924 Document the activated event might be fired before deviceready

          Show
          jira-bot ASF subversion and git services added a comment - Commit 5f50c7c065a91ecd07e9ee281e0de33c07482dd7 in cordova-docs's branch refs/heads/master from Sergey Shakhnazarov [ https://git-wip-us.apache.org/repos/asf?p=cordova-docs.git;h=5f50c7c ] CB-11924 Document the activated event might be fired before deviceready
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user asfgit closed the pull request at:

          https://github.com/apache/cordova-docs/pull/650

          Show
          githubbot ASF GitHub Bot added a comment - Github user asfgit closed the pull request at: https://github.com/apache/cordova-docs/pull/650

            People

            • Assignee:
              Unassigned
              Reporter:
              sebastienlorber Sebastien Lorber
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development