[FMRadio][Features]Async methods implementation
authorDominik Rekawek <d.rekawek@samsung.com>
Tue, 16 Dec 2014 14:11:11 +0000 (15:11 +0100)
committerDominik Rekawek <d.rekawek@samsung.com>
Tue, 30 Dec 2014 11:30:43 +0000 (12:30 +0100)
JS,Cpp: Start() Stop() seekUp seekDown()

Both: code required to mantain provided functions

Validation:
-Compile success
-Module visible on target device
-Functional validation performed by hardcoding callbacks invocations

Change-Id: I9a0d6b18b483dc66c713b3b5843cd6560d6d8fbe
Signed-off-by: Dominik Rekawek <d.rekawek@samsung.com>
src/radio/radio.gyp
src/radio/radio_api.js
src/radio/radio_extension.cc
src/radio/radio_extension.h
src/radio/radio_instance.cc
src/radio/radio_instance.h
src/radio/radio_manager.cc [new file with mode: 0755]
src/radio/radio_manager.h [new file with mode: 0755]
src/tizen-wrt.gyp

index d4abb6cac19275c50f2c4636af4ef8a1ca97e7c1..be730a7c7129da3e04d640f8af09fe01a67c29ea 100644 (file)
         'radio_api.js',
         'radio_extension.cc',
         'radio_extension.h',
+        'radio_manager.cc',
+        'radio_manager.h',
         'radio_instance.cc',
         'radio_instance.h'
       ],
+       'includes': [
+        '../common/pkg-config.gypi',
+        ],
       'conditions': [
         ['tizen == 1', {
           'variables': {
index 790f07160fab6b7de6f8363385dca88663ea4b10..fc7a083e0ea2997f55f09eb4a91ab732f080fdca 100644 (file)
 // Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 var validator_ = xwalk.utils.validator;
 var types_ = validator_.Types;
 var native_ = new xwalk.utils.NativeManager(extension);
 
+var _listeners_FMRadioInterrupted;
+var _listeners_AntennaChange;
+
 var RadioState = {
-        PLAYING : 'PLAYING',
-        SCANNING : 'SCANNING',
-        READY : 'READY'
+    PLAYING : 'PLAYING',
+    SCANNING : 'SCANNING',
+    READY : 'READY'
 };
 
 function FMRadioManager() {
-     Object.defineProperties(this, {
-            'frequency': { value: 'TEST', writable: false,enumerable: true },
-            'frequencyUpperBound': { value: 'TEST',writable: false,enumerable: true },
-            'frequencyLowerBound': { value: 'TEST',writable: false,enumerable: true },
-            'signalStrength': {  value: 'TEST',writable: false,enumerable: true },
-            'state': { value: 'TEST',writable: false,enumerable: true },
-            'isAntennaConnected': {  value: 'TEST',writable: false,enumerable: true },
-            'mute': {value: 'TEST', writable: false,enumerable: true }
-          });
+    Object.defineProperties(this, {
+        'frequency' : {
+            enumerable : true,
+            get : frequencyGetter,
+            set : function() {
+            }
+        },
+        'frequencyUpperBound' : {
+            enumerable : true,
+            get : frequencyUpperGetter,
+            set : function() {
+            }
+        },
+        'frequencyLowerBound' : {
+            enumerable : true,
+            get : frequencyLowerGetter,
+            set : function() {
+            }
+        },
+        'signalStrength' : {
+            value : 'TEST',
+            writable : false,
+            enumerable : true
+        },
+        'state' : {
+            value : 'READY',
+            writable : false,
+            enumerable : true
+        },
+        'isAntennaConnected' : {
+            value : 'TEST',
+            writable : false,
+            enumerable : true
+        },
+        'mute' : {
+            value : 'TEST',
+            writable : false,
+            enumerable : true
+        }
+    });
+
+    function frequencyGetter() {
+        // TODO
+        return 1000;
+    }
+
+    function frequencyUpperGetter() {
+        return 108;
+    }
+
+    function frequencyLowerGetter() {
+        return 87.5;
+    }
 }
 
 FMRadioManager.prototype.seekUp = function() {
-    var ret = native_.call('FMRadio_SeekUp');
-    return 'SeekUp';
+    var args = validator_.validateArgs(arguments, [ {
+        name : 'successCallback',
+        type : types_.FUNCTION,
+        optional : true,
+        nullable : true
+    }, {
+        name : 'errorCallback',
+        type : types_.FUNCTION,
+        optional : true,
+        nullable : true
+    } ]);
+
+    var ret = native_.call('FMRadio_SeekUp', {}, function(result) {
+        if (native_.isFailure(result)) {
+            if (args.errorCallback)
+                args.errorCallback(native_.getErrorObject(result));
+        } else {
+            if (args.successCallback)
+                args.successCallback();
+        }
+    });
+
+};
+
+FMRadioManager.prototype.start = function() {
+    var args = validator_.validateArgs(arguments, [ {
+        name : 'frequency',
+        type : types_.DOUBLE,
+        optional : true,
+        nullable : true
+    } ]);
+
+    if (args.frequency) {
+        if (args.frequency < this.frequencyLowerBound
+                || args.frequency > this.frequencyUpperBound)
+            throw new tizen.WebAPIException(
+                    tizen.WebAPIException.INVALID_VALUES_ERR);
+    }
+    var result = native_.callSync('FMRadio_Start', {
+        'frequency' : args.frequency ? args.frequency
+                : this.frequencyLowerBound
+    });
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
 };
 
 FMRadioManager.prototype.seekDown = function() {
-    var ret = native_.call('FMRadio_SeekDown');
-    return 'SeekDown'
+    var args = validator_.validateArgs(arguments, [ {
+        name : 'successCallback',
+        type : types_.FUNCTION,
+        optional : true,
+        nullable : true
+    }, {
+        name : 'errorCallback',
+        type : types_.FUNCTION,
+        optional : true,
+        nullable : true
+    } ]);
+
+    var ret = native_.call('FMRadio_SeekDown', {}, function(result) {
+        if (native_.isFailure(result)) {
+            if (args.errorCallback)
+                args.errorCallback(native_.getErrorObject(result));
+        } else {
+            if (args.successCallback)
+                args.successCallback();
+        }
+    });
 };
 
 FMRadioManager.prototype.scanStart = function() {
-    var ret = native_.call('FMRadio_ScanStart');
-    return 'scanStart'
+
+};
+
+FMRadioManager.prototype.stop = function() {
+    var ret = native_.callSync('FMRadio_Stop');
 };
 
 FMRadioManager.prototype.scanStop = function() {
-    var ret = native_.call('FMRadio_ScanStop');
-    return 'scanStop'
+
 };
 
+function FMRadioInterruptManager() {
+
+    this.oninterrupted;
+    this.oninterruptfinished;
+};
+
+FMRadioInterruptManager.prototype.FMRadioInterruptedCBSwitch = function(args) {
+    if (args.action == 'oninterrupted') {
+        if (this.oninterrupted) {
+            this.oninterrupted();
+        }
+    } else {
+
+        if (this.oninterruptfinished) {
+            this.oninterruptfinished();
+        }
+    }
+};
+
+FMRadioInterruptManager.prototype.FMRadioInterruptedSet = function(oi, oif) {
+    this.oninterrupted = oi;
+    this.oninterruptfinished = oif;
+    native_.addListener('FMRadio_Interrupted', this.FMRadioInterruptedCBSwitch
+            .bind(this));
+};
+
+var intmgr = new FMRadioInterruptManager();
+
 FMRadioManager.prototype.setFMRadioInterruptedListener = function() {
+
+    var args = validator_.validateArgs(arguments, [ {
+        name : 'eventCallback',
+        type : types_.LISTENER,
+        values : [ 'oninterrupted', 'oninterruptfinished' ]
+    } ]);
+    intmgr.FMRadioInterruptedSet(args.eventCallback.oninterrupted,
+            args.eventCallback.oninterruptfinished)
+
     var ret = native_.callSync('FMRadio_SetFMRadioInterruptedListener');
-    return 'setFMRadioInterruptedListener'
+
 };
 
 FMRadioManager.prototype.unsetFMRadioInterruptedListener = function() {
+
+    // TODO intmgr unset
     var ret = native_.callSync('FMRadio_UnsetFMRadioInterruptedListener');
-    return 'unsetFMRadioInterruptedListener'
 };
 
 FMRadioManager.prototype.setAntennaChangeListener = function() {
+    var args = validator_.validateArgs(arguments, [ {
+        name : 'eventCallback',
+        type : types_.LISTENER,
+        values : [ 'onchange' ]
+    } ]);
+
+    // TODO listener manager
     var ret = native_.callSync('FMRadio_SetAntennaChangeListener');
-    return 'setAntennaChangeListener'
+
 };
 
 FMRadioManager.prototype.unsetAntennaChangeListener = function() {
+
+    // TODO listener manager
     var ret = native_.callSync('FMRadio_UnsetAntennaChangeListener');
-    return 'unsetAntennaChangeListener'
+
 };
 
 exports = new FMRadioManager();
-
index 0ca6d1cffa584facdd970cc263811e2aa60a182a..ae9f6eeb07a5f4d4856b944f3b10a9d4968b1a27 100644 (file)
@@ -23,5 +23,5 @@ RadioExtension::RadioExtension() {
 RadioExtension::~RadioExtension() {}
 
 common::Instance* RadioExtension::CreateInstance() {
-  return new extension::radio::RadioInstance;
+    return &extension::radio::RadioInstance::getInstance();
 }
index b93d493e053432e6d350d7564933a3cc7919b2fa..6d46831154048482c5428d985566f19e65378854 100644 (file)
@@ -7,14 +7,15 @@
 
 #include "common/extension.h"
 
-class RadioExtension : public common::Extension {
- public:
-  RadioExtension();
-  virtual ~RadioExtension();
+class RadioExtension : public common::Extension
+{
+    public:
+    RadioExtension();
+    virtual ~RadioExtension();
 
- private:
-  virtual common::Instance* CreateInstance();
   private:
+    virtual common::Instance* CreateInstance();
 };
 
-#endif
+#endif //RADIO_RADIO_EXTENSION_H_
 
index 70a9d8077343cea32ce72caed7e7ce256e4d4398..1f87cd3bb87c54dcedf3f604b43f1a4447358987 100644 (file)
@@ -43,47 +43,77 @@ namespace radio {
     RadioInstance::~RadioInstance() {
     }
 
-    void RadioInstance::Start(const picojson::value& args,
-            picojson::object& out){
-        LoggerD(".cc Start()");
+    RadioInstance& RadioInstance::getInstance() {
+            static RadioInstance instance;
+            return instance;
     }
 
-    void RadioInstance::Stop(const picojson::value& args,
-            picojson::object& out){
-        LoggerD(".cc Stop()");
+    void RadioInstance::InstanceReportSuccess(picojson::object& out) {
+        LoggerD(".cc InstanceReportSuccess()");
     }
 
     void RadioInstance::SeekUp(const picojson::value& args,
             picojson::object& out) {
         LoggerD(".cc SeekUp()");
+        FMRadioManager::GetInstance()->SeekUp(args);
     }
+
     void RadioInstance::SeekDown(const picojson::value& args,
             picojson::object& out) {
         LoggerD(".cc SeekDown()");
+        FMRadioManager::GetInstance()->SeekDown(args);
     }
+
+    void RadioInstance::Start(const picojson::value& args,
+            picojson::object& out) {
+        try{
+            LoggerD(".cc RadioInstance::Start()");
+            FMRadioManager::GetInstance()->Start(args.get("frequency").get<double>());
+        }
+        catch(const PlatformException& e){
+            LoggerE(".cc RadioInstance::Start() CATCH");
+            ReportError(e,out);
+        }
+    }
+
+    void RadioInstance::Stop(const picojson::value& args,
+            picojson::object& out) {
+          LoggerD(".cc Stop()");
+          FMRadioManager::GetInstance()->Stop();
+    }
+
     void RadioInstance::ScanStart(const picojson::value& args,
             picojson::object& out) {
-        LoggerD(".cc ScanStart()");
+          FMRadioManager::GetInstance()->ScanStart(args);
     }
+
     void RadioInstance::ScanStop(const picojson::value& args,
             picojson::object& out) {
-        LoggerD(".cc ScanStop()");
+        FMRadioManager::GetInstance()->ScanStop(args);
     }
+
     void RadioInstance::SetFMRadioInterruptedListener(const picojson::value& args,
             picojson::object& out) {
         LoggerD(".cc SetFMRadioInterruptedListener()");
+        FMRadioManager::GetInstance()->SetFMRadioInterruptedListener();
     }
+
     void RadioInstance::UnsetFMRadioInterruptedListener(const picojson::value& args,
             picojson::object& out) {
         LoggerD(".cc UnsetFMRadioInterruptedListener()");
+        FMRadioManager::GetInstance()->UnsetFMRadioInterruptedListener();
     }
+
     void RadioInstance::SetAntennaChangeListener(const picojson::value& args,
             picojson::object& out) {
         LoggerD(".cc SetAntennaChangeListener()");
+        FMRadioManager::GetInstance()->SetAntennaChangeListener();
     }
+
     void RadioInstance::UnsetAntennaChangeListener(const picojson::value& args,
             picojson::object& out) {
         LoggerD(".cc UnsetAntennaChangeListener()");
+        FMRadioManager::GetInstance()->UnsetAntennaChangeListener();
     }
 
 }
index 8eb1779bbc9ab51f80c5b7ac75219764eddd93e4..da06e7284c04b8bb725c5b47f4cece5e36e32b72 100644 (file)
@@ -6,7 +6,8 @@
 #define RADIO_RADIO_INSTANCE_H_
 
 #include "common/extension.h"
-
+#include "radio_manager.h"
+#include "common/picojson.h"
 
 namespace extension {
 namespace radio {
@@ -18,15 +19,17 @@ class RadioInstance
   RadioInstance();
   virtual ~RadioInstance();
 
+  static RadioInstance& getInstance();
 
+  void InstanceReportSuccess(picojson::object& out);
 
  private:
-  void Start(const picojson::value& args, picojson::object& out);
-  void Stop(const picojson::value& args, picojson::object& out);
   void SeekUp(const picojson::value& args, picojson::object& out);
   void SeekDown(const picojson::value& args, picojson::object& out);
   void ScanStart(const picojson::value& args, picojson::object& out);
   void ScanStop(const picojson::value& args, picojson::object& out);
+  void Start(const picojson::value& args, picojson::object& out);
+  void Stop(const picojson::value& args, picojson::object& out);
   void SetFMRadioInterruptedListener(const picojson::value& args, picojson::object& out);
   void UnsetFMRadioInterruptedListener(const picojson::value& args, picojson::object& out);
   void SetAntennaChangeListener(const picojson::value& args, picojson::object& out);
diff --git a/src/radio/radio_manager.cc b/src/radio/radio_manager.cc
new file mode 100755 (executable)
index 0000000..334d5f7
--- /dev/null
@@ -0,0 +1,225 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "radio_manager.h"
+
+#include <unistd.h>
+
+#include <cstring>
+#include <algorithm>
+
+#include <glib.h>
+
+#include <vconf.h>
+
+#include "common/logger.h"
+#include "common/extension.h"
+#include "common/platform_exception.h"
+
+using namespace common;
+using namespace std;
+
+namespace extension {
+namespace radio {
+
+typedef struct RadioSeekCBstruct_
+{
+    double cbid;
+    radio_h radio_instance;
+} RadioSeekCBstruct;
+
+
+static void createEventSuccess(picojson::object& obj,double callbackId)
+{
+    obj.insert(std::make_pair("callbackId", callbackId));
+    obj.insert(std::make_pair("status", picojson::value("success")));
+    picojson::value event = picojson::value(obj);
+    RadioInstance::getInstance().PostMessage(event.serialize().c_str());
+}
+
+static void createEventSuccess(double callbackId)
+{
+    picojson::value event = picojson::value(picojson::object());
+    picojson::object& obj = event.get<picojson::object>();
+    createEventSuccess(obj,callbackId);
+}
+
+
+static void createEventFail(double callbackId,const PlatformException& ex)
+{
+
+    picojson::value event = picojson::value(picojson::object());
+    picojson::object& obj = event.get<picojson::object>();
+
+    obj.insert(std::make_pair("error", ex.ToJSON()));
+    obj.insert(std::make_pair("callbackId", callbackId));
+    obj.insert(std::make_pair("status", picojson::value("error")));
+
+    RadioInstance::getInstance().PostMessage(event.serialize().c_str());
+ }
+
+int FMRadioManager::Create()
+{
+    if (radio_instance==NULL)
+    {
+        int err = radio_create(&radio_instance);
+        if(err){
+            LoggerE("radio_create %d",err);
+            radio_instance=NULL;
+        }
+        return err;
+
+    }
+    return 0;
+}
+
+FMRadioManager::FMRadioManager() : radio_instance(NULL)
+{
+    LoggerD("FMRadioManager::FMRadioManager()");
+}
+
+FMRadioManager::~FMRadioManager()
+{
+
+    LoggerD("FMRadioManager::~FMRadioManager()");
+    int err = radio_destroy(radio_instance);
+    LoggerD("radio_destroy() error %d",err);
+}
+
+FMRadioManager* FMRadioManager::GetInstance()
+{
+
+    static FMRadioManager instance;
+
+    instance.Create();
+    return &instance;
+}
+
+void FMRadioManager::CheckErr(string str,int err)
+{
+    if(err)
+    {
+        LoggerE("%s() error %d",str.c_str(),err);
+    }
+
+    if (err==RADIO_ERROR_INVALID_PARAMETER  )
+    {
+        throw common::InvalidValuesException(str);
+    }
+    else if(err==RADIO_ERROR_INVALID_STATE)
+    {
+        throw common::InvalidValuesException(str);
+    }
+    else if(err==RADIO_ERROR_SOUND_POLICY)
+    {
+        throw common::UnknownException(str);
+    }
+    else if(err==RADIO_ERROR_NOT_SUPPORTED)
+    {
+        throw common::ServiceNotAvailableException(str);
+    }
+    else
+    {
+        throw common::UnknownException(str);
+    }
+
+}
+
+void FMRadioManager::Start(double freq)
+{
+    LoggerD("FMRadioManager::Start(%f)",freq);
+
+    int err = radio_set_frequency (radio_instance, freq);
+    CheckErr("radio_set_frequency",err);
+
+    err= radio_start(radio_instance);
+    CheckErr("radio_start",err);
+}
+
+void FMRadioManager::Stop()
+{
+    int err= radio_stop(radio_instance);
+    CheckErr("radio_stop",err);
+}
+
+PlatformException FMRadioManager::GetException(char * name,int err)
+{
+    const int SIZE = 200;
+    char buff[SIZE];
+    snprintf(buff,SIZE-1,"%s:%d",name,err);
+
+    //TODO Split exception types
+    return UnknownException(buff);
+
+}
+
+void FMRadioManager::RadioSeekCB(int frequency, void *user_data)
+{
+    RadioSeekCBstruct * data = static_cast<RadioSeekCBstruct*>(user_data);
+    double callbackId = data->cbid;
+    int err = radio_set_frequency(static_cast<radio_h>(data->radio_instance),frequency);
+
+    if (RADIO_ERROR_NONE != err)
+    {
+        createEventFail(callbackId,GetException("radio_set_frequency",err));
+    }
+    else
+    {
+        createEventSuccess(callbackId);
+    }
+
+    delete data;
+}
+
+void FMRadioManager::SeekUp(const picojson::value& args){
+
+    double callbackId = args.get("callbackId").get<double>();
+    RadioSeekCBstruct *data= new RadioSeekCBstruct;
+    data->cbid = callbackId;
+    data->radio_instance = radio_instance;
+    int err = radio_seek_up (radio_instance,RadioSeekCB,static_cast<void *>(data));
+    if(RADIO_ERROR_NONE != err)
+    {
+        delete data;
+        createEventFail(callbackId,GetException("radio_set_frequency",err));
+    }
+
+}
+
+void FMRadioManager::SeekDown(const picojson::value& args){
+
+    double callbackId = args.get("callbackId").get<double>();
+        RadioSeekCBstruct *data= new RadioSeekCBstruct;
+        data->cbid = callbackId;
+        data->radio_instance = radio_instance;
+        int err = radio_seek_down (radio_instance,RadioSeekCB,static_cast<void *>(data));
+        if(RADIO_ERROR_NONE != err)
+        {
+            delete data;
+            createEventFail(callbackId,GetException("radio_set_frequency",err));
+        }
+}
+
+void FMRadioManager::ScanStart(const picojson::value& args){
+    LoggerD("FMRadioManager::StartScan()");
+}
+void FMRadioManager::ScanStop(const picojson::value& args){
+    LoggerD("FMRadioManager::StopScan()");
+}
+void FMRadioManager::SetFMRadioInterruptedListener(){
+    LoggerD("FMRadioManager::SetFMRadioInterruptedListener()");
+}
+void FMRadioManager::UnsetFMRadioInterruptedListener(){
+    LoggerD("FMRadioManager::UnsetFMRadioInterruptedListener()");
+}
+void FMRadioManager::SetAntennaChangeListener(){
+    LoggerD("FMRadioManager::SetAntennaChangeListener()");
+}
+void FMRadioManager::UnsetAntennaChangeListener(){
+    LoggerD("FMRadioManager::UnetAntennaChangeListener()");
+}
+
+} // namespace
+} // namespace extension
+
diff --git a/src/radio/radio_manager.h b/src/radio/radio_manager.h
new file mode 100755 (executable)
index 0000000..4305e2d
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FMRADIO_FMRADIO_MANAGER_H_
+#define FMRADIO_FMRADIO_MANAGER_H_
+
+#include <string>
+#include <list>
+#include <device/callback.h>
+#include "common/picojson.h"
+#include "common/platform_exception.h"
+
+#include "radio_instance.h"
+
+#include <radio.h>
+
+namespace extension {
+namespace radio {
+
+class FMRadioManager {
+public:
+
+    static FMRadioManager* GetInstance();
+
+    void Start(double freq);
+    void Stop();
+    void SeekUp(const picojson::value& args);
+    void SeekDown(const picojson::value& args);
+    void ScanStart(const picojson::value& args);
+    void ScanStop(const picojson::value& args);
+    void SetFMRadioInterruptedListener();
+    void UnsetFMRadioInterruptedListener();
+    void SetAntennaChangeListener();
+    void UnsetAntennaChangeListener();
+
+private:
+
+    static common::PlatformException GetException(char * name,int err);
+    static void RadioSeekCB(int frequency, void *user_data);
+    static void CheckErr(std::string str,int err);
+
+    radio_h radio_instance;
+
+    int Create();
+
+    FMRadioManager();
+    ~FMRadioManager();
+
+
+};
+
+} // namespace
+} // namespace extension
+
+#endif // RADIO_RADIO_MANAGER_H_
+
index 7f3bde8bf7896fa3714371a666254f8a53bc6a2e..7bd283c7682fea11e7250e72378ef6561f5a10d5 100644 (file)
@@ -24,6 +24,7 @@
               'calendar/calendar.gyp:*',
               'datasync/datasync.gyp:*',
               'messaging/messaging.gyp:*',
+              'radio/radio.gyp:*',
               'nfc/nfc.gyp:*',
               'power/power.gyp:*',
               'bookmark/bookmark.gyp:*',