You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2012/07/28 03:58:17 UTC

js commit: [Cordova-Tizen]

Updated Branches:
  refs/heads/master 8c46a970a -> b8fae990b


[Cordova-Tizen]

    This is our very first commit  to Cordova.js in our attemps to port Cordova to Tizen.

    based on 2.0.0 version

    We first started with the old architecture, but it became obvious that it would be best to go directly with the new architecture know as Callback.js and eventually Cordova.js.

    the Intel Open source Technology Center(OTC) team behind this still on progress work is:
    - Christophe Guiraud, Intel Open source Technology Center, Senior Software Engineer
    - Regis Merlino, Intel OTC, Senior Software Engineer,
    - Paul Plaquette, Intel OTC, Senior Software Engineer (me)

    Still on Progress, as Tizen is still on progress, as a web only based platform, as well as cordova API.

    Whats in:
    - Accelerometer
    - Battery
    - Camera
    - Compass
    - Contact, ContactUtils, contacts
    - Device
    - File
    - FileTransfer
    - Media
    - MediaError
    - NetworkStatus
    - Notification, SoundBeat, BufferLoader
    - manager
    - bootstrap-tizen.js

    there's a know issue with notifications UI that is requiring a tizen.css, and for now is integrating
    that should be pop up windows as a front window div... this will be fix very soon


Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/commit/b8fae990
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/b8fae990
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/b8fae990

Branch: refs/heads/master
Commit: b8fae990b914ee619a925cddad413149b19cd7af
Parents: 8c46a97
Author: paul plaquette <pp...@gmail.com>
Authored: Fri Jul 27 15:00:21 2012 +0200
Committer: Anis Kadri <an...@gmail.com>
Committed: Fri Jul 27 18:57:28 2012 -0700

----------------------------------------------------------------------
 Jakefile                                |    1 +
 lib/scripts/bootstrap-tizen.js          |    1 +
 lib/tizen/exec.js                       |   59 +++
 lib/tizen/platform.js                   |   39 ++
 lib/tizen/plugin/tizen/Accelerometer.js |   19 +
 lib/tizen/plugin/tizen/Battery.js       |   22 ++
 lib/tizen/plugin/tizen/BufferLoader.js  |   86 +++++
 lib/tizen/plugin/tizen/Camera.js        |   65 ++++
 lib/tizen/plugin/tizen/Compass.js       |   27 ++
 lib/tizen/plugin/tizen/Contact.js       |  486 ++++++++++++++++++++++++++
 lib/tizen/plugin/tizen/ContactUtils.js  |  371 ++++++++++++++++++++
 lib/tizen/plugin/tizen/Device.js        |   36 ++
 lib/tizen/plugin/tizen/File.js          |  354 +++++++++++++++++++
 lib/tizen/plugin/tizen/FileTransfer.js  |  141 ++++++++
 lib/tizen/plugin/tizen/Media.js         |  135 +++++++
 lib/tizen/plugin/tizen/MediaError.js    |    8 +
 lib/tizen/plugin/tizen/NetworkStatus.js |   40 +++
 lib/tizen/plugin/tizen/Notification.js  |  124 +++++++
 lib/tizen/plugin/tizen/SoundBeat.js     |   73 ++++
 lib/tizen/plugin/tizen/contacts.js      |   64 ++++
 lib/tizen/plugin/tizen/manager.js       |   17 +
 21 files changed, 2168 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/Jakefile
----------------------------------------------------------------------
diff --git a/Jakefile b/Jakefile
index fb97f8a..7c412f9 100644
--- a/Jakefile
+++ b/Jakefile
@@ -75,6 +75,7 @@ task('build', ['clean', 'hint'], function () {
         packager.generate("wp7",commitId);
         packager.generate("android",commitId);
         packager.generate("bada",commitId);
+        packager.generate("tizen",commitId);
         packager.generate("errgen",commitId);
         packager.generate("test",commitId);
         complete();

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/scripts/bootstrap-tizen.js
----------------------------------------------------------------------
diff --git a/lib/scripts/bootstrap-tizen.js b/lib/scripts/bootstrap-tizen.js
new file mode 100644
index 0000000..19cf867
--- /dev/null
+++ b/lib/scripts/bootstrap-tizen.js
@@ -0,0 +1 @@
+require('cordova/channel').onNativeReady.fire();

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/exec.js
----------------------------------------------------------------------
diff --git a/lib/tizen/exec.js b/lib/tizen/exec.js
new file mode 100644
index 0000000..2c02f34
--- /dev/null
+++ b/lib/tizen/exec.js
@@ -0,0 +1,59 @@
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchrounous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} successCB  The success callback
+ * @param {Function} failCB     The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+
+var tizen = require('cordova/plugin/tizen/manager'),
+    cordova = require('cordova'),
+    utils = require('cordova/utils');
+
+module.exports = function(successCB, failCB, service, action, args) {
+
+    try {
+        var v = tizen.exec(successCB, failCB, service, action, args);
+
+        // If status is OK, then return value back to caller
+        if (v.status == cordova.callbackStatus.OK) {
+
+            // If there is a success callback, then call it now with returned value
+            if (successCB) {
+                try {
+                    successCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+ service + "." + action + " = " + e);
+                }
+
+            }
+            return v.message;
+        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
+            // Nothing to do here
+        } else {
+            // If error, then display error
+            console.log("Error: " + service + "." + action + " Status=" + v.status + " Message=" + v.message);
+
+            // If there is a fail callback, then call it now with returned value
+            if (failCB) {
+                try {
+                    failCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in error callback: " + service + "." + action + " = "+e);
+                }
+            }
+            return null;
+        }
+    } catch (e) {
+        utils.alert("Error: " + e);
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/platform.js
----------------------------------------------------------------------
diff --git a/lib/tizen/platform.js b/lib/tizen/platform.js
new file mode 100644
index 0000000..d098100
--- /dev/null
+++ b/lib/tizen/platform.js
@@ -0,0 +1,39 @@
+module.exports = {
+    id: "tizen",
+    initialize: function() {},
+    objects: {
+        device: {
+            path: "cordova/plugin/tizen/Device"
+        },
+        File: { // exists natively, override
+            path: "cordova/plugin/File"
+        },
+        FileReader: { // exists natively, override
+            path: "cordova/plugin/FileReader"
+        },
+        FileError: { //exists natively, override
+            path: "cordova/plugin/FileError"
+        }
+    },
+    merges: {
+        MediaError: { // exists natively
+            path: "cordova/plugin/tizen/MediaError"
+        },
+        navigator: {
+            children: {
+                device: {
+                    path: "cordova/plugin/tizen/Device"
+                },
+                contacts: {
+                    path: "cordova/plugin/tizen/contacts"
+                },
+               notification: {
+                   path: "cordova/plugin/tizen/Notification"
+               }
+            }
+        },
+        Contact: {
+            path: "cordova/plugin/tizen/Contact"
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Accelerometer.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Accelerometer.js b/lib/tizen/plugin/tizen/Accelerometer.js
new file mode 100644
index 0000000..127d00e
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Accelerometer.js
@@ -0,0 +1,19 @@
+var callback = null;
+
+module.exports = {
+    start: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+        callback = function (motion) {
+            successCallback({
+                x: motion.accelerationIncludingGravity.x,
+                y: motion.accelerationIncludingGravity.y,
+                z: motion.accelerationIncludingGravity.z,
+                timestamp: motion.timeStamp
+            });
+        };
+        window.addEventListener("devicemotion", callback);
+    },
+    stop: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+    }
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Battery.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Battery.js b/lib/tizen/plugin/tizen/Battery.js
new file mode 100644
index 0000000..6c633b7
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Battery.js
@@ -0,0 +1,22 @@
+/*global tizen:false */
+var id = null;
+
+module.exports = {
+    start: function(successCallback, errorCallback) {
+        var tizenSuccessCallback = function(power) {
+            if (successCallback) {
+                successCallback({level: Math.round(power.level * 100), isPlugged: power.isCharging});
+            }
+        };
+
+        if (id === null) {
+            id = tizen.systeminfo.addPropertyValueChangeListener("Power", tizenSuccessCallback);
+        }
+        tizen.systeminfo.getPropertyValue("Power", tizenSuccessCallback, errorCallback);
+    },
+
+    stop: function(successCallback, errorCallback) {
+        tizen.systeminfo.removePropertyValueChangeListener(id);
+        id = null;
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/BufferLoader.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/BufferLoader.js b/lib/tizen/plugin/tizen/BufferLoader.js
new file mode 100644
index 0000000..d0859e1
--- /dev/null
+++ b/lib/tizen/plugin/tizen/BufferLoader.js
@@ -0,0 +1,86 @@
+/*
+ * Buffer Loader Object
+ * This class provides a sound buffer for one or more sounds
+ * holded in a local file located by an url
+ *
+ * uses W3C  Web Audio API
+ *
+ * @constructor
+ *
+ * @param {AudioContext} audio context object
+ * @param {Array} urlList, array of url for sound to load
+ * @param {function} callback , called after buffer was loaded
+ *
+ */
+
+function BufferLoader(context, urlList, callback) {
+    this.context = context;
+    this.urlList = urlList;
+    this.onload = callback;
+    this.bufferList = [];
+    this.loadCount = 0;
+}
+
+/*
+ * This method loads a sound into a buffer
+ * @param {Array} urlList, array of url for sound to load
+ * @param {Number} index, buffer index in the array where to load the url sound
+ *
+ */
+
+BufferLoader.prototype.loadBuffer = function(url, index) {
+    // Load buffer asynchronously
+    var request = null,
+        loader = null;
+
+    request = new XMLHttpRequest();
+
+    if (request === null) {
+        console.log ("BufferLoader.prototype.loadBuffer, cannot allocate XML http request");
+        return;
+    }
+
+    request.open("GET", url, true);
+    request.responseType = "arraybuffer";
+
+    loader = this;
+
+    request.onload = function() {
+    // Asynchronously decode the audio file data in request.response
+    loader.context.decodeAudioData(
+        request.response,
+        function(buffer) {
+                if (!buffer) {
+                    console.log ("BufferLoader.prototype.loadBuffer,error decoding file data: " + url);
+                    return;
+                }
+
+                loader.bufferList[index] = buffer;
+
+                if (++loader.loadCount == loader.urlList.length) {
+                    loader.onload(loader.bufferList);
+                }
+            }
+        );
+    };
+
+    request.onerror = function() {
+        console.log ("BufferLoader.prototype.loadBuffer, XHR error");
+    };
+
+    request.send();
+};
+
+/*
+ * This method loads all sounds identified by their url
+ * and that where given to the object constructor
+ *
+ */
+
+BufferLoader.prototype.load = function() {
+    for (var i = 0; i < this.urlList.length; ++i) {
+        this.loadBuffer(this.urlList[i], i);
+    }
+};
+
+module.exports = BufferLoader;

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Camera.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Camera.js b/lib/tizen/plugin/tizen/Camera.js
new file mode 100644
index 0000000..87e83fb
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Camera.js
@@ -0,0 +1,65 @@
+/*global tizen:false */
+var Camera = require('cordova/plugin/CameraConstants');
+
+function makeReplyCallback(successCallback, errorCallback) {
+    return {
+        onsuccess: function(reply) {
+            if (reply.length > 0) {
+                successCallback(reply[0].value);
+            } else {
+                errorCallback('Picture selection aborted');
+            }
+        },
+        onfail: function() {
+           console.log('The service launch failed');
+        }
+    };
+}
+
+module.exports = {
+    takePicture: function(successCallback, errorCallback, args) {
+        var destinationType = args[1],
+            sourceType = args[2],
+            encodingType = args[5],
+            mediaType = args[6];
+            // Not supported
+            /*
+            quality = args[0]
+            targetWidth = args[3]
+            targetHeight = args[4]
+            allowEdit = args[7]
+            correctOrientation = args[8]
+            saveToPhotoAlbum = args[9]
+            */
+
+        if (destinationType !== Camera.DestinationType.FILE_URI) {
+            errorCallback('DestinationType not supported');
+            return;
+        }
+        if (mediaType !== Camera.MediaType.PICTURE) {
+            errorCallback('MediaType not supported');
+            return;
+        }
+
+        var mimeType;
+        if (encodingType === Camera.EncodingType.JPEG) {
+            mimeType = 'image/jpeg';
+        } else if (encodingType === Camera.EncodingType.PNG) {
+            mimeType = 'image/png';
+        } else {
+            mimeType = 'image/*';
+        }
+
+        var serviceId;
+        if (sourceType === Camera.PictureSourceType.CAMERA) {
+            serviceId = 'http://tizen.org/appsvc/operation/create_content';
+        } else {
+            serviceId = 'http://tizen.org/appsvc/operation/pick';
+        }
+
+        var service = new tizen.ApplicationService(serviceId, null, mimeType, null);
+        tizen.application.launchService(service, null, null,
+                function(error) { errorCallback(error.message); },
+                makeReplyCallback(successCallback, errorCallback));
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Compass.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Compass.js b/lib/tizen/plugin/tizen/Compass.js
new file mode 100644
index 0000000..f1e5d63
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Compass.js
@@ -0,0 +1,27 @@
+var CompassError = require('cordova/plugin/CompassError'),
+    callback = null, ready = false;
+
+module.exports = {
+    getHeading: function(successCallback, errorCallback) {
+        if (window.DeviceOrientationEvent !== undefined) {
+            callback = function (orientation) {
+                var heading = 360 - orientation.alpha;
+                if (ready) {
+                    successCallback({
+                        magneticHeading: heading,
+                        trueHeading: heading,
+                        headingAccuracy: 0,
+                        timestamp: orientation.timeStamp
+                    });
+                    window.removeEventListener("deviceorientation", callback);
+                }
+                ready = true;
+            };
+            ready = false; // workaround invalid first event value returned by WRT
+            window.addEventListener("deviceorientation", callback);
+        }
+        else {
+            errorCallback(CompassError.COMPASS_NOT_SUPPORTED);
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Contact.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Contact.js b/lib/tizen/plugin/tizen/Contact.js
new file mode 100644
index 0000000..f2bf3f5
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Contact.js
@@ -0,0 +1,486 @@
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// ------------------
+// Utility functions
+// ------------------
+
+
+/**
+ * Retrieves a Tizen Contact object from the device by its unique id.
+ *
+ * @param uid
+ *            Unique id of the contact on the device
+ * @return {tizen.Contact} Tizen Contact object or null if contact with
+ *         specified id is not found
+ */
+var findByUniqueId = function(id) {
+
+    if (!id) {
+        return null;
+    }
+
+    var tizenContact = null;
+
+    tizen.contact.getDefaultAddressBook().find(
+        function _successCallback(contacts){
+            tizenContact = contacts[0];
+        },
+        function _errorCallback(error){
+            console.log("tizen find error " + error);
+        },
+        new tizen.AttributeFilter('id', 'CONTAINS', id),
+        new tizen.SortMode('id', 'ASC'));
+
+    return tizenContact || null;
+};
+
+
+var traceTizenContact = function (tizenContact) {
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.id " + tizenContact.id);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.lastUpdated " + tizenContact.lastUpdated);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.name " + tizenContact.name);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.account " + tizenContact.account);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.addresses " + tizenContact.addresses);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.photoURI " + tizenContact.photoURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.phoneNumbers " + tizenContact.phoneNumbers);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.emails " + tizenContact.emails);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.birthday " + tizenContact.birthday);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.organization " + tizenContact.organization);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.notes " + tizenContact.notes);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.urls " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.isFavorite " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.ringtonesURI " + tizenContact.ringtonesURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.categories " + tizenContact.categories);
+};
+
+
+/**
+ * Creates a Tizen contact object from the W3C Contact object and persists
+ * it to device storage.
+ *
+ * @param {Contact}
+ *            contact The contact to save
+ * @return a new contact object with all properties set
+ */
+var saveToDevice = function(contact) {
+
+    if (!contact) {
+        return;
+    }
+
+    var tizenContact = null;
+    var update = false;
+    var i = 0;
+
+    // if the underlying Tizen Contact object already exists, retrieve it for
+    // update
+    if (contact.id) {
+        // we must attempt to retrieve the BlackBerry contact from the device
+        // because this may be an update operation
+        tizenContact = findByUniqueId(contact.id);
+    }
+
+    // contact not found on device, create a new one
+    if (!tizenContact) {
+        tizenContact = new tizen.Contact();
+    }
+    // update the existing contact
+    else {
+        update = true;
+    }
+
+    // NOTE: The user may be working with a partial Contact object, because only
+    // user-specified Contact fields are returned from a find operation (blame
+    // the W3C spec). If this is an update to an existing Contact, we don't
+    // want to clear an attribute from the contact database simply because the
+    // Contact object that the user passed in contains a null value for that
+    // attribute. So we only copy the non-null Contact attributes to the
+    // Tizen Contact object before saving.
+    //
+    // This means that a user must explicitly set a Contact attribute to a
+    // non-null value in order to update it in the contact database.
+    //
+    traceTizenContact (tizenContact);
+
+    // display name
+    if (contact.displayName !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            tizenContact.name.displayName = contact.displayName;
+        }
+    }
+
+    // name
+    if (contact.name !== null) {
+        if (contact.name.givenName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.firstName = contact.name.givenName;
+            }
+        }
+
+        if  (contact.name.middleName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.middleName = contact.name.middleName;
+            }
+        }
+
+        if (contact.name.familyName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.lastName = contact.name.familyName;
+            }
+        }
+
+        if (contact.name.honorificPrefix) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.prefix = contact.name.honorificPrefix;
+            }
+        }
+    }
+
+    // nickname
+    if (contact.nickname !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            if (!utils.isArray(tizenContact.name.nicknames))
+            {
+                tizenContact.name.nicknames = [];
+            }
+            tizenContact.name.nicknames[0] = contact.nickname;
+        }
+    }
+    else {
+        tizenContact.name.nicknames = [];
+    }
+
+    // note
+    if (contact.note !== null) {
+        if (tizenContact.note === null) {
+            tizenContact.note = [];
+        }
+        if (tizenContact.note !== null) {
+            tizenContact.note[0] = contact.note;
+        }
+    }
+
+    // photos
+    if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) {
+        tizenContact.photoURI = contact.photos[0];
+    }
+
+    if (utils.isDate(contact.birthday)) {
+        if (!utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday = new Date();
+        }
+        if (utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday.setDate(contact.birthday.getDate());
+        }
+    }
+
+    // Tizen supports many addresses
+    if (utils.isArray(contact.emails)) {
+
+        // if this is an update, re initialize email addresses
+        if (update) {
+            // doit on effacer sur un update??????
+        }
+
+        // copy the first three email addresses found
+        var emails = [];
+        for (i = 0; i < contact.emails.length; i += 1) {
+            var emailTypes = [];
+
+            emailTypes.push (contact.emails[i].type);
+
+            if (contact.emails[i].pref) {
+                emailTypes.push ("PREF");
+            }
+
+            emails.push(
+                new tizen.ContactEmailAddress(
+                    contact.emails[i].value,
+                    emailTypes)
+            );
+        }
+        tizenContact.emails = emails.length > 0 ? emails : [];
+    }
+    else {
+        tizenContact.emails = [];
+    }
+
+    // Tizen supports many phone numbers
+    // copy into appropriate fields based on type
+    if (utils.isArray(contact.phoneNumbers)) {
+        // if this is an update, re-initialize phone numbers
+        if (update) {
+        }
+
+        var phoneNumbers = [];
+
+        for (i = 0; i < contact.phoneNumbers.length; i += 1) {
+
+            if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) {
+                continue;
+            }
+
+             var phoneTypes = [];
+             phoneTypes.push (contact.phoneNumbers[i].type);
+
+             if (contact.phoneNumbers[i].pref) {
+                 phoneTypes.push ("PREF");
+             }
+
+            phoneNumbers.push(
+                new tizen.ContactPhoneNumber(
+                    contact.phoneNumbers[i].value,
+                    phoneTypes)
+            );
+        }
+
+        tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : [];
+    } else {
+        tizenContact.phoneNumbers = [];
+    }
+
+    if (utils.isArray(contact.addresses)) {
+        // if this is an update, re-initialize addresses
+        if (update) {
+        }
+
+        var addresses = [],
+            address = null;
+
+        for ( i = 0; i < contact.addresses.length; i += 1) {
+            address = contact.addresses[i];
+
+            if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) {
+                continue;
+            }
+
+            var addressTypes = [];
+            addressTypes.push (address.type);
+
+            if (address.pref) {
+                addressTypes.push ("PREF");
+            }
+
+            addresses.push(
+                new tizen.ContactAddress({
+                         country:                   address.country,
+                         region :                   address.region,
+                         city:                      address.locality,
+                         streetAddress:             address.streetAddress,
+                         additionalInformation:     "",
+                         postalCode:                address.postalCode,
+                         types :                    addressTypes
+                }));
+
+        }
+        tizenContact.addresses = addresses.length > 0 ? addresses : [];
+
+    } else{
+        tizenContact.addresses = [];
+    }
+
+    // copy first url found to BlackBerry 'webpage' field
+    if (utils.isArray(contact.urls)) {
+        // if this is an update, re-initialize web page
+        if (update) {
+        }
+
+        var url = null,
+            urls = [];
+
+        for ( i = 0; i< contact.urls.length; i+= 1) {
+            url = contact.urls[i];
+
+            if (!url || !url.value) {
+                continue;
+            }
+
+            urls.push( new tizen.ContactWebSite(url.value, url.type));
+        }
+        tizenContact.urls = urls.length > 0 ? urls : [];
+    } else{
+        tizenContact.urls = [];
+    }
+
+    if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) {
+        // if this is an update, re-initialize org attributes
+        var organization = contact.organizations[0];
+
+         tizenContact.organization = new tizen.ContacOrganization({
+             name:          organization.name,
+             department:    organization.department,
+             office:        "",
+             title:         organization.title,
+             role:          "",
+             logoURI:       ""
+         });
+    }
+
+    // categories
+    if (utils.isArray(contact.categories)) {
+        tizenContact.categories = [];
+
+        var category = null;
+
+        for (i = 0; i < contact.categories.length; i += 1) {
+            category = contact.categories[i];
+
+            if (typeof category === "string") {
+                tizenContact.categories.push(category);
+            }
+        }
+    }
+    else {
+        tizenContact.categories = [];
+    }
+
+    // save to device
+    // in tizen contact mean update or add
+    // later we might use addBatch and updateBatch
+    if (update){
+        tizen.contact.getDefaultAddressBook().update(tizenContact);
+    }
+    else {
+        tizen.contact.getDefaultAddressBook().add(tizenContact);
+    }
+
+    // Use the fully populated Tizen contact object to create a
+    // corresponding W3C contact object.
+    return ContactUtils.createContact(tizenContact, [ "*" ]);
+};
+
+
+/**
+ * Creates a Tizen ContactAddress object from a W3C ContactAddress.
+ *
+ * @return {tizen.ContactAddress} a Tizen ContactAddress object
+ */
+var createTizenAddress = function(address) {
+
+    var type = null,
+        pref = null,
+        typesAr = [];
+
+    if (address === null) {
+        return null;
+    }
+
+
+    var tizenAddress = new tizen.ContactAddress();
+
+    if (tizenAddress === null) {
+        return null;
+    }
+
+    typesAr.push(address.type);
+
+    if (address.pref) {
+        typesAr.push("PREF");
+    }
+
+    tizenAddress.country = address.country || "";
+    tizenAddress.region = address.region || "";
+    tizenAddress.city = address.locality || "";
+    tizenAddress.streetAddress = address.streetAddress || "";
+    tizenAddress.postalCode = address.postalCode || "";
+    tizenAddress.types = typesAr || "";
+
+    return tizenAddress;
+};
+
+module.exports = {
+    /**
+     * Persists contact to device storage.
+     */
+
+    save : function(successCB, failCB) {
+
+        try {
+            // save the contact and store it's unique id
+            var fullContact = saveToDevice(this);
+
+            this.id = fullContact.id;
+
+            // This contact object may only have a subset of properties
+            // if the save was an update of an existing contact. This is
+            // because the existing contact was likely retrieved using a
+            // subset of properties, so only those properties were set in the
+            // object. For this reason, invoke success with the contact object
+            // returned by saveToDevice since it is fully populated.
+
+            if (typeof successCB === 'function') {
+                successCB(fullContact);
+            }
+        }
+        catch (error) {
+            console.log('Error saving contact: ' +  error);
+
+            if (typeof failCB === 'function') {
+                failCB (new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    },
+
+    /**
+     * Removes contact from device storage.
+     *
+     * @param successCB
+     *            successCB callback
+     * @param failCB
+     *            error callback
+     */
+    remove : function (successCB, failCB) {
+
+        try {
+            // retrieve contact from device by id
+            var tizenContact = null;
+
+            if (this.id) {
+                tizenContact = findByUniqueId(this.id);
+            }
+
+
+            // if contact was found, remove it
+            if (tizenContact) {
+
+                tizen.contact.getDefaultAddressBook().remove(tizenContact.id);
+
+                if (typeof success === 'function') {
+                    successCB(this);
+                }
+            }
+            // attempting to remove a contact that hasn't been saved
+            else if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+        catch (error) {
+            console.log('Error removing contact ' + this.id + ": " + error);
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/ContactUtils.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/ContactUtils.js b/lib/tizen/plugin/tizen/ContactUtils.js
new file mode 100644
index 0000000..3252087
--- /dev/null
+++ b/lib/tizen/plugin/tizen/ContactUtils.js
@@ -0,0 +1,371 @@
+/*global tizen:false */
+var ContactAddress = require('cordova/plugin/ContactAddress'),
+    ContactName = require('cordova/plugin/ContactName'),
+    ContactField = require('cordova/plugin/ContactField'),
+    ContactOrganization = require('cordova/plugin/ContactOrganization'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+ * Mappings for each Contact field that may be used in a find operation. Maps
+ * W3C Contact fields to one or more fields in a Tizen contact object.
+ *
+ * Example: user searches with a filter on the Contact 'name' field:
+ *
+ * <code>Contacts.find(['name'], onSuccess, onFail, {filter:'Bob'});</code>
+ *
+ * The 'name' field does not exist in a Tizen contact. Instead, a filter
+ * expression will be built to search the Tizen contacts using the
+ * Tizen 'title', 'firstName' and 'lastName' fields.
+ */
+var fieldMappings = {
+    "id" : ["id"],
+    "displayName" : ["name.displayName"],
+    "nickname": ["name.nicknames"],
+    "name" : [ "name.prefix", "name.firstName", "name.lastName" ],
+    "phoneNumbers" : ["phoneNumbers.number","phoneNumbers.types"],
+    "emails" : ["emails.types", "emails.email"],
+    "addresses" : ["addresses.country","addresses.region","addresses.city","addresses.streetAddress","addresses.postalCode","addresses.country","addresses.types"],
+    "organizations" : ["organization.name","organization.department","organization.office", "organization.title"],
+    "birthday" : ["birthday"],
+    "note" : ["notes"],
+    "photos" : ["photoURI"],
+    "categories" : ["categories"],
+    "urls" : ["urls.url", "urls.type"]
+};
+
+/*
+ * Build an array of all of the valid W3C Contact fields. This is used to
+ * substitute all the fields when ["*"] is specified.
+ */
+var allFields = [];
+
+(function initializeAllFieldsMapping() {
+
+    for ( var key in fieldMappings) {
+        allFields.push(key);
+    }
+    // as we want it to be executed once
+    function initializeAllFieldsMapping() {
+    }
+
+})();
+
+/**
+ * Create a W3C ContactAddress object from a Tizen Address object
+ *
+ * @param {String}
+ *            type the type of address (e.g. work, home)
+ * @param {tizen.ContactAddress}
+ *            tizenAddress a Tizen Address object
+ * @return {ContactAddress} a contact address object or null if the specified
+ *         address is null
+ */
+var createContactAddress = function(type, tizenAddress) {
+    if (!tizenAddress) {
+        return null;
+    }
+
+    var streetAddress = tizenAddress.streetAddress;
+    var locality = tizenAddress.city || "";
+    var region = tizenAddress.region || "";
+    var postalCode = tizenAddress.postalCode || "";
+    var country = tizenAddress.country || "";
+    var formatted = streetAddress + ", " + locality + ", " + region + ", " + postalCode + ", " + country;
+
+    var contact = new ContactAddress(null, type, formatted, streetAddress, locality, region, postalCode, country);
+
+    return contact;
+};
+
+module.exports = {
+    /**
+     * Builds Tizen filter expressions for contact search using the
+     * contact fields and search filter provided.
+     *
+     * @param {String[]}
+     *            fields Array of Contact fields to search
+     * @param {String}
+     *            filter Filter, or search string
+     * @param {Boolean}
+     *                 multiple, one contacts or more wanted as result
+     * @return filter expression or null if fields is empty or filter is null or
+     *         empty
+     */
+
+    buildFilterExpression: function(fields, filter) {
+        // ensure filter exists
+        if (!filter || filter === "") {
+            return null;
+        }
+
+        if ((fields.length === 1) && (fields[0] === "*")) {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // build a filter expression using all Contact fields provided
+        var compositeFilter = null,
+            attributeFilter = null,
+            filterExpression = null,
+            matchFlag = "CONTAINS",
+            matchValue = filter,
+            attributesArray = [];
+
+        if (fields && utils.isArray(fields)) {
+
+            for ( var field in fields) {
+
+                if (!fields[field]) {
+                    continue;
+                }
+
+                // retrieve Tizen contact fields that map Cordova fields specified
+                // (tizenFields is a string or an array of strings)
+                var tizenFields = fieldMappings[fields[field]];
+
+                if (!tizenFields) {
+                    // does something maps
+                    continue;
+                }
+
+                // construct the filter expression using the Tizen fields
+                for ( var index in tizenFields) {
+                    attributeFilter = new tizen.AttributeFilter(tizenFields[index], matchFlag, matchValue);
+                    if (attributeFilter !== null) {
+                        attributesArray.push(attributeFilter);
+                    }
+                }
+            }
+        }
+
+        // fullfil tizen find attribute as a single or a composite attribute
+        if (attributesArray.length == 1 ) {
+            filterExpression = attributeFilter[0];
+        } else if (attributesArray.length > 1) {
+            // combine the filters as a Union
+            filterExpression = new tizen.CompositeFilter("UNION", attributesArray);
+        } else {
+            filterExpression = null;
+        }
+
+        return filterExpression;
+    },
+
+
+
+    /**
+     * Creates a Contact object from a Tizen Contact object, copying only
+     * the fields specified.
+     *
+     * This is intended as a privately used function but it is made globally
+     * available so that a Contact.save can convert a BlackBerry contact object
+     * into its W3C equivalent.
+     *
+     * @param {tizen.Contact}
+     *            tizenContact Tizen Contact object
+     * @param {String[]}
+     *            fields array of contact fields that should be copied
+     * @return {Contact} a contact object containing the specified fields or
+     *         null if the specified contact is null
+     */
+    createContact: function(tizenContact, fields) {
+
+        if (!tizenContact) {
+            return null;
+        }
+
+        // construct a new contact object
+        // always copy the contact id and displayName fields
+        var contact = new Contact(tizenContact.id, tizenContact.name.displayName);
+
+
+        // nothing to do
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            return contact;
+        } else if (fields.length === 1 && fields[0] === "*") {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // add the fields specified
+        for ( var key in fields) {
+
+            var field = fields[key],
+                index = 0;
+
+            if (!field) {
+                continue;
+            }
+
+            // name
+            if (field.indexOf('name') === 0) {
+
+                var formattedName = (tizenContact.name.prefix || "");
+
+                if (tizenContact.name.firstName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.firstName || "");
+                }
+
+                if (tizenContact.name.middleName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.middleName || "");
+                }
+
+                if (tizenContact.name.lastName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.lastName || "");
+                }
+
+                contact.name = new ContactName(
+                        formattedName,
+                        tizenContact.name.lastName,
+                        tizenContact.name.firstName,
+                        tizenContact.name.middleName,
+                        tizenContact.name.prefix,
+                        null);
+            }
+
+            // phoneNumbers
+            else if (field.indexOf('phoneNumbers') === 0) {
+
+                var phoneNumbers = [];
+
+                for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) {
+
+                    phoneNumbers.push(
+                            new ContactField(
+                                    'PHONE',
+                                    tizenContact.phoneNumbers[index].number,
+                                    ((tizenContact.phoneNumbers[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+
+
+                contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null;
+            }
+
+            // emails
+            else if (field.indexOf('emails') === 0) {
+
+                var emails = [];
+
+                for (index = 0 ; index < tizenContact.emails.length ; ++index) {
+
+                    emails.push(
+                        new ContactField(
+                            'EMAILS',
+                            tizenContact.emails[index].email,
+                            ((tizenContact.emails[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+                contact.emails = emails.length > 0 ? emails : null;
+            }
+
+            // addresses
+            else if (field.indexOf('addresses') === 0) {
+
+                var addresses = [];
+                for (index = 0 ; index < tizenContact.addresses.length ; ++index) {
+
+                    addresses.push(
+                            new ContactAddress(
+                                    ((tizenContact.addresses[index].types[1] &&  tizenContact.addresses[index].types[1] === "PREF") ? true : false),
+                                    tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : "HOME",
+                                    null,
+                                    tizenContact.addresses[index].streetAddress,
+                                    tizenContact.addresses[index].city,
+                                    tizenContact.addresses[index].region,
+                                    tizenContact.addresses[index].postalCode,
+                                    tizenContact.addresses[index].country ));
+                }
+
+                contact.addresses = addresses.length > 0 ? addresses : null;
+            }
+
+            // birthday
+            else if (field.indexOf('birthday') === 0) {
+                if (utils.isDate(tizenContact.birthday)) {
+                    contact.birthday = tizenContact.birthday;
+                }
+            }
+
+            // note only one in Tizen Contact
+            else if (field.indexOf('note') === 0) {
+                if (tizenContact.note) {
+                    contact.note = tizenContact.note[0];
+                }
+            }
+
+            // organizations
+            else if (field.indexOf('organizations') === 0) {
+
+                var organizations = [];
+
+                // there's only one organization in a Tizen Address
+
+                if (tizenContact.organization) {
+                    organizations.push(
+                            new ContactOrganization(
+                                    true,
+                                    'WORK',
+                                    tizenContact.organization.name,
+                                    tizenContact.organization.department,
+                                    tizenContact.organization.jobTitle));
+                }
+
+                contact.organizations = organizations.length > 0 ? organizations : null;
+            }
+
+            // categories
+            else if (field.indexOf('categories') === 0) {
+
+                var categories = [];
+
+                if (tizenContact.categories) {
+
+                    for (index = 0 ; index < tizenContact.categories.length ; ++index) {
+                        categories.push(
+                                new ContactField(
+                                        'MAIN',
+                                        tizenContact.categories,
+                                        (index === 0) ));
+                    }
+
+                    contact.categories = categories.length > 0 ? categories : null;
+                }
+            }
+
+            // urls
+            else if (field.indexOf('urls') === 0) {
+                var urls = [];
+
+                if (tizenContact.urls) {
+                    for (index = 0 ; index <tizenContact.urls.length ; ++index) {
+                        urls.push(
+                                new ContactField(
+                                        tizenContact.urls[index].type,
+                                        tizenContact.urls[index].url,
+                                        (index === 0)));
+                    }
+                }
+
+                contact.urls = urls.length > 0 ? urls : null;
+            }
+
+            // photos
+            else if (field.indexOf('photos') === 0) {
+                var photos = [];
+
+                if (tizenContact.photoURI) {
+                    photos.push(new ContactField('URI', tizenContact.photoURI, true));
+                }
+
+                contact.photos = photos.length > 0 ? photos : null;
+            }
+        }
+
+        return contact;
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Device.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Device.js b/lib/tizen/plugin/tizen/Device.js
new file mode 100644
index 0000000..4d4287c
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Device.js
@@ -0,0 +1,36 @@
+/*global tizen:false */
+var channel = require('cordova/channel');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+function Device() {
+    this.version = null;
+    this.uuid = null;
+    this.name = null;
+    this.cordova =  "2.0.0";
+    this.platform = "Tizen";
+
+    var me = this;
+
+    function onSuccessCallback(sysInfoProp) {
+        me.name = sysInfoProp.model;
+        me.uuid = sysInfoProp.imei;
+        me.version = sysInfoProp.version;
+        channel.onCordovaInfoReady.fire();
+    }
+
+    function onErrorCallback(error) {
+        console.log("error initializing cordova: " + error);
+    }
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getDeviceInfo(onSuccessCallback, onErrorCallback);
+    });
+}
+
+Device.prototype.getDeviceInfo = function(success, fail, args) {
+    tizen.systeminfo.getPropertyValue("Device", success, fail);
+};
+
+module.exports = new Device();

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/File.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/File.js b/lib/tizen/plugin/tizen/File.js
new file mode 100644
index 0000000..2bf553d
--- /dev/null
+++ b/lib/tizen/plugin/tizen/File.js
@@ -0,0 +1,354 @@
+/*global WebKitBlobBuilder:false */
+var FileError = require('cordova/plugin/FileError'),
+    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    File = require('cordova/plugin/File'),
+    FileSystem = require('cordova/plugin/FileSystem');
+
+var nativeRequestFileSystem = window.webkitRequestFileSystem,
+    nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL,
+    NativeFileReader = window.FileReader;
+
+function getFileSystemName(nativeFs) {
+    return (nativeFs.name.indexOf("Persistent") != -1) ? "persistent" : "temporary";
+}
+
+function makeEntry(entry) {
+    if (entry.isDirectory) {
+        return new DirectoryEntry(entry.name, decodeURI(entry.toURL()));
+    }
+    else {
+        return new FileEntry(entry.name, decodeURI(entry.toURL()));
+    }
+}
+
+module.exports = {
+    /* requestFileSystem */
+    requestFileSystem: function(successCallback, errorCallback, args) {
+        var type = args[0],
+            size = args[1];
+
+        nativeRequestFileSystem(type, size, function(nativeFs) {
+            successCallback(new FileSystem(getFileSystemName(nativeFs), makeEntry(nativeFs.root)));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* resolveLocalFileSystemURI */
+    resolveLocalFileSystemURI: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            successCallback(makeEntry(entry));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryReader */
+    readEntries: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(dirEntry) {
+            var reader = dirEntry.createReader();
+            reader.readEntries(function(entries) {
+                var retVal = [];
+                for (var i = 0; i < entries.length; i++) {
+                    retVal.push(makeEntry(entries[i]));
+                }
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* Entry */
+    getMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getMetadata(function(metaData) {
+                successCallback(metaData.modificationTime);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    moveTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.moveTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    copyTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.copyTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    remove: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.remove(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getParent: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getParent(function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileEntry */
+    getFileMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.file(function(file) {
+                var retVal = new File(file.name, decodeURI(entry.toURL()), file.type, file.lastModifiedDate, file.size);
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryEntry */
+    getDirectory: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getDirectory(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    removeRecursively: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.removeRecursively(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getFile: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getFile(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileReader */
+    readAsText: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            encoding = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsText(file, encoding);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    readAsDataURL: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsDataURL(file);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileWriter */
+    write: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            text = args[1],
+            position = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.position - position);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                var blob = new WebKitBlobBuilder();
+                blob.append(text);
+
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.seek(position);
+                writer.write(blob.getBlob('text/plain'));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    truncate: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            size = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.length);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.truncate(size);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/FileTransfer.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/FileTransfer.js b/lib/tizen/plugin/tizen/FileTransfer.js
new file mode 100644
index 0000000..9ed7834
--- /dev/null
+++ b/lib/tizen/plugin/tizen/FileTransfer.js
@@ -0,0 +1,141 @@
+/*global WebKitBlobBuilder:false */
+var FileEntry = require('cordova/plugin/FileEntry'),
+    FileTransferError = require('cordova/plugin/FileTransferError'),
+    FileUploadResult = require('cordova/plugin/FileUploadResult');
+
+var nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL;
+
+function getParentPath(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(0, pos + 1);
+}
+
+function getFileName(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(pos + 1);
+}
+
+module.exports = {
+    upload: function(successCallback, errorCallback, args) {
+        var filePath = args[0],
+            server = args[1],
+            fileKey = args[2],
+            fileName = args[3],
+            mimeType = args[4],
+            params = args[5],
+            /*trustAllHosts = args[6],*/
+            chunkedMode = args[7];
+
+        nativeResolveLocalFileSystemURI(filePath, function(entry) {
+            entry.file(function(file) {
+                function uploadFile(blobFile) {
+                    var fd = new FormData();
+
+                    fd.append(fileKey, blobFile, fileName);
+                    for (var prop in params) {
+                        if(params.hasOwnProperty(prop)) {
+                            fd.append(prop, params[prop]);
+                        }
+                    }
+
+                    var xhr = new XMLHttpRequest();
+                    xhr.open("POST", server);
+                    xhr.onload = function(evt) {
+                        if (xhr.status == 200) {
+                            var result = new FileUploadResult();
+                            result.bytesSent = file.size;
+                            result.responseCode = xhr.status;
+                            result.response = xhr.response;
+                            successCallback(result);
+                        } else if (xhr.status == 404) {
+                            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                        } else {
+                            errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                        }
+                    };
+                    xhr.ontimeout = function(evt) {
+                        errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                    };
+
+                    xhr.send(fd);
+                }
+
+                var bytesPerChunk;
+                if (chunkedMode === true) {
+                    bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.
+                } else {
+                    bytesPerChunk = file.size;
+                }
+                var start = 0;
+                var end = bytesPerChunk;
+                while (start < file.size) {
+                    var chunk = file.webkitSlice(start, end, mimeType);
+                    uploadFile(chunk);
+                    start = end;
+                    end = start + bytesPerChunk;
+                }
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            }
+            );
+        },
+        function(error) {
+            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+        }
+        );
+    },
+
+    download: function(successCallback, errorCallback, args) {
+        var url = args[0],
+            filePath = args[1];
+
+        var xhr = new XMLHttpRequest();
+
+        function writeFile(fileEntry) {
+            fileEntry.createWriter(function(writer) {
+                writer.onwriteend = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(new FileEntry(fileEntry.name, fileEntry.toURL()));
+                    } else {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    }
+                };
+
+                writer.onerror = function(evt) {
+                    errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                };
+
+                var builder = new WebKitBlobBuilder();
+                builder.append(xhr.response);
+                var blob = builder.getBlob();
+                writer.write(blob);
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            });
+        }
+
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == xhr.DONE) {
+                if (xhr.status == 200 && xhr.response) {
+                    nativeResolveLocalFileSystemURI(getParentPath(filePath), function(dir) {
+                        dir.getFile(getFileName(filePath), {create: true}, writeFile, function(error) {
+                            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                        });
+                    }, function(error) {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    });
+                } else if (xhr.status == 404) {
+                    errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                } else {
+                    errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                }
+            }
+        };
+
+        xhr.open("GET", url, true);
+        xhr.responseType = "arraybuffer";
+        xhr.send();
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Media.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Media.js b/lib/tizen/plugin/tizen/Media.js
new file mode 100644
index 0000000..5eb5c32
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Media.js
@@ -0,0 +1,135 @@
+/*global Media:false, webkitURL:false */
+var MediaError = require('cordova/plugin/MediaError'),
+    audioObjects = {};
+
+module.exports = {
+    create: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::create() - id =" + id + ", src =" + src);
+        audioObjects[id] = new Audio(src);
+        audioObjects[id].onStalledCB = function () {
+            console.log("media::onStalled()");
+             audioObjects[id].timer = window.setTimeout(function () {
+                    audioObjects[id].pause();
+                    if (audioObjects[id].currentTime !== 0)
+                        audioObjects[id].currentTime = 0;
+                    console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED);
+                    var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled");
+                    Media.onStatus(id, Media.MEDIA_ERROR, err);
+                }, 2000);
+        };
+        audioObjects[id].onEndedCB = function () {
+            console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        };
+        audioObjects[id].onErrorCB = function () {
+            console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error);
+            Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);
+        };
+        audioObjects[id].onPlayCB = function () {
+            console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
+        };
+        audioObjects[id].onPlayingCB = function () {
+            console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
+        };
+        audioObjects[id].onDurationChangeCB = function () {
+            console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " +  audioObjects[id].duration);
+            Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);
+        };
+        audioObjects[id].onTimeUpdateCB = function () {
+            console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " +  audioObjects[id].currentTime);
+            Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);
+        };
+        audioObjects[id].onCanPlayCB = function () {
+            console.log("media::onCanPlayCB()");
+            window.clearTimeout(audioObjects[id].timer);
+            audioObjects[id].play();
+        };
+      },
+    startPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1], options = args[2];
+        console.log("media::startPlayingAudio() - id =" + id + ", src =" + src + ", options =" + options);
+        audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);
+        audioObjects[id].play();
+    },
+    stopPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        audioObjects[id].pause();
+        if (audioObjects[id].currentTime !== 0)
+            audioObjects[id].currentTime = 0;
+        console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED");
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);
+    },
+    seekToAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], milliseconds = args[1];
+        console.log("media::seekToAudio()");
+         audioObjects[id].currentTime = milliseconds;
+        successCallback( audioObjects[id].currentTime);
+    },
+    pausePlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED");
+        audioObjects[id].pause();
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
+    },
+    getCurrentPositionAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::getCurrentPositionAudio()");
+        successCallback(audioObjects[id].currentTime);
+    },
+    release: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        console.log("media::release()");
+    },
+    setVolume: function (successCallback, errorCallback, args) {
+        var id = args[0], volume = args[1];
+        console.log("media::setVolume()");
+        audioObjects[id].volume = volume;
+    },
+    startRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::startRecordingAudio() - id =" + id + ", src =" + src);
+
+        function gotStreamCB(stream) {
+            audioObjects[id].src = webkitURL.createObjectURL(stream);
+            console.log("media::startRecordingAudio() - stream CB");
+        }
+
+        function gotStreamFailedCB(error) {
+            console.log("media::startRecordingAudio() - error CB:" + error.toString());
+        }
+
+        if (navigator.webkitGetUserMedia) {
+            audioObjects[id] = new Audio();
+            navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);
+        } else {
+            console.log("webkitGetUserMedia not supported");
+        }
+        successCallback();
+    },
+    stopRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::stopRecordingAudio() - id =" + id);
+        audioObjects[id].pause();
+        successCallback();
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/MediaError.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/MediaError.js b/lib/tizen/plugin/tizen/MediaError.js
new file mode 100644
index 0000000..fabf77f
--- /dev/null
+++ b/lib/tizen/plugin/tizen/MediaError.js
@@ -0,0 +1,8 @@
+
+// The MediaError object already exists on Tizen. This prevents the Cordova
+// version from being defined. This object is used to merge in differences
+// between Tizen and Cordova MediaError objects.
+module.exports = {
+        MEDIA_ERR_NONE_ACTIVE : 0,
+        MEDIA_ERR_NONE_SUPPORTED : 4
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/NetworkStatus.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/NetworkStatus.js b/lib/tizen/plugin/tizen/NetworkStatus.js
new file mode 100644
index 0000000..56076e4
--- /dev/null
+++ b/lib/tizen/plugin/tizen/NetworkStatus.js
@@ -0,0 +1,40 @@
+/*global tizen:false */
+var Connection = require('cordova/plugin/Connection');
+
+module.exports = {
+    getConnectionInfo: function (successCallback, errorCallback) {
+        var cncType = Connection.NONE;
+        var infoCount = 0;
+
+        function infoCB() {
+            infoCount++;
+            if (infoCount > 1)
+               successCallback(cncType);
+        }
+
+        function errorCB(error) {
+           console.log("Error: " + error.code + "," + error.name + "," + error.message);
+           infoCB();
+        }
+
+        function wifiSuccessCB(wifi) {
+            if ((wifi.status === "ON")  && (wifi.ipAddress.length !== 0))
+                cncType = Connection.WIFI;
+            infoCB();
+        }
+
+        function cellularSuccessCB(cell) {
+            if ((cncType === Connection.NONE) && (cell.status === "ON") && (cell.ipAddress.length !== 0))
+                cncType = Connection.CELL_2G;
+            infoCB();
+        }
+
+        if (tizen.systeminfo.isSupported('WifiNetwork')) {
+            tizen.systeminfo.getPropertyValue('WifiNetwork', wifiSuccessCB, errorCB);
+        }
+
+        if (tizen.systeminfo.isSupported('CellularNetwork')) {
+            tizen.systeminfo.getPropertyValue('CellularNetwork', cellularSuccessCB, errorCB);
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/Notification.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/Notification.js b/lib/tizen/plugin/tizen/Notification.js
new file mode 100644
index 0000000..9137c84
--- /dev/null
+++ b/lib/tizen/plugin/tizen/Notification.js
@@ -0,0 +1,124 @@
+var SoundBeat = require('cordova/plugin/tizen/SoundBeat');
+
+/* TODO: get resource path from app environment? */
+var soundBeat = new SoundBeat(["./sounds/beep.wav"]);
+
+module.exports = {
+
+    alert: function(message, alertCallback, title, buttonName) {
+        return this.confirm(message, alertCallback, title, buttonName);
+    },
+
+    confirm: function(message, confirmCallback, title, buttonLabels) {
+        var index            =    null,
+            overlayElement    =    null,
+            popup            =    null,
+            element         =    null,
+            titleString        =     null,
+            messageString    =    null,
+            buttonString    =    null,
+            buttonsArray    =    null;
+
+
+        console.log ("message" , message);
+        console.log ("confirmCallback" , confirmCallback);
+        console.log ("title" , title);
+        console.log ("buttonLabels" , buttonLabels);
+
+        titleString = '<div class="popup-title"><p>' + title + '</p></div>';
+        messageString = '<div class="popup-text"><p>' + message + '</p></div>';
+        buttonString = '<div class="popup-button-bg"><ul>';
+
+        switch(typeof(buttonLabels))
+        {
+        case "string":
+            buttonsArray = buttonLabels.split(",");
+
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+
+        case "array":
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+        default:
+            console.log ("cordova/plugin/tizen/Notification, default, buttonLabels: ", buttonLabels);
+            break;
+        }
+
+        buttonString += '</ul></div>';
+
+        overlayElement = document.createElement("div");
+        overlayElement.className = 'ui-popupwindow-screen';
+
+        overlayElement.style.zIndex = 1001;
+        overlayElement.style.width = "100%";
+        overlayElement.style.height = "100%";
+        overlayElement.style.top = 0;
+        overlayElement.style.left = 0;
+        overlayElement.style.margin = 0;
+        overlayElement.style.padding = 0;
+        overlayElement.style.position = "absolute";
+
+        popup = document.createElement("div");
+        popup.className = "ui-popupwindow";
+        popup.style.position = "fixed";
+        popup.style.zIndex = 1002;
+        popup.innerHTML = titleString + messageString + buttonString;
+
+        document.body.appendChild(overlayElement);
+        document.body.appendChild(popup);
+
+        function createListener(button) {
+            return function() {
+                document.body.removeChild(overlayElement);
+                document.body.removeChild(popup);
+                confirmCallback(button.value);
+            };
+        }
+
+       for (index in buttonsArray) {
+           console.log ("index: ", index);
+
+           element = document.getElementById("popup-button-" + buttonsArray[index]);
+           element.addEventListener("click", createListener(element), false);
+       }
+    },
+
+    vibrate: function(milliseconds) {
+        console.log ("milliseconds" , milliseconds);
+
+        if (navigator.vibrate) {
+            navigator.vibrate(milliseconds);
+        }
+        else {
+            console.log ("cordova/plugin/tizen/Notification, vibrate API does not exists");
+        }
+    },
+
+    beep: function(count) {
+        console.log ("count" , count);
+        soundBeat.play(count);
+    }
+};
+
+

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/SoundBeat.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/SoundBeat.js b/lib/tizen/plugin/tizen/SoundBeat.js
new file mode 100644
index 0000000..9cafbb0
--- /dev/null
+++ b/lib/tizen/plugin/tizen/SoundBeat.js
@@ -0,0 +1,73 @@
+/*global webkitAudioContext:false */
+/*
+ *  SoundBeat
+ * used by Notification Manager beep method
+ *
+ * This class provides sounds play
+ *
+ * uses W3C  Web Audio API
+ * uses BufferLoader object
+ *
+ * NOTE: the W3C Web Audio doc tells we do not need to recreate the audio
+ *       context to play a sound but only the audiosourcenode (createBufferSource)
+ *       in the webkit implementation we have to.
+ *
+ */
+
+var BufferLoader = require('cordova/plugin/tizen/BufferLoader');
+
+function SoundBeat(urlList) {
+    this.context = null;
+    this.urlList = urlList || null;
+    this.buffers = null;
+}
+
+/*
+ * This method play a loaded sounds on the Device
+ * @param {Number} times Number of times to play loaded sounds.
+ *
+ */
+SoundBeat.prototype.play = function(times) {
+
+    var i = 0, sources = [], that = this;
+
+    function finishedLoading (bufferList) {
+        that.buffers = bufferList;
+
+        for (i = 0; i < that.buffers.length ; i +=1) {
+            if (that.context) {
+                sources[i] = that.context.createBufferSource();
+
+                sources[i].buffer = that.buffers[i];
+                sources[i].connect (that.context.destination);
+
+                sources[i].loop = true;
+                sources[i].noteOn (0);
+                sources[i].noteOff(sources[i].buffer.duration * times);
+            }
+        }
+    }
+
+    if (webkitAudioContext !== null) {
+        this.context = new webkitAudioContext();
+    }
+    else {
+        console.log ("SoundBeat.prototype.play, w3c web audio api not supported");
+        this.context = null;
+    }
+
+    if (this.context === null) {
+        console.log ("SoundBeat.prototype.play, cannot create audio context object");
+        return;
+    }
+
+    this.bufferLoader = new BufferLoader (this.context, this.urlList, finishedLoading);
+    if (this.bufferLoader === null) {
+        console.log ("SoundBeat.prototype.play, cannot create buffer loader object");
+        return;
+    }
+
+    this.bufferLoader.load();
+};
+
+module.exports = SoundBeat;

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/contacts.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/contacts.js b/lib/tizen/plugin/tizen/contacts.js
new file mode 100644
index 0000000..59e2e52
--- /dev/null
+++ b/lib/tizen/plugin/tizen/contacts.js
@@ -0,0 +1,64 @@
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils');
+
+module.exports = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     *
+     * @return array of Contacts matching search criteria
+     */
+    find : function(fields, successCB, failCB, options) {
+
+        // Success callback is required. Throw exception if not specified.
+        if (typeof successCB !== 'function') {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+
+        // Search qualifier is required and cannot be empty.
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+            return;
+        }
+
+        // options are optional
+        var filter ="",
+            multiple = false,
+            contacts = [],
+            tizenFilter = null;
+
+        if (options) {
+            filter = options.filter || "";
+            multiple =  options.multiple || false;
+        }
+
+        if (filter){
+            tizenFilter = ContactUtils.buildFilterExpression(fields, filter);
+        }
+
+        tizen.contact.getDefaultAddressBook().find(
+            function(tizenContacts) {
+                if (multiple) {
+                    for (var index in tizenContacts) {
+                        contacts.push(ContactUtils.createContact(tizenContacts[index], fields));
+                    }
+                }
+                else {
+                    contacts.push(ContactUtils.createContact(tizenContacts[0], fields));
+                }
+
+                // return results
+                successCB(contacts);
+            },
+            function(error) {
+                if (typeof failCB === 'function') {
+                    failCB(ContactError.UNKNOWN_ERROR);
+                }
+            },
+            tizenFilter,
+            null);
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/b8fae990/lib/tizen/plugin/tizen/manager.js
----------------------------------------------------------------------
diff --git a/lib/tizen/plugin/tizen/manager.js b/lib/tizen/plugin/tizen/manager.js
new file mode 100644
index 0000000..b07dab2
--- /dev/null
+++ b/lib/tizen/plugin/tizen/manager.js
@@ -0,0 +1,17 @@
+var cordova = require('cordova');
+
+module.exports = {
+    exec: function (successCallback, errorCallback, clazz, action, args) {
+        var plugin = require('cordova/plugin/tizen/' + clazz);
+
+        if (plugin && typeof plugin[action] === 'function') {
+            var result = plugin[action](successCallback, errorCallback, args);
+            return result || {status: cordova.callbackStatus.NO_RESULT};
+        }
+
+        return {"status" : cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION, "message" : "Function " + clazz + "::" + action + " cannot be found"};
+    },
+    resume: function () {},
+    pause: function () {},
+    destroy: function () {}
+};