javascripttizentizen-web-appsamsung-gear

"Permission denied" Tizen web app error accessing the heart rate monitor on a Samsung Gear S3 frontier


I'm trying to create a web app in tizen for my Samsung Gear S3 frontier. But, I'm getting a "Permission denied" security error.

I have:

<tizen:privilege name="http://developer.samsung.com/privilege/healthinfo"/>

and

<tizen:privilege name="http://tizen.org/privilege/healthinfo"/>

enabled in my config.xml.

I can get heart rate readings if I enable sensors permissions for the app in the settings, but it resets every time I compile and upload a newer version, which is rather tedious.

This is my JS code, sort-of following Retrieving Data from GEAR S3 Heart Rate Monitor (HRM) to Mobile or Server:

window.onload = function () {
    // add eventListener for tizenhwkey
    document.addEventListener('tizenhwkey', function(e) {
        if(e.keyName === "back") {
            try {
                tizen.application.getCurrentApplication().exit();
            } catch (ignore) {
            }
        }
    });

    // Sample code
    var textbox = document.querySelector('.contents');
    var box = document.querySelector('#textbox');

    textbox.addEventListener("click", function(){
        console.log('have box');

        if (fetch === undefined) {
            box.innerHTML = 'No such thing as fetch';
        } else {
            box.innerHTML = "We have fetch";            
        }
    });

    var sensors = tizen.sensorservice.getAvailableSensors();
    console.log('Available sensors: ' + sensors.toString());

    var heartRateData=0;

    function onsuccessCB(hrmInfo) {

        box.innerHTML = 'Heart rate: ' + hrmInfo.heartRate;
        heartRateData = hrmInfo.heartRate;
        // holding 15 seconds as HRM sensor needs some time 
    }

    function onerrorCB(error) {
        tizen.humanactivitymonitor.stop('HRM');
        console.log('Error occurred: ' + error.message);
    }

    function onchangedCB(hrmInfo) {
        //alert("onChanged...");
        tizen.humanactivitymonitor.getHumanActivityData('HRM', onsuccessCB, onerrorCB);

    }

    tizen.humanactivitymonitor.start('HRM', onchangedCB);
};

I would expect the config.xml settings to take care of the permissions, but evidently it doesn't. The watch is running Tizen 4.0.0.2 and it is sporting a "HRM_RAW" sensor, which I am unable to access as well without manually setting the permission.

How do I solve this problem?


Solution

  • I think I've found the answer myself, after some more creative web searching. It is done using tizen.ppm.requestPermission() (following https://developer.tizen.org/forums/web-application-development/security-exception-while-accessing-hrm

    This results in the expected behaviour. The app asks at installation through the wearable user interface whether the permission should be granted, and if this decision should be the default.

    However, I did some refactoring as you often need several permissions in your app, and callback hell is waiting just around the corner. So I wrote a Promise wrapper around the tizen call:

    function requestPermit(uri) {
      return new Promise(function(resolve, reject) {
        tizen.ppm.requestPermission(uri,
          function(success) => { resolve(success); },
          function(error) => { reject(error); });
      });
    }
    

    which allows me to

    function main() {
      return permitRequester('http://tizen.org/privilege/healthinfo')
        .then(function() { return permitRequester('http://developer.samsung.com/privilege/healthinfo'); })
        .then(function() { return permitRequester('http://developer.samsung.com/privilege/medicalinfo'); })
        .then(function() { return displayHeartRate(); })
        .catch(function(err) { return console.log(err); });
    }
    
    window.onload = main();
    

    Hope this is of help to anyone. I created a ES2016 npm/webpack project out of it if you need more info, at https://github.com/reinvantveer/Axyll