From cae84cbd1ed5306526e579a3e5b1e5961fba9bef Mon Sep 17 00:00:00 2001 From: Jason Hu Date: Thu, 8 Aug 2013 17:39:49 +0800 Subject: [PATCH] update to latest 2.2 release --- web/cache.manifest | 3 +- web/dbsamples/dbcontent.xml | 311 + web/ripple.css | 101 + web/ripple.html | 128 +- web/ripple.js | 31219 ++++++++++++++++++++++++++++++------------ 5 files changed, 22723 insertions(+), 9039 deletions(-) create mode 100644 web/dbsamples/dbcontent.xml diff --git a/web/cache.manifest b/web/cache.manifest index 1a1dddc..8d04437 100644 --- a/web/cache.manifest +++ b/web/cache.manifest @@ -5,6 +5,7 @@ CACHE: package.json beep.wav browserCheck.html +dbsamples/dbcontent.xml images/Colt-Landscape.png images/Colt.png images/NOTICE @@ -81,4 +82,4 @@ themes/light/images/ui-icons_454545_256x240.png themes/light/images/ui-icons_888888_256x240.png themes/light/images/ui-icons_cd0a0a_256x240.png themes/light/theme.css -# Manifest build date: Thu May 02 2013 14:48:30 GMT+0800 (CST) \ No newline at end of file +# Manifest build date: Mon Jul 15 2013 16:17:22 GMT+0800 (CST) \ No newline at end of file diff --git a/web/dbsamples/dbcontent.xml b/web/dbsamples/dbcontent.xml new file mode 100644 index 0000000..32647e2 --- /dev/null +++ b/web/dbsamples/dbcontent.xml @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + name + description + rating + geolocation + orientation + + 1553F420-4FFC-4B6E-AD86-A9DEB3625375 + seagull.gif + IMAGE + image/gif + Seagull + /opt/usr/media/Images/seagull.gif + + desktop/seagull.lnk + + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + 391168 + Natural Animation + 1 + + 800 + 600 + FLIP_HORIZONTAL + + + + + name + description + rating + geolocation + orientation + + 291C723B-7DFB-471F-8FF1-5E8A224BB7C5 + webapi-tizen-content-test_image.png + IMAGE + image/png + webapi-tizen-content-test_image + /opt/usr/media/webapi-tizen-content-tests/webapi-tizen-content-test_image.png + + desktop/webapi-tizen-content-test_image.lnk + + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + 116454 + 0 + + 320 + 240 + NORMAL + + + + + + E718584C-B72E-4E85-917B-DDDA95A18B0B + /opt/usr/media/Images/ + Images + INTERNAL + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + + + + 5BB9A98B-303F-4595-B507-01B7175BB90D + /opt/usr/media/Sounds/ + Sounds + INTERNAL + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + + + + F71CE175-3345-4BC9-9AAB-23335A1DCC6F + /opt/usr/media/Videos/ + Videos + INTERNAL + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + + + + 55CB28E5-CF6D-454F-B634-E4D94F0755F8 + /opt/usr/media/webapi-tizen-content-tests/ + Tests + INTERNAL + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + + + + EC3AD0ED-57DF-46AE-B95D-072FBE33D529 + /opt/storage/sdcard/Sounds/ + External Sounds + EXTERNAL + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + + + + 4E2B7B57-7090-4DFA-A7DA-8A77F747699A + /opt/storage/sdcard/Videos/ + External Videos + EXTERNAL + Tue Jun 04 2013 09:49:55 GMT+0800 (CST) + + + diff --git a/web/ripple.css b/web/ripple.css index 2c86d00..38eb440 100644 --- a/web/ripple.css +++ b/web/ripple.css @@ -2234,6 +2234,107 @@ textarea { border-bottom: #ccc 1px solid; padding:10px; } +/* Hardware Key ----------------------->*/ + +#hwkeys-panel { + width: 128px; + padding: 8px 3px 6px 3px; + position: absolute; + top: 580px; + left: 380px; + font-family: Arial, Helvetica, sans-serif; + background-color: #222222; + -moz-box-shadow: 0px 10px 15px #888888; /* Firefox 3.6 and earlier */ + box-shadow: 0px 10px 15px #888888; + -webkit-border-radius: 5px 5px 5px 5px; + -moz-border-radius: 5px 5px 5px 5px; + border-radius: 5px 5px 5px 5px; +} + +#hwkeys-container-div { + z-index: 0; + padding:0; + background-color: #222222; + border:1px solid #222222; + width:124px; + position: relative; +} + +.hwkeys-content-table { + width:124px; + font-size: 15px; + color: #555555; +} + +.hwkeys-content-table td{ + width:124px; + height: 40px; + padding-left: 0px; + border-width: 0; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select:none; +} + +.hwkeys-button:hover{ + cursor: pointer; + background-color:#444444; + background-image: -webkit-linear-gradient(top, #444444 41%, #222222 57%); + background-image: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0.41, #444444), + color-stop(0.57, #222222) + ); +} + +.hwkeys-button:active{ + cursor: pointer; + background-color:#666666; + background-image: -webkit-linear-gradient(top, #555555 41%, #333333 57%); + background-image: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0.41, #555555), + color-stop(0.57, #333333) + ); +} + +.hwkeys-title-div{ + font-size:14px; + font-weight:bold; + color: #dddddd; + width:120px; + height:30px; + text-align:center; + vertical-align: middle; + display: table-cell; + border-top-left-radius:0.8em; + border-top-right-radius:0.8em; +} + +.hwkeys-button { + color: #dddddd; + background-color: #222222; + font-size: 15px; + padding: 7px; + width: 119px; + height: 36px; + border:1px solid #a1a1a1; + -moz-border-radius: 5px 5px 5px 5px; + -webkit-border-radius: 5px 5px 5px 5px; + background-image: -webkit-linear-gradient(top, #333333 41%, #111111 57%); + background-image: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0.41, #333333), + color-stop(0.57, #111111) + ); +} /* * Copyright 2011 Research In Motion Limited. * diff --git a/web/ripple.html b/web/ripple.html index dc9afaf..2ff7a63 100644 --- a/web/ripple.html +++ b/web/ripple.html @@ -61,7 +61,7 @@
- +
Visible Panel
Visible Panels
@@ -367,6 +367,38 @@
+ +
+
+ + + +
+
Hardware Keys
+
+ + + +
+
+
+
+ +
-
Version: 2.1.0
-
May 2, 2013
+
Version: 2.2.0
+
July 15, 2013

Based on the Ripple Mobile Emulator
Copyright 2013 Intel Corporation. All rights reserved diff --git a/web/ripple.js b/web/ripple.js index 2a6a7a5..8d577dd 100644 --- a/web/ripple.js +++ b/web/ripple.js @@ -1,5 +1,5 @@ /*! - Ripple Mobile Environment Emulator v0.9.8 :: Built On Thu May 02 2013 14:48:30 GMT+0800 (CST) + Ripple Mobile Environment Emulator v0.9.8 :: Built On Mon Jul 15 2013 16:17:21 GMT+0800 (CST) Apache License Version 2.0, January 2004 @@ -61773,353 +61773,1350 @@ options.subPaths.shift();this.writeNode("_Layer",options,node);return node;}else if(layer.options.maxScale){this.writeNode("sld:MinScaleDenominator",layer.options.maxScale,node);} if(layer.options.minScale){this.writeNode("sld:MaxScaleDenominator",layer.options.minScale,node);} this.nestingLayerLookup[layer.name]=node;return node;}},"_WFS":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:layer.protocol.featurePrefix+":"+layer.protocol.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WFS,version:layer.protocol.version,url:layer.protocol.url},node);return node;},"_InlineGeometry":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:this.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("InlineGeometry",layer,node);return node;},"_GML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.GML,url:layer.protocol.url,version:layer.protocol.format.version},node);return node;},"_KML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.KML,version:layer.protocol.format.version,url:layer.protocol.url},node);return node;}},"gml":OpenLayers.Util.applyDefaults({"boundedBy":function(bounds){var node=this.createElementNSPlus("gml:boundedBy");this.writeNode("gml:Box",bounds,node);return node;}},OpenLayers.Format.GML.v2.prototype.writers.gml),"ows":OpenLayers.Format.OWSCommon.v1_0_0.prototype.writers.ows,"sld":OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld,"feature":OpenLayers.Format.GML.v2.prototype.writers.feature},CLASS_NAME:"OpenLayers.Format.OWSContext.v0_3_1"}); -define.unordered = true;define('ripple/accelerometer', function (require, exports, module) { -/* - * Copyright 2011 Research In Motion Limited. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var _self, - utils = require('ripple/utils'), - exception = require('ripple/exception'), - event = require('ripple/event'), - Rotation = require('ripple/platform/w3c/1.0/Rotation'), - Acceleration = require('ripple/platform/w3c/1.0/Acceleration'), - _motion = { - acceleration: new Acceleration(0, 0, 0), - accelerationIncludingGravity: new Acceleration(0, 0, -9.81), - rotationRate: new Rotation(0, 0, 0), - orientation: new Rotation(0, 0, 0), - interval: 60000, - timestamp: new Date().getTime() +(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.indexi;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);/*global setImmediate: false, setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root, previous_async; + + root = this; + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; }; -function _validateAccelerometerInfo(x, y, z) { - return !(isNaN(x) || isNaN(y) || isNaN(z)); -} + function only_once(fn) { + var called = false; + return function() { + if (called) throw new Error("Callback was already called."); + called = true; + fn.apply(root, arguments); + } + } -_self = { - getInfo: function () { - return utils.copy(_motion); - }, + //// cross-browser compatiblity functions //// - setInfo: function (e) { - var triggerDeviceMotion = false, - triggerDeviceOrientation = false; + var _each = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; - if (e.x !== undefined && e.y !== undefined && e.z !== undefined) { - _motion = { - acceleration: new Acceleration(e.x, e.y, e.z), - accelerationIncludingGravity: new Acceleration(e.x, e.y, e.z), - rotationRate: new Rotation(0, 0, 0), - orientation: new Rotation(e.alpha, e.beta, e.gamma), - timestamp: new Date().getTime() + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _each(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _each(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + if (typeof setImmediate === 'function') { + async.nextTick = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); }; - triggerDeviceMotion = true; - triggerDeviceOrientation = true; + async.setImmediate = async.nextTick; } else { - _motion = { - acceleration: new Acceleration(0, 0, 0), - accelerationIncludingGravity: new Acceleration(0, 0, -9.81), - rotationRate: new Rotation(0, 0, 0), - orientation: new Rotation(0, 0, 0), - timestamp: new Date().getTime() + async.nextTick = function (fn) { + setTimeout(fn, 0); }; + async.setImmediate = async.nextTick; + } + } + else { + async.nextTick = process.nextTick; + if (typeof setImmediate !== 'undefined') { + async.setImmediate = setImmediate; + } + else { + async.setImmediate = async.nextTick; } + } - if (triggerDeviceMotion) { - event.trigger("DeviceMotionEvent", [_motion]); + async.each = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); } + var completed = 0; + _each(arr, function (x) { + iterator(x, only_once(function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + } + })); + }); + }; + async.forEach = async.each; - if (triggerDeviceOrientation) { - event.trigger("DeviceOrientationEvent", [_motion]); + async.eachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(null); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + async.forEachSeries = async.eachSeries; - event.trigger("AccelerometerInfoChangedEvent", [_motion]); - }, + async.eachLimit = function (arr, limit, iterator, callback) { + var fn = _eachLimit(limit); + fn.apply(null, [arr, iterator, callback]); + }; + async.forEachLimit = async.eachLimit; - shake: function (shakeXtimes) { - var id, - count = 1, - stopCount = shakeXtimes || 17, - oldX = _motion.accelerationIncludingGravity.x; + var _eachLimit = function (limit) { + return function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; - id = setInterval(function () { - var freq = 1, - amp = 30, - value = Math.round(amp * Math.sin(freq * count * (180 / Math.PI)) * 100) / 100; + (function replenish () { + if (completed >= arr.length) { + return callback(); + } - if (count > stopCount) { - _motion.acceleration.x = oldX; - _motion.accelerationIncludingGravity.x = oldX; - event.trigger("AccelerometerInfoChangedEvent", [_motion]); - clearInterval(id); - return; - } + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed >= arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + }; - _motion.acceleration.x = value; - _motion.accelerationIncludingGravity.x = value; - event.trigger("AccelerometerInfoChangedEvent", [_motion]); + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.each].concat(args)); + }; + }; + var doParallelLimit = function(limit, fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [_eachLimit(limit)].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.eachSeries].concat(args)); + }; + }; - count++; - }, 80); + var _asyncMap = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = function (arr, limit, iterator, callback) { + return _mapLimit(limit)(arr, iterator, callback); + }; - } -}; + var _mapLimit = function(limit) { + return doParallelLimit(limit, _asyncMap); + }; -module.exports = _self; + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.eachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; -}); -define('ripple/app', function (require, exports, module) { -/* - * Copyright 2011 Research In Motion Limited. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var _data = {}, - utils = require('ripple/utils'), - _self; + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; -_self = { - setInfo: function (info) { - if (!info) { - _data = {}; - } - _data = info; - }, + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; - getInfo: function () { - return utils.copy(_data); - }, + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); - isPreferenceReadOnly: function (key) { - return (_data.preferences && - _data.preferences[key] && - _data.preferences[key].readonly && - _data.preferences[key].readonly === true); - }, + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); - validateVersion: function (configValidationObject) { - // TODO: WTF figure this out, platform is empty object when require at require time - // could be that the new platform _getBuilder code dies when called, beforre it is initialized - var spec = require('ripple/platform').current(); - if (typeof spec.config.validateVersion === "function" && configValidationObject) { - return spec.config.validateVersion(configValidationObject); - } + async.some = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; - return true; - }, + async.every = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; - saveInfo: function (configValidationObject) { - var spec = require('ripple/platform').current(), - info = null; - if (typeof spec.config.extractInfo === "function") { - info = spec.config.extractInfo(configValidationObject); - } + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; - if (info) { - _self.setInfo(info); + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + if (!keys.length) { + return callback(null); } - } -}; - -module.exports = _self; + var results = {}; -}); -define('ripple/appcache', function (require, exports, module) { -/* - * Copyright 2011 Research In Motion Limited. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -module.exports = { - initialize: function () { - window.addEventListener('load', function (e) { - window.applicationCache.addEventListener('updateready', function (e) { - if (window.applicationCache.status === window.applicationCache.UPDATEREADY) { - window.applicationCache.swapCache(); - window.location.reload(); + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; } - }, false); - }, false); - } -}; - -}); -define('ripple/bootstrap', function (require, exports, module) { -/* - * Copyright 2011 Research In Motion Limited. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var _bound, - _console = require('ripple/console'), - ui = require('ripple/ui'), - db = require('ripple/db'), - _CURRENT_URL = "current-url"; - -function _bindObjects(win, doc) { - if (!win.tinyHippos) { - require('ripple/emulatorBridge').link(win, doc); - /// require('ripple/platform/tizen/2.0/touchEvent').mask(win, doc); - require('ripple/touchEventEmulator').mask(win, doc); - require('ripple/documentEventListener').mask(win, doc); - require('ripple/deviceMotionEmulator').init(win, doc); - require('ripple/resizer').init(win, doc); - _bound = true; - } -} + } + }; + var taskComplete = function () { + _each(listeners.slice(0), function (fn) { + fn(); + }); + }; -function _createFrame(src) { - var frame = document.createElement("iframe"); - frame.setAttribute("id", "document"); - frame.src = src; + addListener(function () { + if (_keys(results).length === keys.length) { + callback(null, results); + callback = function () {}; + } + }); - if (ui.registered("omnibar")) { - frame.addEventListener("beforeload", function () { - _bound = false; - _bindObjects(frame.contentWindow, frame.contentDocument); - var id = window.setInterval(function () { - if (_bound) { - window.clearInterval(id); - } else { - _bindObjects(frame.contentWindow, frame.contentDocument); + _each(keys, function (k) { + var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; + var taskCallback = function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _each(_keys(results), function(rkey) { + safeResults[rkey] = results[rkey]; + }); + safeResults[k] = args; + callback(err, safeResults); + // stop subsequent errors hitting callback multiple times + callback = function () {}; } - }, 1); + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } }); - } - - return frame; -} + }; -function _cleanBody() { - require('ripple/utils').forEach(document.body.children, function (child) { - if (child && child.id && !child.id.match(/ui|tooltip|bus/)) { - document.body.removeChild(child); + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor !== Array) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); } + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback.apply(null, arguments); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.setImmediate(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + var _parallel = function(eachfn, tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + eachfn.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + eachfn.each(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; - document.body.removeAttribute("style"); - document.body.removeAttribute("id"); - document.body.removeAttribute("class"); - }); -} - -function _post(src) { - var event = require('ripple/event'), - frame = _createFrame(src); + async.parallel = function (tasks, callback) { + _parallel({ map: async.map, each: async.each }, tasks, callback); + }; - _console.log("Initialization Finished (Make it so.)"); + async.parallelLimit = function(tasks, limit, callback) { + _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + }; - frame.onload = function () { - var bootLoader = document.querySelector("#emulator-booting"), - id; - if (bootLoader) { - document.querySelector("#ui").removeChild(bootLoader); + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (tasks.constructor === Array) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.eachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); } + }; - event.trigger("TinyHipposLoaded"); + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; - _cleanBody(); - id = window.setInterval(_cleanBody, 20); + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; - window.setTimeout(function () { - window.clearInterval(id); - }, 1200); + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); - if (ui.registered("omnibar")) { - //reset the onload function so that when navigating we can destroy - //the iframe and create a new one so we can reinject the platform by - //calling post again. - frame.onload = function () { - var url = frame.contentWindow.location.href; - document.getElementById("viewport-container").removeChild(frame); - event.trigger("FrameHistoryChange", [url]); - _console.log("-----------------------------------------------------------"); - _console.log("Pay no attention to that man behind the curtain."); - _console.log("Environment Warning up again (Set main batteries to auto-fire cycle)"); - _post(url); - }; + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); } }; - // append frame - document.getElementById("viewport-container").appendChild(frame); + async.doWhilst = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (test()) { + async.doWhilst(iterator, test, callback); + } + else { + callback(); + } + }); + }; - delete tinyHippos.boot; -} + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; -function _bootstrap() { - // TODO: figure this out for web and ext - //_console.log("-----------------------------------------------------------"); - //_console.log("There be dragons above here!"); - _console.log("Web Simulator :: Environment Warming Up (Tea. Earl Gray. Hot.)"); + async.doUntil = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + if (!test()) { + async.doUntil(iterator, test, callback); + } + else { + callback(); + } + }); + }; - window.tinyHippos = require('ripple'); + async.queue = function (worker, concurrency) { + if (concurrency === undefined) { + concurrency = 1; + } + function _insert(q, data, pos, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + var item = { + data: task, + callback: typeof callback === 'function' ? callback : null + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } - tinyHippos.boot(function () { - var uri = ui.registered('omnibar') ? - db.retrieve(_CURRENT_URL) || "about:blank" : - document.documentURI.replace(/enableripple=[^&]*[&]?/i, "").replace(/[\?&]*$/, ""); + if (q.saturated && q.tasks.length === concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + if (workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if (q.empty && q.tasks.length === 0) { + q.empty(); + } + workers += 1; + var next = function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if (q.drain && q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + var cb = only_once(next); + worker(task.data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + } + }; + return q; + }; + + async.cargo = function (worker, payload) { + var working = false, + tasks = []; + + var cargo = { + tasks: tasks, + payload: payload, + saturated: null, + empty: null, + drain: null, + push: function (data, callback) { + if(data.constructor !== Array) { + data = [data]; + } + _each(data, function(task) { + tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + if (cargo.saturated && tasks.length === payload) { + cargo.saturated(); + } + }); + async.setImmediate(cargo.process); + }, + process: function process() { + if (working) return; + if (tasks.length === 0) { + if(cargo.drain) cargo.drain(); + return; + } - _post(uri); - delete tinyHippos.boot; - }); -} + var ts = typeof payload === 'number' + ? tasks.splice(0, payload) + : tasks.splice(0); -module.exports = { - bootstrap: _bootstrap, - inject: function (frameWindow, frameDocument) { - _bindObjects(frameWindow, frameDocument); + var ds = _map(ts, function (task) { + return task.data; + }); + + if(cargo.empty) cargo.empty(); + working = true; + worker(ds, function () { + working = false; + + var args = arguments; + _each(ts, function (data) { + if (data.callback) { + data.callback.apply(null, args); + } + }); + + process(); + }); + }, + length: function () { + return tasks.length; + }, + running: function () { + return working; + } + }; + return cargo; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _each(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + callback.apply(null, memo[key]); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + async.times = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.map(counter, iterator, callback); + }; + + async.timesSeries = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.mapSeries(counter, iterator, callback); + }; + + async.compose = function (/* functions... */) { + var fns = Array.prototype.reverse.call(arguments); + return function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([function () { + var err = arguments[0]; + var nextargs = Array.prototype.slice.call(arguments, 1); + cb(err, nextargs); + }])) + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }; + }; + + var _applyEach = function (eachfn, fns /*args...*/) { + var go = function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + return eachfn(fns, function (fn, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }; + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + return go.apply(this, args); + } + else { + return go; + } + }; + async.applyEach = doParallel(_applyEach); + async.applyEachSeries = doSeries(_applyEach); + + async.forever = function (fn, callback) { + function next(err) { + if (err) { + if (callback) { + return callback(err); + } + throw err; + } + fn(next); + } + next(); + }; + + root.async = async; + +}()); +(function() { + + var redblack = {}; + var root = this; + var orig = root.redblack; + + if (typeof module !== 'undefined' && module.exports) { + module.exports = redblack; + } else { + root.redblack = redblack; } -}; -}); -define('ripple/bus', function (require, exports, module) { + redblack.VERSION = '0.1.2'; + + redblack.noConflict = function() { + root.redblack = orig; + return redblack; + }; + + redblack.tree = function() { + return new Tree(); + }; + + var BLACK = redblack.BLACK = 'black'; + var RED = redblack.RED = 'red'; + + // Node + // --------------- + + function Node(key, value) { + this.key = key; + this.value = value; + this.color = RED; + this.left = null; + this.right = null; + this.parent = null; + }; + + Node.prototype.grandparent = function() { + if (this.parent === null) return null; + return this.parent.parent; + }; + + Node.prototype.sibling = function() { + if (this.parent === null) return null; + return this === this.parent.left ? this.parent.right : this.parent.left; + }; + + Node.prototype.uncle = function() { + if (this.parent === null) return null; + return this.parent.sibling(); + }; + + // Cursor + // --------------- + + function Cursor(tree, start, end) { + this.tree = tree; + this.start = start; + this.end = end; + + var self = this; + this.walk = function walk(node, iterator) { + if (node === null) return; + + if (start !== undefined && node.key < start) { + walk(node.right, iterator); + } else if (end !== undefined && node.key > end) { + walk(node.left, iterator); + } else { + walk(node.left, iterator); + iterator(node.value, node.key, self.tree); + walk(node.right, iterator); + } + }; + }; + + Cursor.prototype.forEach = function(iterator) { + this.walk(this.tree.root, iterator); + }; + + Cursor.prototype.map = function(iterator) { + var results = []; + + this.forEach(function(value, key, tree) { + results.push(iterator(value, key, tree)); + }); + + return results; + }; + + // Tree + // --------------- + + function Tree() { + this.root = null; + this.balancer = new Balancer(this); + }; + + Tree.prototype.get = function(key) { + var node = find(this.root, key); + return node === null ? null : node.value; + }; + + Tree.prototype.insert = function(key, value) { + var newNode = new Node(key, value); + + if (this.root === null) { + this.root = newNode; + } else { + var node = this.root; + + while (true) { + if (key < node.key) { + if (node.left === null) { + node.left = newNode; + break; + } else { + node = node.left; + } + } else if (key > node.key) { + if (node.right === null) { + node.right = newNode; + break; + } else { + node = node.right; + } + } else { + node.value = value; + return; + } + } + + newNode.parent = node; + } + + this.balancer.inserted(newNode); + }; + + Tree.prototype.delete = function(key) { + var node = find(this.root, key); + if (node === null) return; + + if (node.left !== null && node.right !== null) { + var pred = node.left; + while (pred.right !== null) pred = pred.right; + + node.key = pred.key; + node.value = pred.value; + node = pred; + } + + var child = (node.right === null) ? node.left : node.right; + if (nodeColor(node) === BLACK) { + node.color = nodeColor(child); + this.balancer.deleted(node); + } + + this.balancer.replaceNode(node, child); + + if (nodeColor(this.root) === RED) { + this.root.color = BLACK; + } + }; + + Tree.prototype.range = function(start, end) { + return new Cursor(this, start, end); + }; + + // Proxy cursor methods + for (var method in Cursor.prototype) { + if (Cursor.prototype.hasOwnProperty(method)) { + var func = Cursor.prototype[method]; + Tree.prototype[method] = function() { + var cursor = new Cursor(this); + return func.apply(cursor, arguments); + }; + } + } + + // Balancer + // --------------- + + function Balancer(tree) { + this.tree = tree; + }; + + Balancer.prototype.inserted = function(node) { + this.insertCase1(node); + }; + + Balancer.prototype.deleted = function(node) { + this.deleteCase1(node); + }; + + Balancer.prototype.replaceNode = function(original, replacement) { + if (original.parent === null) { + this.tree.root = replacement; + } else { + if (original === original.parent.left) { + original.parent.left = replacement; + } else { + original.parent.right = replacement; + } + } + + if (replacement !== null) { + replacement.parent = original.parent; + } + }; + + Balancer.prototype.rotateLeft = function(node) { + var right = node.right; + this.replaceNode(node, right); + + // Update pointers + node.right = right.left; + if (right.left !== null) right.left.parent = node; + right.left = node; + node.parent = right; + }; + + Balancer.prototype.rotateRight = function(node) { + var left = node.left; + this.replaceNode(node, left); + + // Update pointers + node.left = left.right; + if (left.right !== null) left.right.parent = node; + left.right = node; + node.parent = left; + }; + + Balancer.prototype.insertCase1 = function(node) { + if (node.parent === null) { + node.color = BLACK; + } else { + this.insertCase2(node); + } + }; + + Balancer.prototype.insertCase2 = function(node) { + if (nodeColor(node.parent) === BLACK) { + return; + } else { + this.insertCase3(node); + } + }; + + Balancer.prototype.insertCase3 = function(node) { + var uncle = node.uncle(); + var grandparent = node.grandparent(); + + if (uncle !== null && nodeColor(uncle) === RED) { + node.parent.color = BLACK; + uncle.color = BLACK; + grandparent.color = RED; + this.insertCase1(grandparent); + } else { + this.insertCase4(node); + } + }; + + Balancer.prototype.insertCase4 = function(node) { + var grandparent = node.grandparent(); + + if (node === node.parent.right && node.parent === grandparent.left) { + this.rotateLeft(node.parent); + node = node.left; + } else if (node === node.parent.left && node.parent === grandparent.right) { + this.rotateRight(node.parent); + node = node.right; + } + + this.insertCase5(node); + }; + + Balancer.prototype.insertCase5 = function(node) { + var grandparent = node.grandparent(); + + node.parent.color = BLACK; + grandparent.color = RED; + + if (node === node.parent.left && node.parent === grandparent.left) { + this.rotateRight(grandparent); + } else if (node === node.parent.right && node.parent === grandparent.right) { + this.rotateLeft(grandparent); + } + }; + + Balancer.prototype.deleteCase1 = function(node) { + if (node.parent !== null) this.deleteCase2(node); + }; + + Balancer.prototype.deleteCase2 = function(node) { + var sibling = node.sibling(); + + if (nodeColor(sibling) === RED) { + node.parent.color = RED; + sibling.color = BLACK; + if (node === node.parent.left) { + this.rotateLeft(node.parent); + } else { + this.rotateRight(node.parent); + } + } + + this.deleteCase3(node); + }; + + Balancer.prototype.deleteCase3 = function(node) { + var sibling = node.sibling(); + + if (nodeColor(node.parent) === BLACK && + nodeColor(sibling) === BLACK && + nodeColor(sibling.left) === BLACK && + nodeColor(sibling.right) === BLACK) { + + sibling.color = RED; + this.deleteCase1(node.parent); + } else { + this.deleteCase4(node); + } + }; + + Balancer.prototype.deleteCase4 = function(node) { + var sibling = node.sibling(); + + if (nodeColor(node.parent) === RED && + nodeColor(sibling) === BLACK && + nodeColor(sibling.left) === BLACK && + nodeColor(sibling.right) === BLACK) { + + sibling.color = RED; + node.parent.color = BLACK; + } else { + this.deleteCase5(node); + } + }; + + Balancer.prototype.deleteCase5 = function(node) { + var sibling = node.sibling(); + + if (node === node.parent.left && + nodeColor(sibling) === BLACK && + nodeColor(sibling.left) === RED && + nodeColor(sibling.right) === BLACK) { + + sibling.color = RED; + sibling.left.color = BLACK; + this.rotateRight(sibling); + } else if (node === node.parent.right && + nodeColor(sibling) === BLACK && + nodeColor(sibling.right) === RED && + nodeColor(sibling.left) === BLACK) { + + sibling.color = RED; + sibling.right.color = BLACK; + this.rotateLeft(sibling); + } + + this.deleteCase6(node); + }; + + Balancer.prototype.deleteCase6 = function(node) { + var sibling = node.sibling(); + + sibling.color = nodeColor(node.parent); + node.parent.color = BLACK; + + if (node === node.parent.left) { + sibling.right.color = BLACK; + this.rotateLeft(node.parent); + } else { + sibling.left.color = BLACK; + this.rotateRight(node.parent); + } + }; + + // Helpers + // --------------- + + function nodeColor(node) { + return node === null ? BLACK : node.color; + }; + + function find(node, key) { + while (node !== null) { + if (key === node.key) { + return node; + } else if (key < node.key) { + node = node.left; + } else if (key > node.key) { + node = node.right; + } + } + + return node; + }; + +})(); +define.unordered = true;define('ripple/accelerometer', function (require, exports, module) { /* * Copyright 2011 Research In Motion Limited. * @@ -62135,58 +63132,115 @@ define('ripple/bus', function (require, exports, module) { * See the License for the specific language governing permissions and * limitations under the License. */ +var _self, + utils = require('ripple/utils'), + exception = require('ripple/exception'), + event = require('ripple/event'), + Rotation = require('ripple/platform/w3c/1.0/Rotation'), + Acceleration = require('ripple/platform/w3c/1.0/Acceleration'), + _motion = { + acceleration: new Acceleration(0, 0, 0), + accelerationIncludingGravity: new Acceleration(0, 0, -9.81), + rotationRate: new Rotation(0, 0, 0), + orientation: new Rotation(0, 0, 0), + interval: 60000, + timestamp: new Date().getTime() + }; -var _send = document.getElementById("bus-send"), - _receive = document.getElementById("bus-receive"), - _evt = document.createEvent("Events"); +function _validateAccelerometerInfo(x, y, z) { + return !(isNaN(x) || isNaN(y) || isNaN(z)); +} -_evt.initEvent('bus-init', true, true); -document.dispatchEvent(_evt); +_self = { + getInfo: function () { + return utils.copy(_motion); + }, -module.exports = { - send: function (msg, data, callback) { - var m = document.createElement("span"); - m.dataset.msg = msg; - m.innerHTML = JSON.stringify(data); + setInfo: function (e) { + var triggerDeviceMotion = false, + triggerDeviceOrientation = false; - if (callback) { - m.dataset.callback = Math.uuid(); - this.receive(m.dataset.callback, callback); + if (e.x !== undefined && e.y !== undefined && e.z !== undefined) { + _motion = { + acceleration: new Acceleration(e.x, e.y, e.z), + accelerationIncludingGravity: new Acceleration(e.x, e.y, e.z), + rotationRate: new Rotation(0, 0, 0), + orientation: new Rotation(e.alpha, e.beta, e.gamma), + timestamp: new Date().getTime() + }; + triggerDeviceMotion = true; + triggerDeviceOrientation = true; + } + else { + _motion = { + acceleration: new Acceleration(0, 0, 0), + accelerationIncludingGravity: new Acceleration(0, 0, -9.81), + rotationRate: new Rotation(0, 0, 0), + orientation: new Rotation(0, 0, 0), + timestamp: new Date().getTime() + }; } - _send.appendChild(m); - }, + if (triggerDeviceMotion) { + event.trigger("DeviceMotionEvent", [_motion]); + } - receive: function (msg, handler) { - if (!handler) { - return; + if (triggerDeviceOrientation) { + event.trigger("DeviceOrientationEvent", [_motion]); } - _receive.addEventListener("DOMNodeInserted", function (evt) { - if (evt.target.dataset.msg === msg) { - handler(JSON.parse(evt.target.innerHTML)); - } - }); + event.trigger("AccelerometerInfoChangedEvent", [_motion]); }, - ajax: function (method, url, data, success, fail) { - this.send("xhr", { - method: method, - url: url, - data: data - }, function (result) { - if (result.code === 200) { - success(result.data); - } - else { - fail(result); + triggerEvent: function() { + event.trigger("DeviceMotionEvent", [_motion]); + event.trigger("DeviceOrientationEvent", [_motion]); + event.trigger("AccelerometerInfoChangedEvent", [_motion]); + }, + + shake: function (shakeXtimes) { + var id, + count = 1, + stopCount = shakeXtimes || 17, + oldX = _motion.accelerationIncludingGravity.x; + + id = setInterval(function () { + var freq = 1, + amp = 30, + value = Math.round(amp * Math.sin(freq * count * (180 / Math.PI)) * 100) / 100; + + if (count > stopCount) { + _motion.acceleration.x = oldX; + _motion.accelerationIncludingGravity.x = oldX; + event.trigger("AccelerometerInfoChangedEvent", [_motion]); + clearInterval(id); + return; } + + _motion.acceleration.x = value; + _motion.accelerationIncludingGravity.x = value; + + event.trigger("AccelerometerInfoChangedEvent", [_motion]); + + count++; + + }, 80); + }, + + init: function () { + event.on("DeviceMotionEventAddedEvent", function () { + _self.triggerEvent(); + }); + event.on("DeviceOrientationEventAddedEvent", function () { + _self.triggerEvent(); }); } }; +module.exports = _self; + }); -define('ripple/console', function (require, exports, module) { +define('ripple/app', function (require, exports, module) { /* * Copyright 2011 Research In Motion Limited. * @@ -62202,34 +63256,58 @@ define('ripple/console', function (require, exports, module) { * See the License for the specific language governing permissions and * limitations under the License. */ -var _self; - -function _log(msg, method) { - try { - console[method](_self.prefix ? _self.prefix + " :: " + msg : msg); - } catch (e) { - // silent - } -} +var _data = {}, + utils = require('ripple/utils'), + _self; _self = { - log: function (msg) { - _log(msg, "log"); + setInfo: function (info) { + if (!info) { + _data = {}; + } + _data = info; }, - warn: function (msg) { - _log(msg, "warn"); + getInfo: function () { + return utils.copy(_data); }, - error: function (msg) { - _log(msg, "error"); + isPreferenceReadOnly: function (key) { + return (_data.preferences && + _data.preferences[key] && + _data.preferences[key].readonly && + _data.preferences[key].readonly === true); + }, + + validateVersion: function (configValidationObject) { + // TODO: WTF figure this out, platform is empty object when require at require time + // could be that the new platform _getBuilder code dies when called, beforre it is initialized + var spec = require('ripple/platform').current(); + if (typeof spec.config.validateVersion === "function" && configValidationObject) { + return spec.config.validateVersion(configValidationObject); + } + + return true; + }, + + saveInfo: function (configValidationObject) { + var spec = require('ripple/platform').current(), + info = null; + if (typeof spec.config.extractInfo === "function") { + info = spec.config.extractInfo(configValidationObject); + } + + if (info) { + _self.setInfo(info); + } } + }; module.exports = _self; }); -define('ripple/constants', function (require, exports, module) { +define('ripple/appcache', function (require, exports, module) { /* * Copyright 2011 Research In Motion Limited. * @@ -62246,66 +63324,488 @@ define('ripple/constants', function (require, exports, module) { * limitations under the License. */ module.exports = { - "API_URL": "http://api.tinyhippos.com", + initialize: function () { + window.addEventListener('load', function (e) { + window.applicationCache.addEventListener('updateready', function (e) { + if (window.applicationCache.status === window.applicationCache.UPDATEREADY) { + window.applicationCache.swapCache(); + window.location.reload(); + } + }, false); + }, false); + } +}; - "RELEASE_VERSION": "simulator-release-version", +}); +define('ripple/bootstrap', function (require, exports, module) { +/* + * Copyright 2011 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var _bound, + _console = require('ripple/console'), + utils = require('ripple/utils'), + ui = require('ripple/ui'), + db = require('ripple/db'), + _CURRENT_URL = "current-url", + resizer = require('ripple/resizer'), + platform = require('ripple/platform'); - "SERVICES": { - "GOOGLE_MAPS_URI": "http://maps.google.com/maps/api/staticmap?size=476x476&maptype=roadmap", - "GOOGLE_MAPS_API_KEY": "ABQIAAAA-CaPZHXR-0Tzhui_h6gpjhSE_2rGlnYiB7L-ZGVwgaut5s7OYRSlBAaHCzBuZf2_23_vrCOfPxXHjA" - }, +var _srcChangedObserver = new WebKitMutationObserver(function (mutations) { + utils.forEach(mutations, function (mutation) { + _bindObjectsToFrame(mutation.target); + }); + }); - "FS_SIZE": 1024 * 1024 * 10, +function _observeIframeAdded(doc) { + doc._iframeAddedObserver.observe(doc, {childList: true, subtree: true}); +} - "COMMON": { - "APPLICATION_STATE": "ui-application-state-", - "PREFIX": "tinyhippos-", - "DEVICE_CONTAINER" : "device-container", - "MENU_BUTTON" : "menu-button", - "BACK_BUTTON" : "back-button", - "HTML_CONTAINER" : "document", - "INFO_SECTION": "information-sub-container", - "ORIENTATION_SELECT_PORTRAIT_ID" : "layout-portrait", - "ORIENTATION_SELECT_LANDSCAPE_ID" : "layout-landscape", - "PLATFORM_SELECT_ID": "platform-select", - "DEVICE_SELECT_ID": "device-select", - "STORAGE_TABLE_BODY_CLASS": "preferences-list-body", - "STORAGE_COUNT_CONTAINER_ID": "preferences-count", - "GEO_MAP_CONTAINER_ID": "geo-map", - "FILESYSTEM_UPDATE_BUTTON_ID_WITH_HASH": "#update-filesystem-button", - "USER_AGENT_DEFAULT": "default", - "APPLICATIONS_CONTAINER_ID": "widget-applications-content", - "STORAGE_CLEAR_BUTTON_ID": "preferences-clear-button", - "AJAX_LOADER_CONTAINER_CLASS": ".loader", - "IRRELEVANT_CLASS": "irrelevant", - "MULTIMEDIA_VOLUME_SLIDER_ID": "media-volume", - "MULTIMEDIA_VOLUME_FIELD_ID": "media-volume-value", - "MULTIMEDIA_AUDIO_STATE_FIELD_ID": "media-audio-state", - "MULTIMEDIA_AUDIO_PLAYING_FIELD_ID": "multimedia-isaudioplaying", - "MULTIMEDIA_AUDIO_PROGRESS_ID": "media-audio-progress", - "MULTIMEDIA_AUDIO_FILE_FIELD_ID": "media-audio-file", - "MULTIMEDIA_VIDEO_STATE_FIELD_ID": "media-video-state", - "MULTIMEDIA_VIDEO_PLAYING_FIELD_ID": "multimedia-isvideoplaying", - "MULTIMEDIA_VIDEO_PROGRESS_ID": "media-video-progress", - "MULTIMEDIA_VIDEO_FILE_FIELD_ID": "media-video-file", - "EXTENSION_URL_CONTAINER": "extension-url", - "SECURITY_LEVEL": "security-level" - }, - "LAUNCHING_HISTORY": "application-launching-history", +function _bindObjects(win, doc) { + if (!win.tinyHippos) { + require('ripple/emulatorBridge').link(win, doc); + /// require('ripple/platform/tizen/2.0/touchEvent').mask(win, doc); + require('ripple/touchEventEmulator').mask(win, doc); + require('ripple/hwKeyEmulator').init(win, doc); + require('ripple/documentEventListener').mask(win, doc); + require('ripple/deviceMotionEmulator').init(win, doc); + require('ripple/resizer').init(win, doc); + win.addEventListener("DOMContentLoaded", function () { + var iframes = $(this.document).find("iframe"); + // Observe iframe added event so that we can bind objects to newly added iframes + if (!this.document._iframeAddedObserver) { + this.document._iframeAddedObserver = new WebKitMutationObserver(function (mutations) { + utils.forEach(mutations, function (mutation) { + for (var i in mutation.addedNodes) { + var node = mutation.addedNodes[i]; + if (node.tagName && (node.tagName.toUpperCase() === "IFRAME")) { + _bindObjectsToFrame(node); + } + } + }); + }); + _observeIframeAdded(this.document); + } + iframes.each(function () { + _bindObjectsToFrame(this); + }); - "FILESYSTEM": { - "PERSISTENCE_KEY": "filesystem", - "INPUT_PREFIX_ID": "#panel-filesystem-" - }, + }); + win.frameElement._bound = true; + } +} - "PLATFORM": { - "DEFAULT": { - "name": "tizen", - "version": "1.0" +function _beforeLoad() { + this._bound = false; + _bindObjects(this.contentWindow, this.contentDocument); + this._intervalId = window.setInterval(function () { + if (this._bound) { + window.clearInterval(this._intervalId); + } else { + _bindObjects(this.contentWindow, this.contentDocument); + } + }.bind(this), 1); +} + +function _bindObjectsToFrame(frame) { + _srcChangedObserver.observe(frame, {attributes: true, attributeFilter: ["src"]}); + frame.addEventListener("beforeload", _beforeLoad); + // beforeload event of an iframe will not be triggered unless we detach and + // then attach the iframe to the dom tree + var parentNode = frame.parentNode; + var nextNode = frame.nextNode; + if (parentNode) { + // Disable iframe added observer to avoid infinite loop of binding objects + if (frame.ownerDocument && frame.ownerDocument._iframeAddedObserver) { + frame.ownerDocument._iframeAddedObserver.disconnect(); + } + parentNode.removeChild(frame); + if (nextNode) + nextNode.insertBefore(frame); + else + parentNode.appendChild(frame); + + if (frame.ownerDocument && frame.ownerDocument._iframeAddedObserver) { + _observeIframeAdded(frame.ownerDocument); } - }, + } +} - "DEVICE": { +function _createFrame(src) { + var frame = document.createElement("iframe"); + frame.setAttribute("id", "document"); + frame.src = src; + + if (ui.registered("omnibar")) { + _bindObjectsToFrame(frame); + } + + return frame; +} + +function _cleanBody() { + require('ripple/utils').forEach(document.body.children, function (child) { + if (child && child.id && !child.id.match(/ui|tooltip|bus/)) { + document.body.removeChild(child); + } + + document.body.removeAttribute("style"); + document.body.removeAttribute("id"); + document.body.removeAttribute("class"); + }); +} + +function reload() { + window.tinyHipposReload = true; + location.reload(); +} + +function _post(src) { + var event = require('ripple/event'), + frame = _createFrame(src); + + _console.log("Initialization Finished (Make it so.)"); + + frame.onload = function () { + var bootLoader = document.querySelector("#emulator-booting"), + id, + iframe = document.getElementById('document'), + viewportTagFound = false, + viewportTagContent = {}, + viewportTagStr = "", + tagProperties = [], + propertyKey ="", + propertyValue = "", + curViewPortWidth = "", + curViewPortHeight = "", + layout = db.retrieve("layout") || "portrait", + preLayout = ""; + + if (bootLoader) { + document.querySelector("#ui").removeChild(bootLoader); + } + + // Workaround to enforce the content of iframe to rerender when scrolling + document.getElementById('document').contentWindow.onscroll = function() { + jQuery("#device-maskmask").show(); + setTimeout(function() { + jQuery("#device-maskmask").hide(); + }, 50); + } + + event.trigger("TinyHipposLoaded"); + _cleanBody(); + id = window.setInterval(_cleanBody, 20); + + window.setTimeout(function () { + window.clearInterval(id); + }, 1200); + + // Clean data for different app + if (db.retrieve("current-url") !== db.retrieve("previous-url")) { + db.remove("viewport_width"); + db.remove("viewport_height"); + db.remove("viewportTag"); + db.remove("prelayout"); + } + + curViewPortWidth = db.retrieve("viewport_width"); + curViewPortHeight = db.retrieve("viewport_height"); + preLayout = db.retrieve("prelayout") || "portrait"; + db.save("previous-url", db.retrieve("current-url")); + + if (iframe.contentDocument.getElementsByName('viewport')[0] !== undefined) { + viewportTagStr = iframe.contentDocument.getElementsByName('viewport')[0].getAttribute("content"); + viewportTagStr = viewportTagStr.replace(/\s/g, ''); + tagProperties = viewportTagStr.split(","); + + for (var i in tagProperties) { + propertyKey = tagProperties[i].split("=")[0]; + propertyValue = tagProperties[i].split("=")[1]; + viewportTagContent[propertyKey] = propertyValue; + } + viewportTagFound = true; + } + + // if viewport tag found (width, height) + if (viewportTagFound && ((viewportTagContent['width'] !== undefined) || (viewportTagContent['height'] !== undefined))) { + if ((viewportTagContent['width'] !== undefined)) { + if (curViewPortWidth !== viewportTagContent['width']) { + db.saveObject("viewportTag", viewportTagContent); + if (layout !== preLayout) { + db.save("prelayout", layout); + resizer.changeLayoutType(layout); + event.trigger("LayoutChanged", [layout], true); + frame.contentWindow.location.reload(); // get the updated screenAvailWidth, screenWidth.... + } else { + resizer.changeLayoutType(layout); + } + } + } else { + if (curViewPortHeight !== viewportTagContent['height']) { + db.saveObject("viewportTag", viewportTagContent); + if (layout !== preLayout) { + db.save("prelayout", layout); + resizer.changeLayoutType(layout); + event.trigger("LayoutChanged", [layout], true); + frame.contentWindow.location.reload(); // get the updated screenAvailWidth, screenWidth.... + } else { + resizer.changeLayoutType(layout); + } + } + } + } else { + // Set layout to portrait if no viewport tag detected + resizer.changeLayoutType('portrait'); + event.trigger("LayoutChanged", ['portrait'], true); + } + + if (ui.registered("omnibar")) { + //reset the onload function so that when navigating we can destroy + //the iframe and create a new one so we can reinject the platform by + //calling post again. + frame.onload = function () { + var url = frame.contentWindow.location.href; + document.getElementById("viewport-container").removeChild(frame); + event.trigger("FrameHistoryChange", [url]); + _console.log("-----------------------------------------------------------"); + _console.log("Pay no attention to that man behind the curtain."); + _console.log("Environment Warning up again (Set main batteries to auto-fire cycle)"); + _post(url); + }; + } + }; + + // append frame + document.getElementById("viewport-container").appendChild(frame); + + delete tinyHippos.boot; +} + +function _bootstrap() { + // TODO: figure this out for web and ext + //_console.log("-----------------------------------------------------------"); + //_console.log("There be dragons above here!"); + _console.log("Web Simulator :: Environment Warming Up (Tea. Earl Gray. Hot.)"); + + window.tinyHippos = require('ripple'); + + tinyHippos.boot(function () { + var uri = ui.registered('omnibar') ? + db.retrieve(_CURRENT_URL) || "about:blank" : + document.documentURI.replace(/enableripple=[^&]*[&]?/i, "").replace(/[\?&]*$/, ""); + + _post(uri); + delete tinyHippos.boot; + }); +} + +module.exports = { + bootstrap: _bootstrap, + inject: function (frameWindow, frameDocument) { + _bindObjects(frameWindow, frameDocument); + } +}; + +}); +define('ripple/bus', function (require, exports, module) { +/* + * Copyright 2011 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var _send = document.getElementById("bus-send"), + _receive = document.getElementById("bus-receive"), + _evt = document.createEvent("Events"); + +_evt.initEvent('bus-init', true, true); +document.dispatchEvent(_evt); + +module.exports = { + send: function (msg, data, callback) { + var m = document.createElement("span"); + m.dataset.msg = msg; + m.innerHTML = JSON.stringify(data); + + if (callback) { + m.dataset.callback = Math.uuid(); + this.receive(m.dataset.callback, callback); + } + + _send.appendChild(m); + }, + + receive: function (msg, handler) { + if (!handler) { + return; + } + + _receive.addEventListener("DOMNodeInserted", function (evt) { + if (evt.target.dataset.msg === msg) { + handler(JSON.parse(evt.target.innerHTML)); + } + }); + }, + + ajax: function (method, url, data, success, fail) { + this.send("xhr", { + method: method, + url: url, + data: data + }, function (result) { + if (result.code === 200) { + success(result.data); + } + else { + fail(result); + } + }); + } +}; + +}); +define('ripple/console', function (require, exports, module) { +/* + * Copyright 2011 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var _self; + +function _log(msg, method) { + try { + console[method](_self.prefix ? _self.prefix + " :: " + msg : msg); + } catch (e) { + // silent + } +} + +_self = { + log: function (msg) { + _log(msg, "log"); + }, + + warn: function (msg) { + _log(msg, "warn"); + }, + + error: function (msg) { + _log(msg, "error"); + } +}; + +module.exports = _self; + +}); +define('ripple/constants', function (require, exports, module) { +/* + * Copyright 2011 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = { + "API_URL": "http://api.tinyhippos.com", + + "RELEASE_VERSION": "simulator-release-version", + + "SERVICES": { + "GOOGLE_MAPS_URI": "http://maps.google.com/maps/api/staticmap?size=476x476&maptype=roadmap", + "GOOGLE_MAPS_API_KEY": "ABQIAAAA-CaPZHXR-0Tzhui_h6gpjhSE_2rGlnYiB7L-ZGVwgaut5s7OYRSlBAaHCzBuZf2_23_vrCOfPxXHjA" + }, + + "FS_SIZE": 1024 * 1024 * 10, + + "COMMON": { + "APPLICATION_STATE": "ui-application-state-", + "PREFIX": "tinyhippos-", + "DEVICE_CONTAINER" : "device-container", + "MENU_BUTTON" : "menu-button", + "BACK_BUTTON" : "back-button", + "HTML_CONTAINER" : "document", + "INFO_SECTION": "information-sub-container", + "ORIENTATION_SELECT_PORTRAIT_ID" : "layout-portrait", + "ORIENTATION_SELECT_LANDSCAPE_ID" : "layout-landscape", + "PLATFORM_SELECT_ID": "platform-select", + "DEVICE_SELECT_ID": "device-select", + "STORAGE_TABLE_BODY_CLASS": "preferences-list-body", + "STORAGE_COUNT_CONTAINER_ID": "preferences-count", + "GEO_MAP_CONTAINER_ID": "geo-map", + "FILESYSTEM_UPDATE_BUTTON_ID_WITH_HASH": "#update-filesystem-button", + "USER_AGENT_DEFAULT": "default", + "APPLICATIONS_CONTAINER_ID": "widget-applications-content", + "STORAGE_CLEAR_BUTTON_ID": "preferences-clear-button", + "AJAX_LOADER_CONTAINER_CLASS": ".loader", + "IRRELEVANT_CLASS": "irrelevant", + "MULTIMEDIA_VOLUME_SLIDER_ID": "media-volume", + "MULTIMEDIA_VOLUME_FIELD_ID": "media-volume-value", + "MULTIMEDIA_AUDIO_STATE_FIELD_ID": "media-audio-state", + "MULTIMEDIA_AUDIO_PLAYING_FIELD_ID": "multimedia-isaudioplaying", + "MULTIMEDIA_AUDIO_PROGRESS_ID": "media-audio-progress", + "MULTIMEDIA_AUDIO_FILE_FIELD_ID": "media-audio-file", + "MULTIMEDIA_VIDEO_STATE_FIELD_ID": "media-video-state", + "MULTIMEDIA_VIDEO_PLAYING_FIELD_ID": "multimedia-isvideoplaying", + "MULTIMEDIA_VIDEO_PROGRESS_ID": "media-video-progress", + "MULTIMEDIA_VIDEO_FILE_FIELD_ID": "media-video-file", + "EXTENSION_URL_CONTAINER": "extension-url", + "SECURITY_LEVEL": "security-level" + }, + "LAUNCHING_HISTORY": "application-launching-history", + + "FILESYSTEM": { + "PERSISTENCE_KEY": "filesystem", + "INPUT_PREFIX_ID": "#panel-filesystem-" + }, + + "PLATFORM": { + "DEFAULT": { + "name": "tizen", + "version": "1.0" + } + }, + + "DEVICE": { "SAVED_KEY": "device-key" }, @@ -62996,16 +64496,16 @@ _self = { _orientation = _bind("ondeviceorientation", widgetWindow); _calibration = _bind("oncompassneedscalibration", widgetWindow); - widgetWindow.addEventListener = function (event, callback, useCapture) { - switch (event) { + widgetWindow.addEventListener = function (e, callback, useCapture) { + switch (e) { case "deviceorientation": _orientation.set(callback); + event.trigger("DeviceOrientationEventAddedEvent"); break; - case "devicemotion": _motion.set(callback); + event.trigger("DeviceMotionEventAddedEvent"); break; - case "compassneedscalibration": _calibration.set(callback); break; @@ -65113,17 +66613,17 @@ module.exports = { "screen": { "width": 720, - "height": 1280 + "height": 1280 }, "viewPort": { "portrait": { "width": 360, - "height": 610, + "height": 640, "paddingTop": 0, "paddingLeft": 0 }, "landscape": { - "width": 610, + "width": 640, "height": 360, "paddingTop": 0, "paddingLeft": 0 @@ -65164,17 +66664,17 @@ module.exports = { "screen": { "width": 480, - "height": 800 + "height": 800 }, "viewPort": { "portrait": { "width": 320, - "height": 506, + "height": 534, "paddingTop": 0, "paddingLeft": 0 }, "landscape": { - "width": 506, + "width": 534, "height": 320, "paddingTop": 0, "paddingLeft": 0 @@ -65207,9 +66707,7 @@ define('ripple/devices', function (require, exports, module) { var _self, db = require('ripple/db'), utils = require('ripple/utils'), - exception = require('ripple/exception'), platform = require('ripple/platform'), - constants = require('ripple/constants'), event = require('ripple/event'), _devices = {}; @@ -65299,33 +66797,107 @@ _self = module.exports = { }, getDevice: function (deviceId) { - var device, width, height; + var device, width, height, viewportWidth, viewportHeight, layout, viewportTag, ratio; device = _devices[deviceId] ? utils.copy(_devices[deviceId]) : null; - width = db.retrieve("custom_width"); - height = db.retrieve("custom_height"); + width = db.retrieve("custom_width") || 600; + height = db.retrieve("custom_height") || 800; + viewportTag = db.retrieveObject("viewportTag"); + layout = db.retrieve("layout") || "portrait" ; - if (width === undefined) { - width = 600; - } else { - width = parseInt(width, 10); + if (deviceId === undefined) + return null; + width = parseInt(width, 10); + height = parseInt(height, 10); + + if (viewportTag !== undefined) { + if (viewportTag['width'] !== undefined) { + viewportWidth = parseInt(viewportTag['width'], 10); + if (isNaN(viewportWidth)) { + viewportWidth = viewportWidth = device.viewPort[layout].width; + } + db.saveObject("viewport_width", viewportWidth); + + if (layout === "portrait") { + if (deviceId !== "custom") { + ratio = device.screen.height / device.screen.width; + } else { + ratio = height / width; + } + viewportHeight = viewportWidth * ratio; + db.saveObject("viewport_height", viewportHeight); + } else { + if (deviceId !== "custom") { + ratio = device.screen.width / device.screen.height; + } else { + ratio = width / height; + } + viewportHeight = viewportWidth * ratio; + db.saveObject("viewport_height", viewportHeight); + } + } else if(viewportTag['height'] !== undefined) { + viewportHeight = parseInt(viewportTag['height'], 10); + if (isNaN(viewportHeight)) { + viewportHeight = viewportHeight = device.viewPort[layout].height; + } + db.saveObject("viewport_height", viewportHeight); + + if (layout === "portrait") { + if (deviceId !== "custom") { + ratio = device.screen.height / device.screen.width; + } else { + ratio = height / width; + } + viewportWidth = viewportHeight / ratio; + db.saveObject("viewport_width", viewportWidth); + } else { + if (deviceId !== "custom") { + ratio = device.screen.width / device.screen.height; + } else { + ratio = width / height; + } + viewportWidth = viewportHeight / ratio; + db.saveObject("viewport_width", viewportWidth); + } + } } - if (height === undefined) { - height = 800; - } else { - height = parseInt(height, 10); + if (viewportWidth === undefined) { + if (deviceId === "custom") { + viewportWidth = width; + } else { + viewportWidth = device.viewPort[layout].width; + } + } + + if (viewportHeight === undefined) { + if (deviceId === "custom") { + viewportHeight = height; + } else { + viewportHeight = device.viewPort[layout].height; + } } $('#resolution-custom-width').val(width); $('#resolution-custom-height').val(height); + if (deviceId === "custom") { - device.screen.width = device.viewPort.portrait.width = width; - device.screen.height = device.viewPort.portrait.height = height; - device.viewPort.landscape.height = width; - device.viewPort.landscape.width = height; + device.screen.width = width; + device.screen.height = height; $('input:radio[name="resolution-type"][value="custom"]').click(); } + + if (layout === "portrait") { + device.viewPort.portrait.width = viewportWidth; + device.viewPort.portrait.height = viewportHeight; + device.viewPort.landscape.width = viewportHeight; + device.viewPort.landscape.height = viewportWidth; + } else { + device.viewPort.portrait.width = viewportHeight; + device.viewPort.portrait.height = viewportWidth; + device.viewPort.landscape.width = viewportWidth; + device.viewPort.landscape.height = viewportHeight; + } return device; }, @@ -65516,11 +67088,9 @@ define('ripple/emulatorBridge', function (require, exports, module) { * See the License for the specific language governing permissions and * limitations under the License. */ -var _isMouseDown = false, - platform = require('ripple/platform'), +var platform = require('ripple/platform'), builder = require('ripple/platform/builder'), utils = require('ripple/utils'), - exception = require('ripple/exception'), _xhr, _win, _doc; function _getEmulatedViewportStyle(attr) { @@ -65528,20 +67098,27 @@ function _getEmulatedViewportStyle(attr) { return vp["client" + attr]; } +function _getEmulatedDeviceStyle(attr) { + var vp = document.getElementById("device-container"), value; + value = vp.style[attr].replace(/\s/g, ''); + value = value.split("px")[0] - 4; + return (value); +} + function _screenAvailWidth() { - return _getEmulatedViewportStyle("Width"); + return _getEmulatedDeviceStyle("width"); } function _screenAvailHeight() { - return _getEmulatedViewportStyle("Height"); + return _getEmulatedDeviceStyle("height"); } function _screenWidth() { - return _getEmulatedViewportStyle("Width"); + return _getEmulatedDeviceStyle("width"); } function _screenHeight() { - return _getEmulatedViewportStyle("Height"); + return _getEmulatedDeviceStyle("height"); } function _window_innerWidth() { @@ -65572,9 +67149,19 @@ function _marshalScreen(win) { module.exports = { link: function (win, doc) { - _win = win; - _doc = doc; - _xhr = win.XMLHttpRequest; + // Only cache the device window and route onmessage to it + if (win.parent.parent === win.parent && + win.frameElement.getAttribute('id') === 'document') { + _win = win; + _doc = doc; + _xhr = win.XMLHttpRequest; + + window.onmessage = function (e) { + if (typeof win.onmessage === 'function') { + win.onmessage(e); + } + }; + } require('ripple/widgetConfig').initialize(); @@ -65586,11 +67173,7 @@ module.exports = { marshal(window.tinyHippos, "tinyHippos"); marshal(window.XMLHttpRequest, "XMLHttpRequest"); - window.onmessage = function (e) { - if (typeof win.onmessage === 'function') { - win.onmessage(e); - } - }; + marshal(window.Date, "Date"); if (currentPlatform.initialize) { currentPlatform.initialize(win); @@ -65778,6 +67361,7 @@ module.exports = { NotificationStateType: "NotificationStateType", DomObjectNotFound: "DomObjectNotFound", LayoutType: "LayoutType", + OrientationType: "OrientationType", DeviceNotFound: "DeviceNotFound", tinyHipposMaskedException: "tinyHipposMaskedException", Geo: "Geo", @@ -66304,6 +67888,51 @@ module.exports = { }; }); +define('ripple/hwKeyEmulator', function (require, exports, module) { +/* + * Copyright 2011 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var event = require('ripple/event'), + _self; + +function _HWKeyEvent(keyName) { + var doc = document.getElementById('document').contentDocument, + event; + + event = doc.createEvent('Event'); + event.initEvent("tizenhwkey", true, false); + event.__defineGetter__("keyName", function () { + return keyName; + }); + doc.dispatchEvent(event); +} + + +_self = { + init: function (win, doc) { + event.clear("tizenhwkeyEvent"); + event.on("tizenhwkeyEvent", function (keyName) { + _HWKeyEvent(keyName); + }); + } +}; + +module.exports = _self; + +}); define('ripple/notifications', function (require, exports, module) { /* * Copyright 2011 Research In Motion Limited. @@ -66406,8 +68035,7 @@ define('ripple/omgwtf', function (require, exports, module) { * See the License for the specific language governing permissions and * limitations under the License. */ -var constants = require('ripple/constants'), - event = require('ripple/event'), +var event = require('ripple/event'), db = require('ripple/db'), _loaded = false, _self; @@ -66487,43 +68115,45 @@ var utils = require('ripple/utils'), app = require('ripple/app'), constants = require('ripple/constants'); -function _objectFactory(context, objects, allowed) { +function _objectFactory(context, objects/*, allowed*/) { utils.forEach(objects, function (obj, key) { var result = {}, objFeatures = {}, rst, f, widgetFeatures; - if (allowed(obj)) { - result = obj.path ? require('ripple/platform/' + obj.path) : {}; - if (typeof result === "function" && obj.handleSubfeatures && obj.handleSubfeatures === true) { - rst = new result(); - if (obj.feature) { - objFeatures = obj.feature.split('|'); - if (rst.handleSubFeatures) { - widgetFeatures = app.getInfo().features; // features in config.xml - f = {}; - utils.forEach(objFeatures, function (o) { - if (widgetFeatures && !!widgetFeatures[o]) { - f[widgetFeatures[o].id] = widgetFeatures[o]; - } - }); - rst.handleSubFeatures(f); - delete rst.handleSubFeatures; - } +// if (allowed(obj)) { + result = obj.path ? require('ripple/platform/' + obj.path) : {}; + if (typeof result === "function" && obj.handleSubfeatures && obj.handleSubfeatures === true) { + rst = new result(); + if (obj.feature) { + objFeatures = obj.feature.split('|'); + if (rst.handleSubFeatures) { + widgetFeatures = app.getInfo().features; // features in config.xml + f = {}; + utils.forEach(objFeatures, function (o) { + if (widgetFeatures && !!widgetFeatures[o]) { + f[widgetFeatures[o].id] = widgetFeatures[o]; + } + }); + rst.handleSubFeatures(f); + delete rst.handleSubFeatures; } - result = rst; } + result = rst; } +// } if (obj.children) { - _objectFactory(result, obj.children, allowed); + _objectFactory(result, obj.children/*, allowed*/); } // inject into the context if it is allowed or it has children that were allowed - if (allowed(obj) || utils.count(result)) { - context[key] = result; - } - else { - delete context[key]; - } +// if (allowed(obj) || utils.count(result)) { + context[key] = result; +// } +// else { +// if (context.hasOwnProperty(key)) +// console.log("delete " + key); +// delete context[key]; +// } }); } @@ -66531,7 +68161,7 @@ module.exports = { build: function (objects) { return { into: function (sandbox) { - var features = utils.copy(app.getInfo().features), +/* var features = utils.copy(app.getInfo().features); allowed = function (obj) { var contains = function (requirements) { return requirements.split('|').some(function (feature) { @@ -66544,8 +68174,9 @@ module.exports = { // 3. the feature exists in the defined features return !obj.feature || !features || (features && contains(obj.feature)); }; +*/ - _objectFactory(sandbox, objects, allowed); + _objectFactory(sandbox, objects/*, allowed*/); } }; } @@ -70588,9 +72219,10 @@ var utils = require('ripple/utils'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), AlarmBase = require('ripple/platform/tizen/2.0/AlarmBase'), _byDayValue = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"], - PERIOD_WEEK = (7 * 24 * 60 * 60), MILLI_SECOND = 1000; + PERIOD_WEEK = (7 * 24 * 60 * 60), MILLI_SECOND = 1000, + AlarmAbsolute; -module.exports = function (date, frequency) { +AlarmAbsolute = function (date, frequency) { var alarm, period = null, daysOfTheWeek = [], ascDays = []; function checkDayValue(days) { @@ -70651,7 +72283,7 @@ module.exports = function (date, frequency) { return true; } - alarm = new AlarmBase(); + alarm = new AlarmBase(this); date = new Date(date); if (frequency !== undefined) { if (tizen1_utils.isValidArray(frequency)) { @@ -70664,7 +72296,7 @@ module.exports = function (date, frequency) { } } - alarm.getNextScheduledDate = function () { + this.getNextScheduledDate = function () { var current = new Date(), diff, isPass, today, total, i, nextDate; @@ -70706,19 +72338,21 @@ module.exports = function (date, frequency) { return getSchedulteDateByDay(current, date, today, nextDate); }; - alarm.__defineGetter__("date", function () { + this.__defineGetter__("date", function () { return date; }); - alarm.__defineGetter__("period", function () { + + this.__defineGetter__("period", function () { return period; }); - alarm.__defineGetter__("daysOfTheWeek", function () { + + this.__defineGetter__("daysOfTheWeek", function () { return daysOfTheWeek; }); - - return alarm; }; +module.exports = AlarmAbsolute; + }); define('ripple/platform/tizen/2.0/AlarmBase', function (require, exports, module) { /* @@ -70737,14 +72371,11 @@ define('ripple/platform/tizen/2.0/AlarmBase', function (require, exports, module * limitations under the License. */ -module.exports = function (id) { - id = id || Math.uuid(null, 16); +module.exports = function (self) { + self = self || this; - this.__defineGetter__("id", function () { - return id; - }); - this.__defineSetter__("id", function (_id) { - id = _id; + self.__defineGetter__("id", function () { + return null; }); }; @@ -70766,17 +72397,18 @@ define('ripple/platform/tizen/2.0/AlarmRelative', function (require, exports, mo * limitations under the License. */ -var AlarmBase = require('ripple/platform/tizen/2.0/AlarmBase'); +var AlarmBase = require('ripple/platform/tizen/2.0/AlarmBase'), + AlarmRelative; -module.exports = function (delay, period) { +AlarmRelative = function (delay, period) { var alarm, date; - alarm = new AlarmBase(); + alarm = new AlarmBase(this); delay = delay || 0; period = period || null; date = new Date(); // Alarm settime - alarm.getRemainingSeconds = function () { + this.getRemainingSeconds = function () { var current, diff, triggerDate, MILLI_SECOND = 1000; current = new Date(); triggerDate = new Date(delay * MILLI_SECOND + date.getTime()); // First triggerDate @@ -70795,16 +72427,17 @@ module.exports = function (delay, period) { return diff; }; - alarm.__defineGetter__("delay", function () { + this.__defineGetter__("delay", function () { return delay; }); - alarm.__defineGetter__("period", function () { + + this.__defineGetter__("period", function () { return period; }); - - return alarm; }; +module.exports = AlarmRelative; + }); define('ripple/platform/tizen/2.0/ApplicationBase', function (require, exports, module) { /* @@ -70950,38 +72583,31 @@ define('ripple/platform/tizen/2.0/ApplicationControl', function (require, export * limitations under the License. */ -var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - ApplicationControlData = require('ripple/platform/tizen/2.0/ApplicationControlData'); +var t = require('ripple/platform/tizen/2.0/typecast'); -module.exports = function (operation, uri, mime, category, data) { - var _self, i; +var ApplicationControl = function (operation, uri, mime, category, data) { + var _data = []; - _self = { - operation: "", - url: "", - mime: "", - category : "", - data: [] - }; + this.operation = t.DOMString(operation); + this.uri = t.DOMString(uri, "?") || null; + this.mime = t.DOMString(mime, "?"); + this.category = t.DOMString(category, "?"); - _self.operation = String(operation); - if (uri) { - _self.uri = String(uri); - } - if (mime) { - _self.mime = String(mime); - } - if (category) { - _self.category = String(category); - } - if (tizen1_utils.isValidArray(data)) { - for (i in data) { - _self.data.push(new ApplicationControlData(data[i].key, data[i].value)); - } + if (data) { + _data = t.ApplicationControlData(data, "[]?"); } - return _self; + + this.__defineGetter__("data", function () { + return _data; + }); + + this.__defineSetter__("data", function (data) { + data = data || []; + _data = t.ApplicationControlData(data, "[]"); + }); }; +module.exports = ApplicationControl; }); define('ripple/platform/tizen/2.0/ApplicationControlData', function (require, exports, module) { @@ -71001,19 +72627,26 @@ define('ripple/platform/tizen/2.0/ApplicationControlData', function (require, ex * limitations under the License. */ -var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'); +var t = require('ripple/platform/tizen/2.0/typecast'); -module.exports = function (key, value) { - this.key = String(key); - this.value = []; +var ApplicationControlData = function (key, value) { + var val = []; - if (tizen1_utils.isValidArray(value)) { - for (var i in value) { - this.value.push(String(value[i])); - } - } + this.key = t.DOMString(key); + val = t.DOMString(value, '[]'); + + this.__defineGetter__("value", function () { + return val; + }); + + this.__defineSetter__("value", function (value) { + value = value || []; + val = t.DOMString(value, '[]'); + }); }; +module.exports = ApplicationControlData; + }); define('ripple/platform/tizen/2.0/ApplicationInformation', function (require, exports, module) { /* @@ -71032,19 +72665,8 @@ define('ripple/platform/tizen/2.0/ApplicationInformation', function (require, ex * limitations under the License. */ -module.exports = function (id, name, iconPath, version, show, categories, installDate, size) { - var _self; - - _self = { - id : id, - name : name, - iconPath : iconPath, - version : version, - show : show, - categories : categories, - installDate : installDate, - size : size - }; +module.exports = function (id, name, iconPath, version, show, categories, installDate, size, packageId) { + var _self = this; _self.__defineGetter__("id", function () { return id; @@ -71070,6 +72692,9 @@ module.exports = function (id, name, iconPath, version, show, categories, instal _self.__defineGetter__("size", function () { return size; }); + _self.__defineGetter__("packageId", function () { + return packageId; + }); return _self; }; @@ -71102,21 +72727,21 @@ module.exports = function (_attributeName, _matchFlag, _matchValue) { }); define('ripple/platform/tizen/2.0/AttributeRangeFilter', function (require, exports, module) { -/* +/* * Copyright 2012 Intel Corporation. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ module.exports = function (_attributeName, _initialValue, _endValue) { return { @@ -71914,14 +73539,14 @@ var utils = require('ripple/utils'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), _alarmMethods = ["SOUND", "DISPLAY"]; -module.exports = function (triggerTime, method, description) { +function CalendarAlarm (triggerTime, method, description) { var absoluteDate = null, before = null, isValid = false, - _self; + _self = this; if (triggerTime instanceof TZDate) { - absoluteDate = new TZDate(triggerTime); + absoluteDate = triggerTime; } else if (triggerTime instanceof TimeDuration) { before = triggerTime; } else { @@ -71932,16 +73557,15 @@ module.exports = function (triggerTime, method, description) { if (!isValid) throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - if (method.equals("DISPLAY") && description === null) - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - _self.absoluteDate = absoluteDate; _self.before = before; _self.method = method; - _self.description = description; + _self.description = description || ""; return _self; -}; +} + +module.exports = CalendarAlarm; }); define('ripple/platform/tizen/2.0/CalendarAttendee', function (require, exports, module) { @@ -71961,11 +73585,11 @@ define('ripple/platform/tizen/2.0/CalendarAttendee', function (require, exports, * limitations under the License. */ -module.exports = function (attendeeInitDict) { - var _self; +module.exports = function (uri, attendeeInitDict) { + var _self = this; + _self.uri = uri; if (attendeeInitDict) { - _self.uri = (attendeeInitDict.uri) ? attendeeInitDict.uri : ""; _self.name = (attendeeInitDict.name) ? attendeeInitDict.name : ""; _self.role = (attendeeInitDict.role) ? attendeeInitDict.role : ""; _self.status = (attendeeInitDict.status) ? attendeeInitDict.status : ""; @@ -71976,7 +73600,6 @@ module.exports = function (attendeeInitDict) { _self.delegateURI = (attendeeInitDict.delegateURI) ? attendeeInitDict.delegateURI : ""; _self.contactRef = (attendeeInitDict.contactRef) ? attendeeInitDict.contactRef : ""; } else { - _self.uri = ""; _self.name = ""; _self.role = ""; _self.status = ""; @@ -72040,7 +73663,7 @@ module.exports = function (eventInitDict) { _self.startDate = eventInitDict.startDate; } if (eventInitDict.duration && (typeof eventInitDict.duration === "object")) { - _self.duration = new TZDate(eventInitDict.duration); + _self.duration = eventInitDict.duration; } if (eventInitDict.location) { _self.location = String(eventInitDict.location); @@ -72106,7 +73729,9 @@ module.exports = function (eventInitDict) { _self.startDate = startDate; _self.endDate = endDate; if (errorCallback) { - errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR)); + window.setTimeout(function () { + errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR)); + }, 1); } }; _self.__defineGetter__("isDetached", function () { @@ -72164,6 +73789,7 @@ var utils = require('ripple/utils'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), TZDate = require('ripple/platform/tizen/2.0/TZDate'), SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), CalendarItemInit, @@ -72171,7 +73797,7 @@ var utils = require('ripple/utils'), CalendarTaskInit, CalendarItem; -CalendarItem = function (type, id, lastModificationDate) { +CalendarItem = function (type, id, lastModificationDate, _security) { var _self; function _2digital(number) { @@ -72192,9 +73818,13 @@ CalendarItem = function (type, id, lastModificationDate) { id = id || Math.uuid(null, 16); } - lastModificationDate = (lastModificationDate) ? utils.copy(lastModificationDate) : (new TZDate()); + lastModificationDate = (lastModificationDate) ? utils.copy(lastModificationDate) : null; _self.status = (type === "EVENT") ? "CONFIRMED" : "NEEDS_ACTION"; + _self.__defineGetter__("calendarId", function () { + return null; + }); + _self.__defineGetter__("id", function () { return id; }); @@ -72206,7 +73836,12 @@ CalendarItem = function (type, id, lastModificationDate) { _self.clone = function () { var item = new CalendarItem(type); + if (_security instanceof Object && !_security.clone) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + item.id = Math.uuid(null, 16); + item.calendarId = _self.calendarId; item.lastModificationDate = new TZDate(); item.description = _self.description; item.summary = _self.summary; @@ -72241,6 +73876,9 @@ CalendarItem = function (type, id, lastModificationDate) { header = "BEGIN:VCALENDAR\r\nPRODID:-//Tizen.org//Tizen Calendar//EN\r\nVERSION:2.0\r\n", end = "END:VCALENDAR\r\n"; + if (_security instanceof Object && !_security.convertToString) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } if (format !== "ICALENDAR_20" && format !== "VCALENDAR_10") { throw new WebAPIError(errorcode.TYPE_MISMATCH_ERROR); } @@ -72492,9 +74130,9 @@ module.exports = function (frequency, ruleInitDict) { _self.frequency = (frequency) ? frequency : 0; if ((ruleInitDict !== undefined) && (ruleInitDict !== null)) { - _self.interval = ((ruleInitDict.interval > 0) && (ruleInitDict.interval === parseInt(ruleInitDict.interval))) ? Number(ruleInitDict.interval) : 1; + _self.interval = ((ruleInitDict.interval > 0) && (ruleInitDict.interval === parseInt(ruleInitDict.interval, 10))) ? Number(ruleInitDict.interval) : 1; _self.untilDate = tizen1_utils.isValidTZDate(ruleInitDict.untilDate) ? (new TZDate(new Date(ruleInitDict.untilDate))) : null; - _self.occurrenceCount = (ruleInitDict.occurrenceCount === parseInt(ruleInitDict.occurrenceCount)) ? Number(ruleInitDict.occurrenceCount) : -1; + _self.occurrenceCount = (ruleInitDict.occurrenceCount === parseInt(ruleInitDict.occurrenceCount, 10)) ? Number(ruleInitDict.occurrenceCount) : -1; _self.daysOfTheWeek = tizen1_utils.isValidArray(ruleInitDict.daysOfTheWeek) ? utils.copy(ruleInitDict.daysOfTheWeek) : []; _self.setPositions = tizen1_utils.isValidArray(ruleInitDict.setPositions) ? utils.copy(ruleInitDict.setPositions) : []; _self.exceptions = tizen1_utils.isValidArray(ruleInitDict.exceptions) ? utils.copy(ruleInitDict.exceptions) : []; @@ -72555,8 +74193,8 @@ module.exports = function (taskInitDict) { if (taskInitDict.startDate && tizen1_utils.isValidTZDate(taskInitDict.startDate)) { _self.startDate = taskInitDict.startDate; } - if (taskInitDict.duration && (typeof taskInitDict.duration === "object")) { - _self.duration = new TZDate(new Date(taskInitDict.duration)); + if (taskInitDict.duration instanceof tizen.TimeDuration) { + _self.duration = taskInitDict.duration; } if (taskInitDict.location) { _self.location = String(taskInitDict.location); @@ -72637,7 +74275,7 @@ define('ripple/platform/tizen/2.0/CompositeFilter', function (require, exports, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ module.exports = function (_type, _filters) { return { @@ -72663,7 +74301,7 @@ define('ripple/platform/tizen/2.0/ContactAccount', function (require, exports, m * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ module.exports = function (id, accountURI) { var _self, _id, _uri; @@ -72808,7 +74446,10 @@ define('ripple/platform/tizen/2.0/ContactBase', function (require, exports, modu * limitations under the License. */ -var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), +var utils = require('ripple/utils'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), ContactName = require('ripple/platform/tizen/2.0/ContactName'), ContactOrganization = require('ripple/platform/tizen/2.0/ContactOrganization'), ContactWebSite = require('ripple/platform/tizen/2.0/ContactWebSite'), @@ -72817,8 +74458,8 @@ var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), ContactPhoneNumber = require('ripple/platform/tizen/2.0/ContactPhoneNumber'), ContactEmailAddress = require('ripple/platform/tizen/2.0/ContactEmailAddress'); -module.exports = function (prop) { - var _self; +function Contact(prop, _security) { + var _self = this; // constructor function init_ContactInitDict(contactInitDict) { @@ -72892,47 +74533,68 @@ module.exports = function (prop) { // public function convertToString(format) { - //TODO - console.log("convert to VCard String..."); + //TODO: convert content accord to Vcard protocal + if (format !== 'VCARD_30') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + return ""; } function clone(obj) { - var copy = obj.constructor(), attr; + var copy = new Contact(), attr, + ignoreProp = ["id", "personId", "addressBookId", "lastUpdated", "isFavorite"]; + if (_security instanceof Object && !_security.clone) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } for (attr in obj) { - if (obj.hasOwnProperty(attr)) - copy[attr] = obj[attr]; + if ((ignoreProp.indexOf(attr) === -1) && + obj.hasOwnProperty(attr) && + (typeof obj[attr] !== "function")) { + copy[attr] = utils.copy(obj[attr]); + } } - /* remove these two attribute */ - copy.id = null; - copy.lastUpdated = null; + return copy; } - _self = { - id: null, - personId: null, - addressBookId: null, - lastUpdated: null, - isFavorite: false, - name: null, - addresses: [], - photoURI: null, - phoneNumbers: undefined, - emails: undefined, - birthday: null, - anniversaries: undefined, // Correct null to undefined - organizations: undefined, - notes: undefined, - urls: [], - ringtoneURI: null, - groupIds: [], - convertToString: convertToString, - clone: function () { - return clone(this); - } + _self.name = null; + _self.addresses = []; + _self.photoURI = null; + _self.phoneNumbers = []; + _self.emails = []; + _self.birthday = null; + _self.anniversaries = []; + _self.organizations = []; + _self.notes = []; + _self.urls = []; + _self.ringtoneURI = null; + _self.groupIds = []; + _self.convertToString = convertToString; + _self.clone = function () { + return clone(_self); }; + _self.__defineGetter__("id", function () { + return null; + }); + + _self.__defineGetter__("personId", function () { + return null; + }); + + _self.__defineGetter__("addressBookId", function () { + return null; + }); + + _self.__defineGetter__("lastUpdated", function () { + return null; + }); + + _self.__defineGetter__("isFavorite", function () { + return false; + }); + if (typeof prop === "string") { init_stringRepresentation(String(prop)); } else if (prop) { @@ -72940,7 +74602,9 @@ module.exports = function (prop) { } return _self; -}; +} + +module.exports = Contact; }); define('ripple/platform/tizen/2.0/ContactEmailAddress', function (require, exports, module) { @@ -73010,12 +74674,21 @@ define('ripple/platform/tizen/2.0/ContactGroup', function (require, exports, mod module.exports = function (name, ringtoneURI, photoURI) { var _self = {}; - _self.id = null; - _self.addressBookId = null; + _self.__defineGetter__("id", function () { + return null; + }); + + _self.__defineGetter__("addressBookId", function () { + return null; + }); + + _self.__defineGetter__("readOnly", function () { + return false; + }); + _self.name = name ? String(name) : ""; _self.ringtoneURI = ringtoneURI ? String(ringtoneURI) : null; _self.photoURI = photoURI ? String(photoURI) : null; - _self.readOnly = false; return _self; }; @@ -73041,50 +74714,53 @@ define('ripple/platform/tizen/2.0/ContactName', function (require, exports, modu var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'); module.exports = function (nameInitDict) { - var _self, i; - - _self = { - prefix: "", - suffix: "", - firstName: "", - middleName: "", - lastName: "", + var self, i; + + self = { + prefix: null, + suffix: null, + firstName: null, + middleName: null, + lastName: null, nicknames: [], phoneticFirstName: null, - phoneticLastName: null, - displayName: null + phoneticLastName: null }; if (nameInitDict) { if (nameInitDict.prefix !== null && nameInitDict.prefix !== undefined) { - _self.prefix = String(nameInitDict.prefix); + self.prefix = String(nameInitDict.prefix); } if (nameInitDict.suffix !== null && nameInitDict.suffix !== undefined) { - _self.suffix = String(nameInitDict.suffix); + self.suffix = String(nameInitDict.suffix); } if (nameInitDict.firstName !== null && nameInitDict.firstName !== undefined) { - _self.firstName = String(nameInitDict.firstName); + self.firstName = String(nameInitDict.firstName); } if (nameInitDict.middleName !== null && nameInitDict.middleName !== undefined) { - _self.middleName = String(nameInitDict.middleName); + self.middleName = String(nameInitDict.middleName); } if (nameInitDict.lastName !== null && nameInitDict.lastName !== undefined) { - _self.lastName = String(nameInitDict.lastName); + self.lastName = String(nameInitDict.lastName); } if (tizen1_utils.isValidArray(nameInitDict.nicknames)) { for (i in nameInitDict.nicknames) { - _self.nicknames.push(String(nameInitDict.nicknames[i])); + self.nicknames.push(String(nameInitDict.nicknames[i])); } } if (nameInitDict.phoneticFirstName !== null && nameInitDict.phoneticFirstName !== undefined) { - _self.phoneticFirstName = String(nameInitDict.phoneticFirstName); + self.phoneticFirstName = String(nameInitDict.phoneticFirstName); } if (nameInitDict.phoneticLastName !== null && nameInitDict.phoneticLastName !== undefined) { - _self.phoneticLastName = String(nameInitDict.phoneticLastName); + self.phoneticLastName = String(nameInitDict.phoneticLastName); } } - return _self; + self.__defineGetter__("displayName", function () { + return null; + }); + + return self; }; }); @@ -73204,25 +74880,18 @@ define('ripple/platform/tizen/2.0/ContactRef', function (require, exports, modul * limitations under the License. */ -module.exports = function (addressBookId, contactId) { - var _self; - - _self = { - addressBookId: undefined, - contactId: undefined - }; - - if ((typeof addressBookId !== "string" || !addressBookId) - (typeof contactId !== "string" || !contactId)) { - return _self; +var ContactRef = function (addressBookId, contactId) { + if (!addressBookId || (typeof addressBookId !== "string") || + !contactId || (typeof contactId !== "string")) { + return this; } - _self.addressBookId = addressBookId; - _self.contactId = contactId; - - return _self; + this.addressBookId = addressBookId; + this.contactId = contactId; }; +module.exports = ContactRef; + }); define('ripple/platform/tizen/2.0/ContactWebSite', function (require, exports, module) { /* @@ -73714,7 +75383,7 @@ define('ripple/platform/tizen/2.0/GeocodeResult', function (require, exports, mo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'); @@ -73723,7 +75392,7 @@ module.exports = function (lat, lon) { _coordinates = new SimpleCoordinates(lat, lon); - jsonObj = { + jsonObj = { "type" : "Point", "coordinates" : [lat, lon] }; @@ -74701,6 +76370,7 @@ define('ripple/platform/tizen/2.0/MessagingService', function (require, exports, var event = require('ripple/event'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), + deviceSettings = require('ripple/deviceSettings'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), PrivMessage = require('ripple/platform/tizen/2.0/PrivMessage'), @@ -74800,7 +76470,7 @@ _self = function (id, type, security_check) { msg_service = { sendMessage: function (_msg, onSuccess, onError) { var m, msg = {}, opt = {}, shortMsg = {}, rst = {}; - if (_security_check.send === false) { + if (_security_check.write === false) { throw (new WebAPIException(errorcode.SECURITY_ERR)); } if (_msg === null || _msg === undefined || _msg.id === undefined) { @@ -74810,12 +76480,30 @@ _self = function (id, type, security_check) { if (msg_utils.setMsg(_msg, msg) === false) { throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR)); } - if (onSuccess && !(new TypeCoerce(t.MessageRecipientsCallback)).match(onSuccess)) { + if ((arguments.length > 1) && onSuccess !== null && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { + if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } + if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false && + (_incomingType === 'sms' || _incomingType === 'mms')) { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.NETWORK_ERR)); + }, 1); + } + return; + } + if (deviceSettings.retrieve("WIFI_NETWORK.status") === false && + _incomingType === 'email') { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.NETWORK_ERR)); + }, 1); + } + return; + } if (typeof _msg.id === 'string') { if (_messages.msg[_msg.id] === undefined) { if (onError) { @@ -74884,11 +76572,11 @@ _self = function (id, type, security_check) { if (!(new TypeCoerce(t.MessageBodySuccessCallback)).match(onSuccess)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { + if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } pendingID = setTimeout(function () { - if (pendingOperations[pendingID] === undefined) { + if (pendingOperations.hasOwnProperty(pendingID) === false) { // has been cancelled/expired return; } @@ -74910,11 +76598,11 @@ _self = function (id, type, security_check) { if (!(new TypeCoerce(t.MessageAttachmentSuccessCallback)).match(onSuccess)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { + if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } pendingID = setTimeout(function () { - if (pendingOperations[pendingID] === undefined) { + if (pendingOperations.hasOwnProperty(pendingID) === false) { // has been cancelled/expired return; } @@ -74930,17 +76618,17 @@ _self = function (id, type, security_check) { if (_security_check.write === false) { throw (new WebAPIException(errorcode.SECURITY_ERR)); } - if (successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { + if ((arguments.length > 0) && successCallback !== null && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { + if ((arguments.length > 1) && errorCallback !== null && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (limit && !(new TypeCoerce(t.long)).match(limit)) { + if ((arguments.length > 2) && limit !== null && !(new TypeCoerce(t.long)).match(limit)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } pendingID = setTimeout(function () { - if (pendingOperations[pendingID] === undefined) { + if (pendingOperations.hasOwnProperty(pendingID) === false) { // has been cancelled/expired return; } @@ -74965,17 +76653,20 @@ _self = function (id, type, security_check) { if (_security_check.write === false) { throw (new WebAPIException(errorcode.SECURITY_ERR)); } - if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) { + if (!(new TypeCoerce(t.MessageFolder)).match(folder)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { + if ((arguments.length > 1) && onSuccess !== null && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (limit && !(new TypeCoerce(t.long)).match(limit)) { + if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((arguments.length > 3) && limit !== null && !(new TypeCoerce(t.long)).match(limit)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } pendingID = setTimeout(function () { - if (pendingOperations[pendingID] === undefined) { + if (pendingOperations.hasOwnProperty(pendingID) === false) { // has been cancelled/expired return; } @@ -74995,19 +76686,14 @@ _self = function (id, type, security_check) { }, stopSync: function (pendingID) { - if (_security_check.write === false) { - throw (new WebAPIException(errorcode.SECURITY_ERR)); - } if (!(new TypeCoerce(t.long)).match(pendingID)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (pendingOperations[pendingID] === undefined) { - return; - } else { + if (pendingOperations[pendingID] !== undefined) { clearTimeout(pendingID); pendingOperations[pendingID](new WebAPIError(errorcode.ABORT_ERR)); - delete pendingOperations[pendingID]; } + delete pendingOperations[pendingID]; } }; msg_service.__defineGetter__("type", function () { @@ -75088,6 +76774,8 @@ define('ripple/platform/tizen/2.0/NDEFRecord', function (require, exports, modul * See the License for the specific language governing permissions and * limitations under the License. */ +var errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'); module.exports = function (tnf, type, payload, id) { var _self = {}, @@ -75096,6 +76784,9 @@ module.exports = function (tnf, type, payload, id) { _id = id || [], _payload = payload; + if (arguments.length < 3) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } _self.__defineGetter__("tnf", function () { return _tnf; }); @@ -75132,13 +76823,19 @@ define('ripple/platform/tizen/2.0/NDEFRecordMedia', function (require, exports, * limitations under the License. */ -var NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecord'); +var NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecord'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'); module.exports = function (mimeType, data) { var _self = {}, _mimeType = mimeType, _data = data; + if (arguments.length < 2) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + _self = new NDEFRecord(2, [], [], []); _self.__defineGetter__("mimeType", function () { @@ -75531,7 +77228,7 @@ module.exports = function (id, name, iconPath, version, totalSize, return description; }); packageInformation.__defineGetter__("appIds", function () { - return appIds; + return appIds; }); return packageInformation; @@ -75690,15 +77387,15 @@ define('ripple/platform/tizen/2.0/SimpleCoordinates', function (require, exports * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ -module.exports = function (_latitude, _longitude) { - return { - latitude: _latitude || 0, - longitude: _longitude || 0 - }; +function SimpleCoordinates (_latitude, _longitude) { + this.latitude = _latitude || 0; + this.longitude = _longitude || 0; + return this; }; +module.exports = SimpleCoordinates; }); define('ripple/platform/tizen/2.0/SortMode', function (require, exports, module) { @@ -75716,7 +77413,7 @@ define('ripple/platform/tizen/2.0/SortMode', function (require, exports, module) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ var errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'); @@ -75760,7 +77457,7 @@ define('ripple/platform/tizen/2.0/StatusNotification', function (require, export * limitations under the License. */ -var utils = require('ripple/utils'), +var utils = require('ripple/utils'), NotificationBase = require('ripple/platform/tizen/2.0/NotificationBase'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), @@ -75860,7 +77557,7 @@ function _checkDictProperties(dict) { } flag = false; utils.forEach(dict.detailInfo, function (info) { - if (!_checkNotificationDetailInfo(info)) { + if (!_checkNotificationDetailInfo(info)) { flag = true; } }); @@ -75934,6 +77631,272 @@ _self = function (_statusType, title, notificationInitDict) { module.exports = _self; }); +define('ripple/platform/tizen/2.0/SyncInfo', function (require, exports, module) { +/* + * Copyright 2013 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var db = require('ripple/db'), + t = require('ripple/platform/tizen/2.0/typecast'), + _counter = 0, + _accounts = {}; + +function SyncInfo(url, id, password, mode, arg) { + var syncInfo, _id, _password, _internal_id; + syncInfo = this; + + function save() { + _accounts[_internal_id] = {id: _id, password: _password}; + db.saveObject("save-syncinfo", _accounts); + } + + _id = id; + _password = password; + _internal_id = _counter++; + + t.SyncMode(mode); + + syncInfo.url = url; + syncInfo.mode = mode; + + syncInfo.__defineSetter__("id", function (id) { + _id = id; + save(); + }); + syncInfo.__defineGetter__("id", function () { + return null; + }); + syncInfo.__defineSetter__("password", function (password) { + _password = password; + save(); + }); + syncInfo.__defineGetter__("password", function () { + return null; + }); + + Object.defineProperty(syncInfo, "__syncInfoID__", { + "configurable": false, + "enumerable": false, + "get": (function (_id_) { + return function () { return _id_; }; + })(_internal_id) + }); + + switch (mode) { + case "MANUAL": + if (arguments.length >= 5) { + t.SyncType(arg); + } + syncInfo.type = arg; + break; + case "PERIODIC": + t.SyncInterval(arg); + syncInfo.interval = arg; + break; + } + save(); + + return syncInfo; +} + +module.exports = SyncInfo; + +}); +define('ripple/platform/tizen/2.0/SyncProfileInfo', function (require, exports, module) { +/* + * Copyright 2013 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function SyncProfileInfo(profileName, syncInfo, serviceInfo) { + var profile = this; + + profile.profileName = profileName; + profile.syncInfo = syncInfo; + profile.serviceInfo = serviceInfo; + + return profile; +} + +module.exports = SyncProfileInfo; + +}); +define('ripple/platform/tizen/2.0/SyncServiceInfo', function (require, exports, module) { +/* + * Copyright 2013 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var db = require('ripple/db'), + t = require('ripple/platform/tizen/2.0/typecast'), + _counter = 0, + _accounts = {}; + +function SyncServiceInfo(enable, serviceType, serverDatabaseUri, id, password) { + var _id, _password, syncServiceInfo, _internal_id; + syncServiceInfo = this; + + function save() { + _accounts[_internal_id] = {id: _id, password: _password}; + db.saveObject("save-syncserviceinfo", _accounts); + } + + t.SyncServiceType(serviceType); + + if (id) { + _id = id; + } + + if (password) { + _password = password; + } + + _internal_id = _counter++; + + syncServiceInfo.enable = enable; + syncServiceInfo.serviceType = serviceType; + syncServiceInfo.serverDatabaseUri = serverDatabaseUri; + + syncServiceInfo.__defineSetter__("id", function (id) { + _id = id; + save(); + }); + + syncServiceInfo.__defineSetter__("password", function (password) { + _password = password; + save(); + }); + + syncServiceInfo.__defineGetter__("id", function () { + return null; + }); + + syncServiceInfo.__defineGetter__("password", function () { + return null; + }); + + Object.defineProperty(syncServiceInfo, "__syncServiceInfoID__", { + "configurable": false, + "enumerable": false, + "get": (function (_id_) { + return function () { return _id_; }; + })(_internal_id) + }); + + save(); + + return syncServiceInfo; +} + +module.exports = SyncServiceInfo; + +}); +define('ripple/platform/tizen/2.0/SyncStatistics', function (require, exports, module) { +/* + * Copyright 2013 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = function (syncStatus, serviceType, lastSyncTime, + serverToClientTotal, serverToClientAdded, serverToClientUpdated, serverToClientRemoved, + clientToServerTotal, clientToServerAdded, clientToServerUpdated, clientToServerRemoved) { + + var statistics = {}; + + statistics.__defineGetter__("syncStatus", function () { + return syncStatus; + }); + + statistics.__defineGetter__("serviceType", function () { + return serviceType; + }); + + statistics.__defineGetter__("lastSyncTime", function () { + return lastSyncTime; + }); + + statistics.__defineGetter__("serverToClientTotal", function () { + return serverToClientTotal; + }); + + statistics.__defineGetter__("serverToClientAdded", function () { + return serverToClientAdded; + }); + + statistics.__defineGetter__("serverToClientUpdated", function () { + return serverToClientUpdated; + }); + + statistics.__defineGetter__("serverToClientRemoved", function () { + return serverToClientRemoved; + }); + + statistics.__defineGetter__("clientToServerTotal", function () { + return clientToServerTotal; + }); + + statistics.__defineGetter__("clientToServerAdded", function () { + return clientToServerAdded; + }); + + statistics.__defineGetter__("clientToServerUpdated", function () { + return clientToServerUpdated; + }); + + statistics.__defineGetter__("clientToServerRemoved", function () { + return clientToServerRemoved; + }); + + return statistics; +}; + + +}); define('ripple/platform/tizen/2.0/TZDate', function (require, exports, module) { /* * Copyright 2012 Intel Corporation. @@ -75958,12 +77921,26 @@ var errorcode = require('ripple/platform/tizen/2.0/errorcode'), _Month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], _Day = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; -module.exports = function (dt) { +function TZDate (dt) { var d, UTCd, UTC_diff, tzid = "", target_diff, temp_date, time = require('ripple/platform/tizen/2.0/time'), hour = arguments[3] || 0, min = arguments[4] || 0, sec = arguments[5] || 0, msec = arguments[6] || 0, + _checkTZDate = function (dat) { + var Tzdate = require('ripple/platform/tizen/2.0/TZDate'), + i, tzd; + if (typeof dat !== 'object' || dat === undefined || dat === null) { + return false; + } + tzd = new Tzdate(); + for (i in tzd) { + if (dat.hasOwnProperty(i) === false) { + return false; + } + } + return true; + }, _d2UTCd_sync = function () { UTCd = new Date(d.valueOf() - (UTC_diff * 1000 * 60 * 60)); }, @@ -75991,7 +77968,8 @@ module.exports = function (dt) { if (dt === null || dt === undefined) { temp_date = new Date(); - target_diff = tz.getTimezoneDiff(time.getLocalTimezone()); + tzid = time.getLocalTimezone(); + target_diff = tz.getTimezoneDiff(tzid); d = new Date(temp_date.valueOf() + (target_diff + temp_date.getTimezoneOffset() / 60) * 1000 * 60 * 60); } else { if (tizen1_utils.isValidDate(dt)) { @@ -76000,344 +77978,354 @@ module.exports = function (dt) { tzid = arguments[1]; } } else { - d = new Date(arguments[0], arguments[1], arguments[2], hour, min, sec, msec); + if (arguments.length === 1) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } else { + d = new Date(arguments[0], arguments[1], arguments[2], hour, min, sec, msec); + } } } if (tz.isValidTimezone(tzid) === false) { - tzid = time.getLocalTimezone(); + tzid = 'UTC'; } UTC_diff = tz.getTimezoneDiff(tzid); _d2UTCd_sync(); - return { - getDate: function () { - return d.getDate(); - }, - setDate: function (dt) { - if (_int_range_check(dt, 1, 31)) { - d.setDate(dt); - _d2UTCd_sync(); - } - }, - getDay: function () { - return d.getDay(); - }, - getFullYear: function () { - return d.getFullYear(); - }, - setFullYear: function (yr) { - if (_int_range_check(yr, 1000, 9999)) { - d.setFullYear(yr); - _d2UTCd_sync(); - } - }, - getHours: function () { - return d.getHours(); - }, - setHours: function (hr) { - if (_int_range_check(hr, 0, 23)) { - d.setHours(hr); - _d2UTCd_sync(); - } - }, - getMilliseconds: function () { - return d.getMilliseconds(); - }, - setMilliseconds: function (msec) { - if (_int_range_check(msec, 0, 999)) { - d.setMilliseconds(msec); - _d2UTCd_sync(); - } - }, - getMinutes: function () { - return d.getMinutes(); - }, - setMinutes: function (min) { - if (_int_range_check(min, 0, 59)) { - d.setMinutes(min); - _d2UTCd_sync(); - } - }, - getMonth: function () { - return d.getMonth(); - }, - setMonth: function (m) { - if (_int_range_check(m, 0, 11)) { - d.setMonth(m); - _d2UTCd_sync(); - } - }, - getSeconds: function () { - return d.getSeconds(); - }, - setSeconds: function (s) { - if (_int_range_check(s, 0, 59)) { - d.setSeconds(s); - _d2UTCd_sync(); - } - }, - getUTCDate: function () { - return UTCd.getDate(); - }, - setUTCDate: function (dt) { - if (_int_range_check(dt, 1, 31)) { - UTCd.setDate(dt); - _UTCd2d_sync(); - } - }, - getUTCDay: function () { - return UTCd.getDay(); - }, - getUTCFullYear: function () { - return UTCd.getFullYear(); - }, - setUTCFullYear: function (yr) { - if (_int_range_check(yr, 1000, 9999)) { - UTCd.setFullYear(yr); - _UTCd2d_sync(); - } - }, - getUTCHours: function () { - return UTCd.getHours(); - }, - setUTCHours: function (hr) { - if (_int_range_check(hr, 0, 23)) { - UTCd.setHours(hr); - _UTCd2d_sync(); - } - }, - getUTCMilliseconds: function () { - return UTCd.getMilliseconds(); - }, - setUTCMilliseconds: function (msec) { - if (_int_range_check(msec, 0, 999)) { - UTCd.setMilliseconds(msec); - _UTCd2d_sync(); - } - }, - getUTCMinutes: function () { - return UTCd.getMinutes(); - }, - setUTCMinutes: function (min) { - if (_int_range_check(min, 0, 59)) { - UTCd.setMinutes(min); - _UTCd2d_sync(); - } - }, - getUTCMonth: function () { - return UTCd.getMonth(); - }, - setUTCMonth: function (m) { - if (_int_range_check(m, 0, 11)) { - UTCd.setMonth(m); - _UTCd2d_sync(); - } - }, - getUTCSeconds: function () { - return UTCd.getSeconds(); - }, - setUTCSeconds: function (s) { - if (_int_range_check(s, 0, 59)) { - UTCd.setSeconds(s); - _UTCd2d_sync(); - } - }, - getTimezone: function () { - return tzid; - }, - toTimezone: function (new_tzid) { - var diff, - Tzdate = require('ripple/platform/tizen/2.0/TZDate'); - if (typeof new_tzid !== 'string') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (tz.isValidTimezone(new_tzid) === true) { - diff = tz.getTimezoneDiff(new_tzid) - UTC_diff; - return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), new_tzid); - } else { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } - }, - toLocalTimezone: function () { - var diff, - Tzdate = require('ripple/platform/tizen/2.0/TZDate'), - localTzid = time.getLocalTimezone(); + this.getDate = function () { + return d.getDate(); + }; + this.setDate = function (dt) { + if (_int_range_check(dt, 1, 31)) { + d.setDate(dt); + _d2UTCd_sync(); + } + }; + this.getDay = function () { + return d.getDay(); + }; + this.getFullYear = function () { + return d.getFullYear(); + }; + this.setFullYear = function (yr) { + if (_int_range_check(yr, 1000, 9999)) { + d.setFullYear(yr); + _d2UTCd_sync(); + } + }; + this.getHours = function () { + return d.getHours(); + }; + this.setHours = function (hr) { + if (_int_range_check(hr, 0, 23)) { + d.setHours(hr); + _d2UTCd_sync(); + } + }; + this.getMilliseconds = function () { + return d.getMilliseconds(); + }; + this.setMilliseconds = function (msec) { + if (_int_range_check(msec, 0, 999)) { + d.setMilliseconds(msec); + _d2UTCd_sync(); + } + }; + this.getMinutes = function () { + return d.getMinutes(); + }; + this.setMinutes = function (min) { + if (_int_range_check(min, 0, 59)) { + d.setMinutes(min); + _d2UTCd_sync(); + } + }; + this.getMonth = function () { + return d.getMonth(); + }; + this.setMonth = function (m) { + if (_int_range_check(m, 0, 11)) { + d.setMonth(m); + _d2UTCd_sync(); + } + }; + this.getSeconds = function () { + return d.getSeconds(); + }; + this.setSeconds = function (s) { + if (_int_range_check(s, 0, 59)) { + d.setSeconds(s); + _d2UTCd_sync(); + } + }; + this.getUTCDate = function () { + return UTCd.getDate(); + }; + this.setUTCDate = function (dt) { + if (_int_range_check(dt, 1, 31)) { + UTCd.setDate(dt); + _UTCd2d_sync(); + } + }; + this.getUTCDay = function () { + return UTCd.getDay(); + }; + this.getUTCFullYear = function () { + return UTCd.getFullYear(); + }; + this.setUTCFullYear = function (yr) { + if (_int_range_check(yr, 1000, 9999)) { + UTCd.setFullYear(yr); + _UTCd2d_sync(); + } + }; + this.getUTCHours = function () { + return UTCd.getHours(); + }; + this.setUTCHours = function (hr) { + if (_int_range_check(hr, 0, 23)) { + UTCd.setHours(hr); + _UTCd2d_sync(); + } + }; + this.getUTCMilliseconds = function () { + return UTCd.getMilliseconds(); + }; + this.setUTCMilliseconds = function (msec) { + if (_int_range_check(msec, 0, 999)) { + UTCd.setMilliseconds(msec); + _UTCd2d_sync(); + } + }; + this.getUTCMinutes = function () { + return UTCd.getMinutes(); + }; + this.setUTCMinutes = function (min) { + if (_int_range_check(min, 0, 59)) { + UTCd.setMinutes(min); + _UTCd2d_sync(); + } + }; + this.getUTCMonth = function () { + return UTCd.getMonth(); + }; + this.setUTCMonth = function (m) { + if (_int_range_check(m, 0, 11)) { + UTCd.setMonth(m); + _UTCd2d_sync(); + } + }; + this.getUTCSeconds = function () { + return UTCd.getSeconds(); + }; + this.setUTCSeconds = function (s) { + if (_int_range_check(s, 0, 59)) { + UTCd.setSeconds(s); + _UTCd2d_sync(); + } + }; + this.getTimezone = function () { + return tzid; + }; + this.toTimezone = function (new_tzid) { + var diff, + Tzdate = require('ripple/platform/tizen/2.0/TZDate'); + if (typeof new_tzid !== 'string') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (tz.isValidTimezone(new_tzid) === true) { + diff = tz.getTimezoneDiff(new_tzid) - UTC_diff; + return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), new_tzid); + } else { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } + }; + this.toLocalTimezone = function () { + var diff, + localTzid, + Tzdate = require('ripple/platform/tizen/2.0/TZDate'); + localTzid = time.getLocalTimezone(); - diff = tz.getTimezoneDiff(localTzid) - UTC_diff; - return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), localTzid); - }, - toUTC: function () { - var Tzdate = require('ripple/platform/tizen/2.0/TZDate'); - return new Tzdate(UTCd, "UTC"); - }, - difference: function (other) { - var diff, - TDur = require('ripple/platform/tizen/2.0/TimeDuration'); - if (typeof other !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - diff = (UTCd.valueOf() - _getValue(other)); - return new TDur(diff).difference(new TDur(0)); - }, - equalsTo: function (other) { - if (typeof other !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - return (UTCd.valueOf() === _getValue(other)); - }, - earlierThan: function (other) { - if (typeof other !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - return (UTCd.valueOf() < _getValue(other)); - }, - laterThan: function (other) { - if (typeof other !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - return (UTCd.valueOf() > _getValue(other)); - }, - addDuration: function (dur) { - var Tzdate = require('ripple/platform/tizen/2.0/TZDate'), - Tunit = {"MSECS": 1, - "SECS": 1000, - "MINS": 60 * 1000, - "HOURS": 60 * 60 * 1000, - "DAYS": 24 * 60 * 60 * 1000 - }; - if (typeof dur !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (dur.length === undefined || dur.length === null || + diff = tz.getTimezoneDiff(localTzid) - UTC_diff; + return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), localTzid); + }; + this.toUTC = function () { + var Tzdate = require('ripple/platform/tizen/2.0/TZDate'); + return new Tzdate(UTCd, "UTC"); + }; + this.difference = function (other) { + var diff, + TDur = require('ripple/platform/tizen/2.0/TimeDuration'); + if (_checkTZDate(other) === false) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + diff = (UTCd.valueOf() - _getValue(other)); + if (diff % 86400000 === 0) { + return new TDur(diff/86400000, 'DAYS'); + } else { + return new TDur(diff); + } + }; + this.equalsTo = function (other) { + if (_checkTZDate(other) === false) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + return (UTCd.valueOf() === _getValue(other)); + }; + this.earlierThan = function (other) { + if (_checkTZDate(other) === false) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + return (UTCd.valueOf() < _getValue(other)); + }; + this.laterThan = function (other) { + if (_checkTZDate(other) === false) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + return (UTCd.valueOf() > _getValue(other)); + }; + this.addDuration = function (dur) { + var Tzdate = require('ripple/platform/tizen/2.0/TZDate'), + Tunit = {"MSECS": 1, + "SECS": 1000, + "MINS": 60 * 1000, + "HOURS": 60 * 60 * 1000, + "DAYS": 24 * 60 * 60 * 1000 + }; + if (typeof dur !== 'object' || dur === undefined || dur === null) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (dur.length === undefined || dur.length === null || dur.unit === undefined || dur.unit === null) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if ((typeof dur.length) !== 'number') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (Tunit[dur.unit] === undefined) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - return new Tzdate(new Date(d.valueOf() + (dur.length * Tunit[dur.unit])), tzid); - }, - toLocaleDateString: function () { - if (d.toString() === "Invalid Date") { - return d.toString(); - } else { - return this.toDateString() + " (" + tz.getTimezoneAbbr(tzid) + ")"; - } - }, - toLocaleTimeString: function () { - if (d.toString() === "Invalid Date") { - return d.toString(); - } else { - return this.toTimeString() + " (" + tz.getTimezoneAbbr(tzid) + ")"; - } - }, - toLocaleString: function () { - if (d.toString() === "Invalid Date") { - return d.toString(); - } else { - return this.toString() + " (" + tz.getTimezoneAbbr(tzid) + ")"; - } - }, - toDateString: function () { - var i, ret = "", fmt = time.getDateFormat(); - if (d.toString() === "Invalid Date") { - return d.toString(); - } - for (i = 0; i < fmt.length; i++) { - switch (fmt.charAt(i)) { - case 'd': - ret = ret + d.getDate(); - break; - case 'y': - ret = ret + d.getFullYear(); - break; - case 'm': - ret = ret + (d.getMonth() + 1); - break; - case 'M': - ret = ret + _Month[d.getMonth()]; - break; - case 'D': - ret = ret + _Day[d.getDay()]; - break; - default: - ret = ret + fmt.charAt(i); - } + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((typeof dur.length) !== 'number') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (Tunit[dur.unit] === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + return new Tzdate(new Date(d.valueOf() + (parseInt(dur.length, 10) * Tunit[dur.unit])), tzid); + }; + this.toLocaleDateString = function () { + if (d.toString() === "Invalid Date") { + return d.toString(); + } else { + return this.toDateString() + " (" + tz.getTimezoneAbbr(tzid) + ")"; + } + }; + this.toLocaleTimeString = function () { + if (d.toString() === "Invalid Date") { + return d.toString(); + } else { + return this.toTimeString() + " (" + tz.getTimezoneAbbr(tzid) + ")"; + } + }; + this.toLocaleString = function () { + if (d.toString() === "Invalid Date") { + return d.toString(); + } else { + return this.toString() + " (" + tz.getTimezoneAbbr(tzid) + ")"; + } + }; + this.toDateString = function () { + var i, ret = "", fmt = time.getDateFormat(); + if (d.toString() === "Invalid Date") { + return d.toString(); + } + for (i = 0; i < fmt.length; i++) { + switch (fmt.charAt(i)) { + case 'd': + ret = ret + d.getDate(); + break; + case 'y': + ret = ret + d.getFullYear(); + break; + case 'm': + ret = ret + (d.getMonth() + 1); + break; + case 'M': + ret = ret + _Month[d.getMonth()]; + break; + case 'D': + ret = ret + _Day[d.getDay()]; + break; + default: + ret = ret + fmt.charAt(i); } - return ret; - }, - toTimeString: function () { - var i, hh, mm, ss, AP, - ret = "", fmt = time.getTimeFormat(); + } + return ret; + }; + this.toTimeString = function () { + var i, hh, mm, ss, AP, + ret = "", fmt = time.getTimeFormat(); - if (d.toString() === "Invalid Date") { - return d.toString(); - } + if (d.toString() === "Invalid Date") { + return d.toString(); + } - if (fmt.search(/ap/) === -1) { - AP = false; + if (fmt.search(/ap/) === -1) { + AP = false; + } else { + AP = true; + if (d.getHours() > 11) { + fmt = fmt.replace("ap", "PM"); } else { - AP = true; - if (d.getHours() > 11) { - fmt = fmt.replace("ap", "PM"); - } else { - fmt = fmt.replace("ap", "AM"); - } + fmt = fmt.replace("ap", "AM"); } - for (i = 0; i < fmt.length; i++) { - switch (fmt.charAt(i)) { - case 'h': - hh = d.getHours(); - if (AP) { - hh = (hh > 12) ? hh - 12 : hh; - } - hh = (hh < 10 ? "0" : "") + hh; - ret = ret + hh; - break; - case 'm': - mm = d.getMinutes(); - mm = (mm < 10 ? "0" : "") + mm; - ret = ret + mm; - break; - case 's': - ss = d.getSeconds(); - ss = (ss < 10 ? "0" : "") + ss; - ret = ret + ss; - break; - default: - ret = ret + fmt.charAt(i); + } + for (i = 0; i < fmt.length; i++) { + switch (fmt.charAt(i)) { + case 'h': + hh = d.getHours(); + if (AP) { + hh = (hh > 12) ? hh - 12 : hh; } + hh = (hh < 10 ? "0" : "") + hh; + ret = ret + hh; + break; + case 'm': + mm = d.getMinutes(); + mm = (mm < 10 ? "0" : "") + mm; + ret = ret + mm; + break; + case 's': + ss = d.getSeconds(); + ss = (ss < 10 ? "0" : "") + ss; + ret = ret + ss; + break; + default: + ret = ret + fmt.charAt(i); } - return ret; - }, - toString: function () { - if (d.toString() === "Invalid Date") { - return d.toString(); - } else { - return (this.toDateString() + " " + this.toTimeString()); - } - }, - getTimezoneAbbreviation: function () { - return tz.getTimezoneAbbr(tzid); - }, - secondsFromUTC: function () { - return (-1 * UTC_diff * 60 * 60); - }, - isDST: function () { - throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR)); - }, - getPreviousDSTTransition: function () { - throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR)); - }, - getNextDSTTransition: function () { - throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR)); + } + return ret; + }; + this.toString = function () { + if (d.toString() === "Invalid Date") { + return d.toString(); + } else { + return (this.toDateString() + " " + this.toTimeString()); } }; -}; + this.getTimezoneAbbreviation = function () { + return tz.getTimezoneAbbr(tzid); + }; + this.secondsFromUTC = function () { + return (-1 * UTC_diff * 60 * 60); + }; + this.isDST = function () { + throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR)); + }; + this.getPreviousDSTTransition = function () { + throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR)); + }; + this.getNextDSTTransition = function () { + throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR)); + }; + return this; +} + +module.exports = TZDate; }); define('ripple/platform/tizen/2.0/TimeDuration', function (require, exports, module) { @@ -76360,7 +78348,7 @@ define('ripple/platform/tizen/2.0/TimeDuration', function (require, exports, mod var errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'); -module.exports = function (l, u) { +function TimeDuration(l, u) { var _length, _unit, TimeDurationUnit = {"MSECS": 1, "SECS": 1000, @@ -76407,87 +78395,89 @@ module.exports = function (l, u) { } else { _unit = "MSECS"; } - return { - length: _length, - unit: _unit, - difference: function (o) { - if (typeof o !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (o.length === undefined || o.length === null || - o.unit === undefined || o.unit === null) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if ((typeof o.length) !== 'number') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (TimeDurationUnit[o.unit] === undefined) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - var thisMS = _length * _toMSECS(_unit), - otherMS = o.length * _toMSECS(o.unit); - return _simplifyDuration(thisMS - otherMS); - }, - equalsTo: function (o) { - if (typeof o !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (o.length === undefined || o.length === null || + this.length = _length; + this.unit = _unit; + this.difference = function (o) { + if (typeof o !== 'object' || o === null || o === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (o.length === undefined || o.length === null || o.unit === undefined || o.unit === null) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if ((typeof o.length) !== 'number') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (TimeDurationUnit[o.unit] === undefined) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((typeof o.length) !== 'number') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (TimeDurationUnit[o.unit] === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } - var thisMS = _length * _toMSECS(_unit), - otherMS = o.length * _toMSECS(o.unit); - return (thisMS === otherMS); - }, - lessThan: function (o) { - if (typeof o !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (o.length === undefined || o.length === null || + var thisMS = _length * _toMSECS(_unit), + otherMS = o.length * _toMSECS(o.unit); + return _simplifyDuration(thisMS - otherMS); + }; + this.equalsTo = function (o) { + if (typeof o !== 'object' || o === null || o === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (o.length === undefined || o.length === null || o.unit === undefined || o.unit === null) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if ((typeof o.length) !== 'number') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (TimeDurationUnit[o.unit] === undefined) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((typeof o.length) !== 'number') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (TimeDurationUnit[o.unit] === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } - var thisMS = _length * _toMSECS(_unit), - otherMS = o.length * _toMSECS(o.unit); - return (thisMS < otherMS); - }, - greaterThan: function (o) { - if (typeof o !== 'object') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (o.length === undefined || o.length === null || + var thisMS = _length * _toMSECS(_unit), + otherMS = o.length * _toMSECS(o.unit); + return (thisMS === otherMS); + }; + this.lessThan = function (o) { + if (typeof o !== 'object' || o === null || o === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (o.length === undefined || o.length === null || o.unit === undefined || o.unit === null) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if ((typeof o.length) !== 'number') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (TimeDurationUnit[o.unit] === undefined) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((typeof o.length) !== 'number') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (TimeDurationUnit[o.unit] === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } - var thisMS = _length * _toMSECS(_unit), - otherMS = o.length * _toMSECS(o.unit); - return (thisMS > otherMS); + var thisMS = _length * _toMSECS(_unit), + otherMS = o.length * _toMSECS(o.unit); + return (thisMS < otherMS); + }; + this.greaterThan = function (o) { + if (typeof o !== 'object' || o === null || o === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } + if (o.length === undefined || o.length === null || + o.unit === undefined || o.unit === null) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((typeof o.length) !== 'number') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (TimeDurationUnit[o.unit] === undefined) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + + var thisMS = _length * _toMSECS(_unit), + otherMS = o.length * _toMSECS(o.unit); + return (thisMS > otherMS); }; -}; + return this; +} + +module.exports = TimeDuration; }); define('ripple/platform/tizen/2.0/WebAPIError', function (require, exports, module) { @@ -76807,7 +78797,7 @@ _self = { getAccounts : function () { var results = []; utils.forEach(_data.accounts, function (account) { - results.push(utils.copy(account)); + results.push(utils.copy(account)); }); return results; @@ -76977,11 +78967,8 @@ var db = require('ripple/db'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), event = require('ripple/event'), utils = require('ripple/utils'), - t = require('ripple/platform/tizen/2.0/typedef'), - tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), + t = require('ripple/platform/tizen/2.0/typecast'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - Alarm = require('ripple/platform/tizen/2.0/AlarmBase'), AlarmRelative = require('ripple/platform/tizen/2.0/AlarmRelative'), AlarmAbsolute = require('ripple/platform/tizen/2.0/AlarmAbsolute'), AlarmStore, @@ -76992,8 +78979,7 @@ var db = require('ripple/db'), PERIOD_WEEK = 7 * PERIOD_DAY, _alarms = {}, _alarmStack = [], _security = { - "http://tizen.org/privilege/alarm": ["add", "remove", "removeAll"], - all: true + "http://tizen.org/privilege/alarm": ["add", "remove", "removeAll"] }, _isInitialized = false, _self; @@ -77057,7 +79043,10 @@ function _convertToAlarm(alarmStore) { } alarm = new AlarmAbsolute(alarmStore.date, frequency); } - alarm.id = alarmStore.id; + + alarm.__defineGetter__("id", function () { + return alarmStore.id; + }); return alarm; } @@ -77091,30 +79080,35 @@ _self = function () { alarm = { add: function (alarm, applicationId, appControl) { - var alarmStore; + var alarmStore, external = alarm; - if (!_security.all && !_security.add) { - throw (new WebAPIException(errorcode.SECURITY_ERR)); - } - if (!(new TypeCoerce(t.Alarm)).match(alarm) || - !(new TypeCoerce(t.ApplicationId)).match(applicationId) || - (appControl && !(new TypeCoerce(t.ApplicationControl)).match(appControl))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + if (!_security.add) { + throw new WebAPIException(errorcode.SECURITY_ERR); } + + alarm = t.Alarm(alarm); + applicationId = t.ApplicationId(applicationId); + appControl = t.ApplicationControl(appControl, "?"); + + alarm.id = Math.uuid(null, 16); currentAppId = _getCurrentAppId(); // Update The Current URL. alarmStore = new AlarmStore(alarm, applicationId, currentAppId, appControl); _updateDB(alarmStore); + + external.__defineGetter__("id", function () { + return alarm.id; + }); }, remove: function (id) { var isFound = false, i; - if (!_security.all && !_security.remove) { - throw (new WebAPIException(errorcode.SECURITY_ERR)); - } - if (!(new TypeCoerce(t.AlarmId)).match(id)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + if (!_security.remove) { + throw new WebAPIException(errorcode.SECURITY_ERR); } + + id = t.AlarmId(id); + for (i in _alarmStack) { if (_alarmStack[i].id !== id) continue; @@ -77123,15 +79117,17 @@ _self = function () { _save(); isFound = true; } - if (!isFound) - throw (new WebAPIException(errorcode.NOT_FOUND_ERR)); + + if (!isFound) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } }, removeAll: function () { var availableStack = [], i; - if (!_security.all && !_security.removeAll) - throw (new WebAPIException(errorcode.SECURITY_ERR)); + if (!_security.removeAll) + throw new WebAPIException(errorcode.SECURITY_ERR); for (i in _alarmStack) { if (_alarmStack[i].currentAppId === currentAppId) @@ -77146,9 +79142,8 @@ _self = function () { get: function (id) { var isFound = false, item, isExpired, alarm; - if (!(new TypeCoerce(t.AlarmId)).match(id)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + id = t.AlarmId(id); + for (item in _alarmStack) { if (_alarmStack[item].id === id) { alarm = _convertToAlarm(_alarmStack[item]); @@ -77162,8 +79157,9 @@ _self = function () { break; } } - if (!isFound) - throw (new WebAPIException(errorcode.NOT_FOUND_ERR)); + if (!isFound) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } return alarm; }, @@ -77190,11 +79186,6 @@ _self = function () { var i, subFeature; for (subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; for (i in _security[subFeature]) { _security[_security[subFeature][i]] = true; } @@ -77278,8 +79269,7 @@ var utils = require('ripple/utils'), _security = { "http://tizen.org/privilege/application.launch": ["launch", "launchAppControl"], "http://tizen.org/privilege/appmanager.kill": ["kill"], - "http://tizen.org/privilege/appmanager.certificate": ["getAppCerts"], - all: true + "http://tizen.org/privilege/appmanager.certificate": ["getAppCerts"] }, _data = { applications : {}, @@ -77305,6 +79295,7 @@ function _setupCurrentApp() { categories: [], installDate: new Date(), size: 1024, + packageId: "sample0123", sharedURI: "/usr/local/share/", operation: "", appControl: { @@ -77320,14 +79311,26 @@ function _setupCurrentApp() { _data.activeApp = _data.applicationContexts[contextId]; } +function _translate(apps) { + // translate string to Date after retrieving from DB, + // it is a temporary sulusion + var i; + for (i in apps) { + if (typeof apps[i].installDate === 'string') { + apps[i].installDate = new Date(apps[i].installDate); + } + } + return apps; +} + function _initialize() { _data = { applications : {}, applicationContexts : {}, activeApp : null, listeners : {} - }, - _data.applications = db.retrieveObject(_DB_APPLICATION_KEY).installedAppList; + }; + _data.applications = _translate(db.retrieveObject(_DB_APPLICATION_KEY).installedAppList); _setupCurrentApp(); $("#app-dialog").dialog({ resizable: false, @@ -77373,13 +79376,14 @@ _self = function () { innerApp.show, innerApp.categories, innerApp.installDate, - innerApp.size), + innerApp.size, + innerApp.packageId), _data.activeApp.id, innerApp); return application; } function kill(contextId, successCallback, errorCallback) { - if (!_security.all && !_security.kill) { + if (!_security.kill) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -77412,7 +79416,7 @@ _self = function () { function launch(id, successCallback, errorCallback) { var htmlContent; - if (!_security.all && !_security.launch) { + if (!_security.launch) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -77441,7 +79445,7 @@ _self = function () { function launchAppControl(appControl, id, successCallback, errorCallback, replyCallback) { var isFound, appId, htmlContent; - if (!_security.all && !_security.launchAppControl) { + if (!_security.launchAppControl) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -77547,7 +79551,8 @@ _self = function () { application.show, application.categories, application.installDate, - application.size)); + application.size, + application.packageId)); } }); if (informationArray.length === 0) { @@ -77614,7 +79619,8 @@ _self = function () { application.show, application.categories, application.installDate, - application.size)); + application.size, + application.packageId)); }); setTimeout(successCallback(appsInfo), 1); } @@ -77622,7 +79628,7 @@ _self = function () { function getAppInfo(id) { var appId, appInfo, theApp; - if (id === null) { + if (arguments.length === 0) { appId = _data.activeApp.appId; theApp = _data.applications[appId]; @@ -77634,7 +79640,8 @@ _self = function () { theApp.show, theApp.categories, theApp.installDate, - theApp.size); + theApp.size, + theApp.packageId); return appInfo; } @@ -77655,14 +79662,15 @@ _self = function () { theApp.show, theApp.categories, theApp.installDate, - theApp.size); + theApp.size, + theApp.packageId); return appInfo; } function getAppCerts(id) { var certs = []; - if (!_security.all && !_security.getAppCerts) { + if (!_security.getAppCerts) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -77731,15 +79739,12 @@ _self = function () { } function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); } } @@ -77803,7 +79808,8 @@ event.on("programChanged", function (status, id) { innerApp.show, innerApp.categories, innerApp.installDate, - innerApp.size); + innerApp.size, + innerApp.packageId); break; case "uninstalled": data = id; @@ -78071,8 +80077,7 @@ var utils = require('ripple/utils'), "http://tizen.org/privilege/bluetoothmanager": ["setVisible"], "http://tizen.org/privilege/bluetooth.admin": ["setName", "setPowered"], "http://tizen.org/privilege/bluetooth.gap": ["getDefaultAdapter", "discoverDevices", "stopDiscovery", "getKnownDevices", "getDevice", "createBonding", "destroyBonding", "hasService"], - "http://tizen.org/privilege/bluetooth.spp": ["registerRFCOMMServiceByUUID", "connectToServiceByUUID", "writeData", "readData", "close", "unregister"], - all: true + "http://tizen.org/privilege/bluetooth.spp": ["registerRFCOMMServiceByUUID", "connectToServiceByUUID", "writeData", "readData", "close", "unregister"] }, _self; @@ -78152,7 +80157,7 @@ BluetoothAdapter = function (devName, devAddress) { // public function setName(name, successCallback, errorCallback) { - if (!_security.all && !_security.setName) { + if (!_security.setName) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78178,7 +80183,7 @@ BluetoothAdapter = function (devName, devAddress) { } function setPowered(state, successCallback, errorCallback) { - if (!_security.all && !_security.setPowered) { + if (!_security.setPowered) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78197,7 +80202,7 @@ BluetoothAdapter = function (devName, devAddress) { function setVisible(mode, successCallback, errorCallback, timeout) { var time; - if (!_security.all && !_security.setVisible) { + if (!_security.setVisible) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78232,7 +80237,7 @@ BluetoothAdapter = function (devName, devAddress) { function discoverDevices(successCallback, errorCallback) { var interval; - if (!_security.all && !_security.discoverDevices) { + if (!_security.discoverDevices) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78298,7 +80303,7 @@ BluetoothAdapter = function (devName, devAddress) { } function stopDiscovery(successCallback, errorCallback) { - if (!_security.all && !_security.stopDiscovery) { + if (!_security.stopDiscovery) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78323,7 +80328,7 @@ BluetoothAdapter = function (devName, devAddress) { function getKnownDevices(successCallback, errorCallback) { var devs = []; - if (!_security.all && !_security.getKnownDevices) { + if (!_security.getKnownDevices) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78348,7 +80353,7 @@ BluetoothAdapter = function (devName, devAddress) { } function getDevice(address, successCallback, errorCallback) { - if (!_security.all && !_security.getDevice) { + if (!_security.getDevice) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78379,7 +80384,7 @@ BluetoothAdapter = function (devName, devAddress) { } function createBonding(address, successCallback, errorCallback) { - if (!_security.all && !_security.createBonding) { + if (!_security.createBonding) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78412,7 +80417,7 @@ BluetoothAdapter = function (devName, devAddress) { } function destroyBonding(address, successCallback, errorCallback) { - if (!_security.all && !_security.destroyBonding) { + if (!_security.destroyBonding) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78442,7 +80447,7 @@ BluetoothAdapter = function (devName, devAddress) { } function registerRFCOMMServiceByUUID(uuid, name, successCallback, errorCallback, securityLevel) { - if (!_security.all && !_security.registerRFCOMMServiceByUUID) { + if (!_security.registerRFCOMMServiceByUUID) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78513,6 +80518,10 @@ BluetoothAdapter = function (devName, devAddress) { } }); + event.on("bt-power-setting", function (status) { + _updatePowerStatus(status); + }); + adapter = { setName : setName, setPowered : setPowered, @@ -78546,7 +80555,7 @@ _initialize(); _self = function () { function getDefaultAdapter() { - if (!_security.all && !_security.getDefaultAdapter) { + if (!_security.getDefaultAdapter) { throw new WebAPIError(errorcode.SECURITY_ERR); } @@ -78562,15 +80571,12 @@ _self = function () { } function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); } } @@ -78614,9 +80620,8 @@ define('ripple/platform/tizen/2.0/bookmark', function (require, exports, module) var db = require('ripple/db'), utils = require('ripple/utils'), - t = require('ripple/platform/tizen/2.0/typedef'), + t = require('ripple/platform/tizen/2.0/typecast'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), BookmarkFolder = require('ripple/platform/tizen/2.0/BookmarkFolder'), BookmarkItem = require('ripple/platform/tizen/2.0/BookmarkItem'), @@ -78630,8 +80635,7 @@ var db = require('ripple/db'), }, _security = { "http://tizen.org/privilege/bookmark.read": ["get"], - "http://tizen.org/privilege/bookmark.write": ["add", "remove"], - all: true + "http://tizen.org/privilege/bookmark.write": ["add", "remove"] }, _self; @@ -78758,27 +80762,16 @@ _self = function () { return false; } - function validate(obj) { - if (obj.title === "") - return false; - - if (("url" in obj) && (obj.url === "")) - return false; - - return true; - } - // public function get(parentFolder, recursive) { var bookmarks = [], parent, peers; - if (!_security.all && !_security.get) { + if (!_security.get) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if ((parentFolder && !(new TypeCoerce(t.BookmarkFolder)).match(parentFolder)) || - (recursive && !(new TypeCoerce(t.boolean)).match(recursive))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + parentFolder = t.BookmarkFolder(parentFolder, "?"); + recursive = t.boolean(recursive, "?"); parent = map(parentFolder); if ((parent === undefined) || (parent && !_isFolder(parent))) { @@ -78793,17 +80786,13 @@ _self = function () { function add(bookmark, parentFolder) { var parent, peers; - if (!_security.all && !_security.add) { + if (!_security.add) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.Bookmark)).match(bookmark) || - (parentFolder && !(new TypeCoerce(t.BookmarkFolder)).match(parentFolder))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!validate(bookmark)) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + bookmark = t.Bookmark(bookmark); + parentFolder = t.BookmarkFolder(parentFolder, "?"); + parent = map(parentFolder); if ((parent === undefined) || (parent && !_isFolder(parent))) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); @@ -78823,12 +80812,11 @@ _self = function () { } function remove(bookmark) { - if (!_security.all && !_security.remove) { + if (!_security.remove) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (bookmark && !(new TypeCoerce(t.Bookmark)).match(bookmark)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + bookmark = t.Bookmark(bookmark, "?"); if (!bookmark) { _data.bookmarks = []; @@ -78848,11 +80836,6 @@ _self = function () { var i, subFeature; for (subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; for (i in _security[subFeature]) { _security[_security[subFeature][i]] = true; } @@ -78954,9 +80937,9 @@ var utils = require('ripple/utils'), }, _calendarsStorage, _security = { - "http://tizen.org/privilege/calendar.read": ["getCalendars", "getDefaultCalendar", "getCalendar", "get", "find", "addChangeListener", "removeChangeListener"], - "http://tizen.org/privilege/calendar.write": ["add", "addBatch", "update", "updateBatch", "remove", "removeBatch"], - all: true + "http://tizen.org/privilege/calendar.read": ["getCalendars", "getDefaultCalendar", "getCalendar", "get", "find", + "addChangeListener", "removeChangeListener", "expandRecurrence", "convertToString", "clone"], + "http://tizen.org/privilege/calendar.write": ["add", "addBatch", "update", "updateBatch", "remove", "removeBatch"] }, _self; @@ -79007,7 +80990,7 @@ _self = function () { // public function getCalendars(type, successCallback, errorCallback) { - if (!_security.all && !_security.getCalendars) { + if (!_security.getCalendars) { throw new WebAPIException(errorcode.SECURITY_ERR); } @@ -79025,9 +81008,13 @@ _self = function () { for (i in _calendars[type]) { result.push(_calendars[type][i]); } - successCallback(result); + window.setTimeout(function () { + successCallback(result); + }, 1); } else if (errorCallback) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); + window.setTimeout(function () { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); + }, 1); } } @@ -79037,7 +81024,7 @@ _self = function () { function getDefaultCalendar(type) { var id, calendar; - if (!_security.all && !_security.getDefaultCalendar) { + if (!_security.getDefaultCalendar) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (!isValidType(type)) @@ -79061,7 +81048,7 @@ _self = function () { function getCalendar(type, id) { var calendar; - if (!_security.all && !_security.getCalendar) { + if (!_security.getCalendar) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (!isValidType(type) || !_isValidId(id)) @@ -79079,14 +81066,9 @@ _self = function () { } function handleSubFeatures(subFeatures) { - var subFeature, i; + var i, subFeature; for (subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; for (i in _security[subFeature]) { _security[_security[subFeature][i]] = true; } @@ -79104,7 +81086,8 @@ _self = function () { }; Calendar = function (type, name, storageItems, id) { - var privateItems = {}; + var privateItems = {}, + defaultWatchId = 0; id = id || Math.uuid(null, 16); // private @@ -79165,10 +81148,17 @@ Calendar = function (type, name, storageItems, id) { calendarItem.availability = utils.copy(storageItem.availability); calendarItem.recurrenceRule = utils.copy(storageItem.recurrenceRule); calendarItem.expandRecurrence = function (startDate, endDate, successCallback, errorCallback) { + if (!_security.expandRecurrence) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + calendarItem.startDate = startDate; calendarItem.endDate = endDate; + if (errorCallback) { - errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR)); + window.setTimeout(function () { + errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR)); + }, 1); } }; calendarItem.frequency = utils.copy(storageItem.frequency); @@ -79183,7 +81173,7 @@ Calendar = function (type, name, storageItems, id) { function loadCalendarTaskInit(calendarItem, storageItem) { loadCalendarItemInit(calendarItem, storageItem); - calendarItem.endDate = new TZDate(new Date(storageItem.endDate)); + calendarItem.dueDate = new TZDate(new Date(storageItem.dueDate)); calendarItem.completedDate = storageItem.completedDate ? new TZDate(new Date(storageItem.completedDate)):storageItem.completedDate; calendarItem.progress = utils.copy(storageItem.progress); } @@ -79195,7 +81185,7 @@ Calendar = function (type, name, storageItems, id) { return; for (i in storageItems) { - calendarItem = new CalendarItem(type, i, new TZDate(new Date(storageItems[i].lastModificationDate))); + calendarItem = new CalendarItem(type, i, new TZDate(new Date(storageItems[i].lastModificationDate)), _security); if (type === "EVENT") { loadCalendarEventInit(calendarItem, storageItems[i]); @@ -79208,6 +81198,7 @@ Calendar = function (type, name, storageItems, id) { } function saveCalendarItems() { + _calendarsStorage[type][id] || (_calendarsStorage[type][id] = {}); _calendarsStorage[type][id].items = new CalendarItemsStorage(privateItems); saveCalendars(); } @@ -79216,13 +81207,13 @@ Calendar = function (type, name, storageItems, id) { function get(id) { var uid; - if (!_security.all && !_security.get) { + if (!_security.get) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!isValidCalendarItemId(id)) + uid = (type === "EVENT") ? id.uid : id; + if (!isValidCalendarItemId(uid)) throw new WebAPIException(errorcode.NOT_FOUND_ERR); - uid = (type === "EVENT") ? id.uid : id; return privateItems[uid]; } @@ -79230,9 +81221,14 @@ Calendar = function (type, name, storageItems, id) { function add(item) { var uid; - if (!_security.all && !_security.add) { + if (!_security.add) { throw new WebAPIException(errorcode.SECURITY_ERR); } + // set the calendarId of the item + item.__defineGetter__("calendarId", function () { + return id; + }); + // typecoerce uid = (type === "EVENT") ? item.id.uid : item.id; privateItems[uid] = utils.copy(item); @@ -79247,7 +81243,7 @@ Calendar = function (type, name, storageItems, id) { } function addBatch(items, successCallback, errorCallback) { - if (!_security.all && !_security.addBatch) { + if (!_security.addBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } tizen1_utils.validateCallbackType(successCallback, errorCallback); @@ -79276,7 +81272,7 @@ Calendar = function (type, name, storageItems, id) { function update(item, updateAllInstances) { var calendarItem, attr, uid; - if (!_security.all && !_security.update) { + if (!_security.update) { throw new WebAPIException(errorcode.SECURITY_ERR); } // typecoerce item, updateAllInstances @@ -79319,7 +81315,7 @@ Calendar = function (type, name, storageItems, id) { } function updateBatch(items, successCallback, errorCallback, updateAllInstances) { - if (!_security.all && !_security.updateBatch) { + if (!_security.updateBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } tizen1_utils.validateCallbackType(successCallback, errorCallback); @@ -79389,7 +81385,7 @@ Calendar = function (type, name, storageItems, id) { function remove(id) { var isFound = false, i, uid; - if (!_security.all && !_security.remove) { + if (!_security.remove) { throw new WebAPIException(errorcode.SECURITY_ERR); } @@ -79417,7 +81413,7 @@ Calendar = function (type, name, storageItems, id) { } function removeBatch(ids, successCallback, errorCallback) { - if (!_security.all && !_security.removeBatch) { + if (!_security.removeBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } tizen1_utils.validateCallbackType(successCallback, errorCallback); @@ -79456,7 +81452,7 @@ Calendar = function (type, name, storageItems, id) { } function find(successCallback, errorCallback, filter, sortMode) { - if (!_security.all && !_security.find) { + if (!_security.find) { throw new WebAPIException(errorcode.SECURITY_ERR); } @@ -79466,9 +81462,12 @@ Calendar = function (type, name, storageItems, id) { for (i in privateItems) { calendarItems.push(privateItems[i]); } - - result = tizen1_utils.query(calendarItems, filter, sortMode); - successCallback(result); + if (calendarItems.length > 0) { + result = tizen1_utils.query(calendarItems, filter, sortMode); + } + window.setTimeout(function () { + successCallback(result); + }, 1); } tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "calendar:find", _find); @@ -79477,7 +81476,7 @@ Calendar = function (type, name, storageItems, id) { function addChangeListener(successCallback) { var watchId; - if (!_security.all && !_security.addChangeListener) { + if (!_security.addChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } if ((typeof successCallback !== "object") || @@ -79486,14 +81485,14 @@ Calendar = function (type, name, storageItems, id) { (typeof successCallback.onitemsremoved !== "function")) throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - watchId = Math.uuid(null, 16); + watchId = ++defaultWatchId; _watchers[watchId] = successCallback; return watchId; } function removeChangeListener(watchId) { - if (!_security.all && !_security.removeChangeListener) { + if (!_security.removeChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (!_isValidId(watchId)) @@ -79537,8 +81536,13 @@ CalendarItemsStorage = function (privateItems) { for (i in privateItems) { itemsStorage[i] = {}; for (attr in privateItems[i]) { - if ((attr === "startDate" || attr === "endDate" || attr === "untilDate" || attr === "completedDate" || attr === "lastModificationDate") && + //TODO: should be + // if (privateItems[i][attr] instanceof TZDate) { + //But, we used "utils.copy" before store the item to privateItems list. + //So the constructor information all lost + if ((attr === "startDate" || attr === "endDate" || attr === "dueDate" || attr === "completedDate" || attr === "lastModificationDate") && (privateItems[i][attr])) { + itemsStorage[i][attr] = privateItems[i][attr].toString(); } else if (typeof privateItems[i] !== "function") { itemsStorage[i][attr] = privateItems[i][attr]; @@ -79575,6 +81579,8 @@ var utils = require('ripple/utils'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + t = require('ripple/platform/tizen/2.0/typedef'), + TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), _DB_CALL_KEY = "tizen1-db-callhistory", _data = { @@ -79583,8 +81589,7 @@ var utils = require('ripple/utils'), }, _security = { "http://tizen.org/privilege/callhistory.read": ["find", "addChangeListener", "removeChangeListener"], - "http://tizen.org/privilege/callhistory.write": ["remove", "removeBatch", "removeAll"], - all: true + "http://tizen.org/privilege/callhistory.write": ["remove", "removeBatch", "removeAll"] }, _self; @@ -79609,23 +81614,30 @@ function _filter(inputArray, filter) { return inputArray; } + if (filter.type && filter.filters) { + filterResults = _filter(inputArray, filter.filters[0]); + for (index = 1; index < filter.filters.length; index++) { + compositeResultArray = _filter(inputArray, filter.filters[index]); + + filterResults = tizen1_utils.arrayComposite(filter.type, filterResults, compositeResultArray); + } + return filterResults; + } + if (filter.attributeName === null || filter.attributeName === undefined) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } if (filter.matchFlag) { - filterResults = tizen1_utils.matchAttributeFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue); + if (filter.attributeName === 'features') { + filterResults = tizen1_utils.matchAttributeArrayFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue); + } else { + filterResults = tizen1_utils.matchAttributeFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue); + } } else if (filter.initialValue || filter.endValue) { filterResults = tizen1_utils.matchAttributeRangeFilter(inputArray, filter.attributeName, filter.initialValue, filter.endValue); } - else if (filter.type && filter.filters) { - for (index = 0; index < filter.filters.length; index++) { - compositeResultArray = _filter(inputArray, filter.filters[index]); - - filterResults = tizen1_utils.arrayComposite(filter.type, filterResults, compositeResultArray); - } - } return filterResults; } @@ -79649,7 +81661,7 @@ function _save() { function _retrieve() { var index; - + _data.callHistory = db.retrieveObject(_DB_CALL_KEY) || []; for (index = 0; index < _data.callHistory.length; index++) { @@ -79659,7 +81671,7 @@ function _retrieve() { function _isValidCallHistoryEntry(arg) { return arg && arg.hasOwnProperty("uid") && arg.hasOwnProperty("type") && - arg.hasOwnProperty("features") && arg.hasOwnProperty("remoteParties") && + arg.hasOwnProperty("features") && arg.hasOwnProperty("remoteParties") && arg.hasOwnProperty("startTime") && arg.hasOwnProperty("duration") && arg.hasOwnProperty("direction"); } @@ -79739,15 +81751,27 @@ _self = function () { limitValue = limit | 0, offsetValue = offset | 0; - if (!_security.all && !_security.find) { + if (!_security.find) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (successCallback === null || successCallback === undefined) { + if (!(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((arguments.length > 1) && errorCallback !== null && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((arguments.length > 2) && filter !== null && !(new TypeCoerce(t.AbstractFilter)).match(filter)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((arguments.length > 3) && sortMode !== null && !(new TypeCoerce(t.SortMode)).match(sortMode)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (typeof successCallback !== "function" || (errorCallback && typeof errorCallback !== "function")) { + if ((arguments.length > 4) && limit !== null && !(new TypeCoerce(t['unsigned long'])).match(limit)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((arguments.length > 5) && offset !== null && !(new TypeCoerce(t['unsigned long'])).match(offset)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } @@ -79771,11 +81795,11 @@ _self = function () { } successCallback(rtn); }, 1); - }, + }; this.remove = function (entry) { var isFound = false, rtn = []; - if (!_security.all && !_security.remove) { + if (!_security.remove) { throw new WebAPIException(errorcode.SECURITY_ERR); } @@ -79803,20 +81827,23 @@ _self = function () { observer.onchanged(rtn); }); - }, + }; this.removeBatch = function (entries, successCallback, errorCallback) { var isFound = false, i, rtn = []; - if (!_security.all && !_security.removeBatch) { + if (!_security.removeBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if ((successCallback && typeof successCallback !== "function") || - (errorCallback && typeof errorCallback !== "function") || - (tizen1_utils.isValidArray(entries) === false)) { + if (tizen1_utils.isValidArray(entries) === false) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((arguments.length > 1) && successCallback !== null && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if ((arguments.length > 2) && errorCallback !== null && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - for (i = 0; i < entries.length; i++) { if (!_isValidCallHistoryEntry(entries[i])) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); @@ -79842,7 +81869,7 @@ _self = function () { return tizen1_utils.isEqual(element, entryValue); }); }); - + _save(); if (successCallback) { @@ -79855,18 +81882,21 @@ _self = function () { observer.onchanged(rtn); }); }, 1); - }, + }; this.removeAll = function (successCallback, errorCallback) { var i, rtn = []; - if (!_security.all && !_security.removeAll) { + if (!_security.removeAll) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if ((successCallback && typeof successCallback !== "function") || - (errorCallback && typeof errorCallback !== "function")) { + if ((arguments.length > 0) && successCallback !== null && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } + if ((arguments.length > 1) && errorCallback !== null && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + for (i = 0; i < _data.callHistory.length; i++) { rtn.push(_rtnEntry(_data.callHistory[i])); } @@ -79880,21 +81910,19 @@ _self = function () { utils.forEach(_data.observers, function (observer) { observer.onchanged(rtn); }); - - }, + + }; this.addChangeListener = function (observerObj) { var handle = Number(Math.uuid(8, 10)); - if (!_security.all && !_security.addChangeListener) { + if (!_security.addChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if ((observerObj === null || observerObj === undefined) || !observerObj.hasOwnProperty("onadded") || - !observerObj.hasOwnProperty("onchanged")) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - - if (typeof observerObj.onadded !== "function" || typeof observerObj.onchanged !== "function") { + if (observerObj === null || typeof observerObj !== 'object' || + (observerObj.hasOwnProperty("onadded") && typeof observerObj.onadded !== 'function') || + (observerObj.hasOwnProperty("onremoved") && typeof observerObj.onremoved !== 'function') || + (observerObj.hasOwnProperty("onchanged") && typeof observerObj.onchanged !== 'function')) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } @@ -79903,7 +81931,7 @@ _self = function () { return handle; }; this.removeChangeListener = function (handle) { - if (!_security.all && !_security.removeChangeListener) { + if (!_security.removeChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (typeof handle !== 'number') { @@ -79916,18 +81944,13 @@ _self = function () { else { throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } - }, + }; this.handleSubFeatures = function (subFeatures) { function setSecurity(method) { _security[method] = true; } for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; utils.forEach(_security[subFeature], setSecurity); } }; @@ -79958,11 +81981,10 @@ define('ripple/platform/tizen/2.0/contact', function (require, exports, module) var db = require('ripple/db'), utils = require('ripple/utils'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - t = require('ripple/platform/tizen/2.0/typedef'), + t = require('ripple/platform/tizen/2.0/typecast'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), Contact = require('ripple/platform/tizen/2.0/ContactBase'), AddressBook, AddressBookData, @@ -79984,11 +82006,10 @@ var db = require('ripple/db'), _security = { "http://tizen.org/privilege/contact.read": ["getAddressBooks", "getDefaultAddressBook", "getAddressBook", "get", "find", "addChangeListener", "removeChangeListener", - "getGroup", "getGroups"], + "getGroup", "getGroups", "clone"], "http://tizen.org/privilege/contact.write": ["add", "addBatch", "update", "updateBatch", "remove", "removeBatch", "addGroup", - "updateGroup", "removeGroup", "link", "unlink"], - all: true + "updateGroup", "removeGroup", "link", "unlink"] }, _self; @@ -80089,7 +82110,11 @@ function _replacePerson(oldId, newId) { for (idc in _data.contacts[idab]) { contact = _data.contacts[idab][idc]; if (contact.personId === oldId) { - contact.personId = newId; + if (newId === null) { + delete _data.contacts[idab][idc]; + } else { + contact.personId = newId; + } } } } @@ -80103,7 +82128,11 @@ function _replacePerson(oldId, newId) { for (idc in dbAddressBook.contacts) { contact = dbAddressBook.contacts[idc]; if (contact.personId === oldId) { - contact.personId = newId; + if (newId === null) { + delete dbAddressBook.contacts[idc]; + } else { + contact.personId = newId; + } } } } @@ -80143,21 +82172,20 @@ _self = function () { // public // Address Book Methods function getAddressBooks(successCallback, errorCallback) { - function _getAddressBooks() { - if (_data.addressBooks.length === 0) { - loadAddressBooks(); - } - successCallback(_data.addressBooks); + if (!_security.getAddressBooks) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!_security.all && !_security.getAddressBooks) { - throw new WebAPIException(errorcode.SECURITY_ERR); + t.ContactManager("getAddressBooks", arguments); + + if (_data.addressBooks.length === 0) { + loadAddressBooks(); } - tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "getAddressBooks", _getAddressBooks); + successCallback(_data.addressBooks); } function getDefaultAddressBook() { - if (!_security.all && !_security.getDefaultAddressBook) { + if (!_security.getDefaultAddressBook) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (_data.addressBooks.length === 0) { @@ -80169,12 +82197,12 @@ _self = function () { function getAddressBook(addressBookId) { var i; - if (!_security.all && !_security.getAddressBook) { + if (!_security.getAddressBook) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.AddressBookId)).match(addressBookId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContactManager("getAddressBook", arguments); + if (_data.addressBooks.length === 0) { loadAddressBooks(); } @@ -80190,15 +82218,12 @@ _self = function () { // Person Methods function get(personId) { - if (!_security.all && !_security.get) { + if (!_security.get) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.PersonId)).match(personId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!personId) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.ContactManager("get", arguments); + if (_data.persons[personId] === undefined) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); } @@ -80209,12 +82234,12 @@ _self = function () { function update(person) { var updated; - if (!_security.all && !_security.update) { + if (!_security.update) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.Person)).match(person)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContactManager("update", arguments); + if (!person.id) { throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } @@ -80236,18 +82261,11 @@ _self = function () { } function updateBatch(persons, successCallback, errorCallback) { - if (!_security.all && !_security.updateBatch) { + if (!_security.updateBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce([t.Person])).match(persons)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContactManager("updateBatch", arguments); window.setTimeout(function () { var i, updated; @@ -80296,15 +82314,12 @@ _self = function () { } function remove(personId) { - if (!_security.all && !_security.remove) { + if (!_security.remove) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.PersonId)).match(personId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!personId) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.ContactManager("remove", arguments); + if (_data.persons[personId] === undefined) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); } @@ -80319,18 +82334,11 @@ _self = function () { } function removeBatch(personIds, successCallback, errorCallback) { - if (!_security.all && !_security.removeBatch) { + if (!_security.removeBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce([t.PersonId])).match(personIds)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContactManager("removeBatch", arguments); window.setTimeout(function () { var i; @@ -80371,95 +82379,86 @@ _self = function () { } function find(successCallback, errorCallback, filter, sortMode) { - function _find() { - var i, matched = [], result = []; + var i, matched = [], result = []; - if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (sortMode && !(new TypeCoerce(t.SortMode)).match(sortMode)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + if (!_security.find) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } - if (filter) { - switch (_filterType(filter)) { - case 0: - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + t.ContactManager("find", arguments); - case 1: - //TODO: - //"compositeFilter doesn't support" - throw new WebAPIException(errorcode.NOT_SUPPORTED_ERR); + if (filter) { + switch (_filterType(filter)) { + case 0: + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - case 2: - case 3: - break; - } - } + case 1: + //TODO: + //"compositeFilter doesn't support" + throw new WebAPIException(errorcode.NOT_SUPPORTED_ERR); - if (filter === null || filter === undefined) { - utils.forEach(_data.persons, function (person) { - matched.push(person); - }); - } else { - switch (filter.attributeName) { - case "id": - case "displayName": - case "photoURI": - case "ringtoneURI": - case "displayContactId": - matched = tizen1_utils.matchAttributeFilter(_data.persons, - filter.attributeName, filter.matchFlag, filter.matchValue); - break; + case 2: + case 3: + break; + } + } - case "contactCount": - if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "number") { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - matched = tizen1_utils.matchAttributeFilter(_data.persons, - filter.attributeName, filter.matchFlag, filter.matchValue); - break; + if (filter === null || filter === undefined) { + utils.forEach(_data.persons, function (person) { + matched.push(person); + }); + } else { + switch (filter.attributeName) { + case "id": + case "displayName": + case "photoURI": + case "ringtoneURI": + case "displayContactId": + matched = tizen1_utils.matchAttributeFilter(_data.persons, + filter.attributeName, filter.matchFlag, filter.matchValue); + break; - case "hasPhoneNumber": - case "hasEmail": - case "isFavorite": - if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - matched = tizen1_utils.matchAttributeBooleanFilter(_data.persons, - filter.attributeName, filter.matchValue); - break; + case "contactCount": + if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "number") { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + matched = tizen1_utils.matchAttributeFilter(_data.persons, + filter.attributeName, filter.matchFlag, filter.matchValue); + break; - default: - break; + case "hasPhoneNumber": + case "hasEmail": + case "isFavorite": + if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - } + matched = tizen1_utils.matchAttributeBooleanFilter(_data.persons, + filter.attributeName, filter.matchValue); + break; - if (sortMode) { - _sort(matched, sortMode); + default: + break; } + } - for (i in matched) { - result.push(new Person(matched[i])); - } - successCallback(result); + if (sortMode) { + _sort(matched, sortMode); } - if (!_security.all && !_security.find) { - throw new WebAPIException(errorcode.SECURITY_ERR); + for (i in matched) { + result.push(new Person(matched[i])); } - tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); + successCallback(result); } function addChangeListener(successCallback) { var id; - if (!_security.all && !_security.addChangeListener) { + if (!_security.addChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.PersonsChangeCallback)).match(successCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContactManager("addChangeListener", arguments); id = ++_data.contactData.nListener; _data.contactData.listeners[id] = successCallback; @@ -80468,15 +82467,12 @@ _self = function () { } function removeChangeListener(watchId) { - if (!_security.all && !_security.removeChangeListener) { + if (!_security.removeChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.long)).match(watchId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (watchId === 0) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.ContactManager("removeChangeListener", arguments); + if (_data.contactData.listeners[watchId] === undefined) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); } @@ -80485,12 +82481,8 @@ _self = function () { function handleSubFeatures(subFeatures) { var i, subFeature; + for (subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; for (i in _security[subFeature]) { _security[_security[subFeature][i]] = true; } @@ -80522,17 +82514,48 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { var addressBook, privateData = new AddressBookData(dbContacts, dbGroups); + // private + function addNewContact(contact, external) { + var added, person; + added = new ContactPrivate(contact, true); + privateData.contacts[added.id] = added; + + person = new PersonBuilder(added); + _data.persons[person.id] = person; + + added.personId = person.id; + added.addressBookId = id; + + dbContacts[added.id] = _serialize(added); + _data.dbStorage.persons[person.id] = _serialize(_data.persons[person.id]); + + external.__defineGetter__("id", function () { + return added.id; + }); + external.__defineGetter__("personId", function () { + return added.personId; + }); + external.__defineGetter__("addressBookId", function () { + return added.addressBookId; + }); + external.__defineGetter__("lastUpdated", function () { + return added.lastUpdated; + }); + if (external.name !== null) { + external.name.__defineGetter__("displayName", function () { + return added.name.displayName; + }); + } + } + // public function get(id) { - if (!_security.all && !_security.get) { + if (!_security.get) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContactId)).match(id)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!id) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.AddressBook("get", arguments); + if (privateData.contacts[id] === undefined) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); } @@ -80540,65 +82563,43 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } function add(contact) { - var added, person; + var added, external = contact; - if (!_security.all && !_security.add) { + if (!_security.add) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (addressBook.readOnly) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.Contact)).match(contact)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - - added = new ContactPrivate(contact, true); - privateData.contacts[added.id] = added; - person = new PersonBuilder(added); - _data.persons[person.id] = person; + t.AddressBook("add", arguments); - added.personId = person.id; - added.addressBookId = id; - - dbContacts[added.id] = _serialize(added); - _data.dbStorage.persons[person.id] = _serialize(_data.persons[person.id]); + addNewContact(contact, external); _save(); - contact.id = added.id; - contact.personId = added.personId; - contact.addressBookId = added.addressBookId; - contact.lastUpdated = added.lastUpdated; - window.setTimeout(function () { utils.forEach(privateData.listeners, function (listener) { listener.oncontactsadded([new ContactPublic(added)]); }); utils.forEach(_data.contactData.listeners, function (listener) { - listener.onpersonsadded([new Person(person)]); + listener.onpersonsadded([new Person(_data.persons[external.personId])]); }); }, 1); } function addBatch(contacts, successCallback, errorCallback) { - if (!_security.all && !_security.addBatch) { + var external = contacts; + if (!_security.addBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (addressBook.readOnly) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce([t.Contact])).match(contacts)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (successCallback && !(new TypeCoerce(t.ContactArraySuccessCallback)).match(successCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.AddressBook("addBatch", arguments); window.setTimeout(function () { - var i, added, person, personIds = []; + var i, personIds = []; if (contacts.length === 0) { if (errorCallback) { @@ -80608,31 +82609,19 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } for (i in contacts) { - added = new ContactPrivate(contacts[i], true); - privateData.contacts[added.id] = added; - - person = new PersonBuilder(added); - _data.persons[person.id] = person; - - added.personId = person.id; - added.addressBookId = id; - - dbContacts[added.id] = _serialize(added); - _data.dbStorage.persons[person.id] = _serialize(_data.persons[person.id]); - - contacts[i] = new ContactPublic(added); - personIds[i] = person.id; + addNewContact(contacts[i], external[i]); + personIds.push(external[i].personId); } _save(); if (successCallback) { - successCallback(contacts); + successCallback(external); } utils.forEach(privateData.listeners, function (listener) { var i, watched = []; for (i in contacts) { - watched.push(new ContactPublic(contacts[i])); + watched.push(new ContactPublic(external[i])); } listener.oncontactsadded(watched); }); @@ -80650,15 +82639,15 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { function update(contact) { var updated; - if (!_security.all && !_security.update) { + if (!_security.update) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (addressBook.readOnly) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.Contact)).match(contact)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.AddressBook("update", arguments); + if (!contact.id) { throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } @@ -80680,21 +82669,14 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } function updateBatch(contacts, successCallback, errorCallback) { - if (!_security.all && !_security.updateBatch) { + if (!_security.updateBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (addressBook.readOnly) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce([t.Contact])).match(contacts)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.AddressBook("updateBatch", arguments); window.setTimeout(function () { var i, updated; @@ -80744,18 +82726,15 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } function remove(id) { - if (!_security.all && !_security.remove) { + if (!_security.remove) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (addressBook.readOnly) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContactId)).match(id)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!id) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.AddressBook("remove", arguments); + if (privateData.contacts[id] === undefined) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); } @@ -80774,21 +82753,14 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } function removeBatch(ids, successCallback, errorCallback) { - if (!_security.all && !_security.removeBatch) { + if (!_security.removeBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } if (addressBook.readOnly) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce([t.ContactId])).match(ids)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.AddressBook("removeBatch", arguments); window.setTimeout(function () { var i; @@ -80832,294 +82804,289 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } function find(successCallback, errorCallback, filter, sortMode) { - function _find() { - var result = [], begin, end, i, - atr, _re, errFlag = false, _rangeMatch, low, high, matched, - _existMatch, _arrayMatch; + var result = [], begin, end, i, + atr, _re, errFlag = false, _rangeMatch, low, high, matched, + _existMatch, _arrayMatch; - if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (sortMode && !(new TypeCoerce(t.SortMode)).match(sortMode)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + if (!_security.find) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } - if (filter) { - switch (_filterType(filter)) { - case 0: - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - case 1: - //TODO: - //"compositeFilter doesn't support" - throw new WebAPIException(errorcode.NOT_SUPPORTED_ERR); - case 2: - case 3: - break; - } - } + t.AddressBook("find", arguments); - /* return all contacts if no filter argument */ - if (filter === null || filter === undefined) { - utils.forEach(privateData.contacts, function (contact) { - result.push(new ContactPublic(contact)); - }); - successCallback(result); - return; + if (filter) { + switch (_filterType(filter)) { + case 0: + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + case 1: + //TODO: + //"compositeFilter doesn't support" + throw new WebAPIException(errorcode.NOT_SUPPORTED_ERR); + case 2: + case 3: + break; } + } - /* check composition of filter.attributeName */ - switch (filter.attributeName) { - case "id" : - case "personId" : - case "addressBookId" : - case "name.prefix" : - case "name.suffix" : - case "name.firstName" : - case "name.middleName" : - case "name.lastName" : - case "name.phoneticFirstName" : - case "name.phoneticLastName" : - case "name.displayName" : - case "account.accountServiceId" : - case "account.contactURI" : - case "photoURI" : - case "ringtoneURI" : - matched = tizen1_utils.matchAttributeFilter(privateData.contacts, - filter.attributeName, filter.matchFlag, filter.matchValue); - break; - case "name.nicknames" : - case "notes" : - case "groupIds" : - matched = tizen1_utils.matchAttributeArrayFilter(privateData.contacts, - filter.attributeName, filter.matchFlag, filter.matchValue); - break; - case "addresses.country" : - case "addresses.region" : - case "addresses.city" : - case "addresses.streetAddress" : - case "addresses.additionalInformation" : - case "addresses.postalCode" : - case "phoneNumbers.number" : - case "emails.email" : - case "anniversaries.label" : - case "organizations.name" : - case "organizations.department" : - case "organizations.title" : - case "organizations.role" : - case "organizations.logoURI" : - case "urls.url" : - case "urls.type" : - atr = filter.attributeName.split("."); - _existMatch = function (obj) { - return (obj[atr[0]] !== undefined); - }; + /* return all contacts if no filter argument */ + if (filter === null || filter === undefined) { + utils.forEach(privateData.contacts, function (contact) { + result.push(new ContactPublic(contact)); + }); + successCallback(result); + return; + } - if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") { - matched = utils.filter(privateData.contacts, _existMatch); - break; - } + /* check composition of filter.attributeName */ + switch (filter.attributeName) { + case "id" : + case "personId" : + case "addressBookId" : + case "name.prefix" : + case "name.suffix" : + case "name.firstName" : + case "name.middleName" : + case "name.lastName" : + case "name.phoneticFirstName" : + case "name.phoneticLastName" : + case "name.displayName" : + case "account.accountServiceId" : + case "account.contactURI" : + case "photoURI" : + case "ringtoneURI" : + matched = tizen1_utils.matchAttributeFilter(privateData.contacts, + filter.attributeName, filter.matchFlag, filter.matchValue); + break; - errFlag = false; + case "name.nicknames" : + case "notes" : + case "groupIds" : + matched = tizen1_utils.matchAttributeArrayFilter(privateData.contacts, + filter.attributeName, filter.matchFlag, filter.matchValue); + break; - switch (filter.matchFlag) - { - case "EXACTLY": - _re = new RegExp("^" + filter.matchValue + "$"); - break; - case "FULLSTRING": - _re = new RegExp("^" + filter.matchValue + "$", "i"); - break; - case "CONTAINS": - _re = new RegExp(filter.matchValue, "i"); - break; - case "STARTSWITH": - _re = new RegExp("^" + filter.matchValue, "i"); - break; - case "ENDSWITH": - _re = new RegExp(filter.matchValue + "$", "i"); - break; - default: - errFlag = true; - } + case "addresses.country" : + case "addresses.region" : + case "addresses.city" : + case "addresses.streetAddress" : + case "addresses.additionalInformation" : + case "addresses.postalCode" : + case "phoneNumbers.number" : + case "emails.email" : + case "anniversaries.label" : + case "organizations.name" : + case "organizations.department" : + case "organizations.title" : + case "organizations.role" : + case "organizations.logoURI" : + case "urls.url" : + case "urls.type" : + atr = filter.attributeName.split("."); + _existMatch = function (obj) { + return (obj[atr[0]] !== undefined); + }; - if (errFlag) { - matched = []; - break; - } + if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") { + matched = utils.filter(privateData.contacts, _existMatch); + break; + } - _arrayMatch = function (obj) { - return (obj[atr[0]].some(function (o) { - if (typeof o[atr[1]] !== "string") { - return false; - } else { - return (o[atr[1]].search(_re) !== -1); - } - })); - }; + errFlag = false; - matched = utils.filter(privateData.contacts, _arrayMatch); + switch (filter.matchFlag) + { + case "EXACTLY": + _re = new RegExp("^" + filter.matchValue + "$"); break; - case "addresses.types" : - case "phoneNumbers.types" : - case "emails.types" : - atr = filter.attributeName.split("."); - _existMatch = function (obj) { - return (obj[atr[0]].some(function (o) { - return (o[atr[1]] !== undefined); - })); - }; - - if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") { - matched = utils.filter(privateData.contacts, _existMatch); - break; - } + case "FULLSTRING": + _re = new RegExp("^" + filter.matchValue + "$", "i"); + break; + case "CONTAINS": + _re = new RegExp(filter.matchValue, "i"); + break; + case "STARTSWITH": + _re = new RegExp("^" + filter.matchValue, "i"); + break; + case "ENDSWITH": + _re = new RegExp(filter.matchValue + "$", "i"); + break; + default: + errFlag = true; + } - errFlag = false; + if (errFlag) { + matched = []; + break; + } - switch (filter.matchFlag) - { - case "EXACTLY": - _re = new RegExp("^" + filter.matchValue + "$"); - break; - case "FULLSTRING": - _re = new RegExp("^" + filter.matchValue + "$", "i"); - break; - case "CONTAINS": - _re = new RegExp(filter.matchValue, "i"); - break; - case "STARTSWITH": - _re = new RegExp("^" + filter.matchValue, "i"); - break; - case "ENDSWITH": - _re = new RegExp(filter.matchValue + "$", "i"); - break; - default: - errFlag = true; - } + _arrayMatch = function (obj) { + return (obj[atr[0]].some(function (o) { + if (typeof o[atr[1]] !== "string") { + return false; + } else { + return (o[atr[1]].search(_re) !== -1); + } + })); + }; - if (errFlag) { - matched = []; - break; - } + matched = utils.filter(privateData.contacts, _arrayMatch); + break; - _arrayMatch = function (obj) { - return (obj[atr[0]].some(function (o) { - if (!tizen1_utils.isValidArray(o[atr[1]])) { - return false; - } else { - return (o[atr[1]].some(function (t) { - return (t.search(_re) !== -1); - })); - } - })); - }; + case "addresses.types" : + case "phoneNumbers.types" : + case "emails.types" : + atr = filter.attributeName.split("."); + _existMatch = function (obj) { + return (obj[atr[0]].some(function (o) { + return (o[atr[1]] !== undefined); + })); + }; - matched = utils.filter(privateData.contacts, _arrayMatch); + if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") { + matched = utils.filter(privateData.contacts, _existMatch); break; - case "anniversaries.date" : - low = filter.initialValue; - high = filter.endValue; - atr = filter.attributeName.split("."); - - if (low !== undefined && low !== null) { - if (!tizen1_utils.isValidDate(low)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - } - if (high !== undefined && high !== null) { - if (!tizen1_utils.isValidDate(high)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - } + } - _rangeMatch = function (obj) { - var isMatched = true; - if (low !== null && low !== undefined) { - if (!tizen1_utils.isValidArray(obj[atr[0]])) { - isMatched = false; - } else { - isMatched = (obj[atr[0]].some(function (o) { - return (o[atr[1]] >= low); - })); - } - } - if (isMatched && (high !== null && high !== undefined)) { - if (!tizen1_utils.isValidArray(obj[atr[0]])) { - isMatched = false; - } else { - isMatched = (obj[atr[0]].some(function (o) { - return (o[atr[1]] <= high); - })); - } - } - return isMatched; - }; + errFlag = false; - matched = utils.filter(privateData.contacts, _rangeMatch); + switch (filter.matchFlag) { + case "EXACTLY": + _re = new RegExp("^" + filter.matchValue + "$"); break; - case "addresses.isDefault" : - case "phoneNumbers.isDefault" : - case "emails.isDefault" : + case "FULLSTRING": + _re = new RegExp("^" + filter.matchValue + "$", "i"); break; - case "isFavorite" : - if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } else { - matched = tizen1_utils.matchAttributeBooleanFilter(privateData.contacts, - filter.attributeName, filter.matchValue); - } + case "CONTAINS": + _re = new RegExp(filter.matchValue, "i"); + break; + case "STARTSWITH": + _re = new RegExp("^" + filter.matchValue, "i"); break; - case "birthday" : - begin = filter.initialValue; - end = filter.endValue; + case "ENDSWITH": + _re = new RegExp(filter.matchValue + "$", "i"); + break; + default: + errFlag = true; + } - if (begin !== null && begin !== undefined) { - if (!tizen1_utils.isValidDate(begin)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + if (errFlag) { + matched = []; + break; + } + + _arrayMatch = function (obj) { + return (obj[atr[0]].some(function (o) { + if (!tizen1_utils.isValidArray(o[atr[1]])) { + return false; + } else { + return (o[atr[1]].some(function (t) { + return (t.search(_re) !== -1); + })); } + })); + }; + + matched = utils.filter(privateData.contacts, _arrayMatch); + break; + + case "anniversaries.date" : + low = filter.initialValue; + high = filter.endValue; + atr = filter.attributeName.split("."); + + if (low !== undefined && low !== null) { + if (!tizen1_utils.isValidDate(low)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } + } + if (high !== undefined && high !== null) { + if (!tizen1_utils.isValidDate(high)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + } - if (end !== null && end !== undefined) { - if (!tizen1_utils.isValidDate(end)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + _rangeMatch = function (obj) { + var isMatched = true; + if (low !== null && low !== undefined) { + if (!tizen1_utils.isValidArray(obj[atr[0]])) { + isMatched = false; + } else { + isMatched = (obj[atr[0]].some(function (o) { + return (o[atr[1]] >= low); + })); + } + } + if (isMatched && (high !== null && high !== undefined)) { + if (!tizen1_utils.isValidArray(obj[atr[0]])) { + isMatched = false; + } else { + isMatched = (obj[atr[0]].some(function (o) { + return (o[atr[1]] <= high); + })); } } + return isMatched; + }; - matched = tizen1_utils.matchAttributeRangeFilter(privateData.contacts, - filter.attributeName, begin, end); - break; - default: - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + matched = utils.filter(privateData.contacts, _rangeMatch); + break; + + case "addresses.isDefault" : + case "phoneNumbers.isDefault" : + case "emails.isDefault" : + break; + + case "isFavorite" : + if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } else { + matched = tizen1_utils.matchAttributeBooleanFilter(privateData.contacts, + filter.attributeName, filter.matchValue); } + break; + + case "birthday" : + begin = filter.initialValue; + end = filter.endValue; - if (sortMode) { - _sort(matched, sortMode); + if (begin !== null && begin !== undefined) { + if (!tizen1_utils.isValidDate(begin)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } } - for (i in matched) { - result.push(new ContactPublic(matched[i])); + if (end !== null && end !== undefined) { + if (!tizen1_utils.isValidDate(end)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } } - successCallback(result); + + matched = tizen1_utils.matchAttributeRangeFilter(privateData.contacts, + filter.attributeName, begin, end); + break; + + default: + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } - if (!_security.all && !_security.find) { - throw new WebAPIException(errorcode.SECURITY_ERR); + if (sortMode) { + _sort(matched, sortMode); } - tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); + + for (i in matched) { + result.push(new ContactPublic(matched[i])); + } + successCallback(result); } function addChangeListener(successCallback, errorCallback) { var id; - if (!_security.all && !_security.addChangeListener) { + if (!_security.addChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.AddressBookChangeCallback)).match(successCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.AddressBook("addChangeListener", arguments); id = ++privateData.nListener; privateData.listeners[id] = successCallback; @@ -81128,15 +83095,12 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } function removeChangeListener(watchId) { - if (!_security.all && !_security.removeChangeListener) { + if (!_security.removeChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.long)).match(watchId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (watchId === 0) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.AddressBook("removeChangeListener", arguments); + if (privateData.listeners[watchId] === undefined) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); } @@ -81146,15 +83110,12 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { function getGroup(groupId) { var i; - if (!_security.all && !_security.getGroup) { + if (!_security.getGroup) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContactGroupId)).match(groupId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!groupId) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.AddressBook("getGroup", arguments); + for (i in privateData.groups) { if (privateData.groups[i].id === groupId) break; @@ -81167,28 +83128,38 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { } function addGroup(group) { - if (!_security.all && !_security.addGroup) { + var external = group; + + if (!_security.addGroup) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContactGroup)).match(group)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - group.id = Math.uuid(null, 16); + + t.AddressBook("addGroup", arguments); + + group.id = Math.uuid(null, 16); group.addressBookId = id; - privateData.groups.push(utils.copy(group)); + external.__defineGetter__("id", function () { + return group.id; + }); + + external.__defineGetter__("addressBookId", function () { + return group.addressBookId; + }); + + privateData.groups.push(group); _save(); } function updateGroup(group) { var i; - if (!_security.all && !_security.updateGroup) { + if (!_security.updateGroup) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContactGroup)).match(group)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.AddressBook("updateGroup", arguments); + if (!group.id) { throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } @@ -81209,15 +83180,12 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { function removeGroup(groupId) { var i; - if (!_security.all && !_security.removeGroup) { + if (!_security.removeGroup) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContactGroupId)).match(groupId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!groupId) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.AddressBook("removeGroup", arguments); + for (i in privateData.groups) { if (privateData.groups[i].id === groupId) break; @@ -81229,14 +83197,14 @@ AddressBook = function (id, name, readOnly, dbContacts, dbGroups) { throw new WebAPIException(errorcode.SECURITY_ERR); } - privateData.groups.splice(i); + privateData.groups.splice(i, 1); _save(); } function getGroups() { var groups = [], i; - if (!_security.all && !_security.getGroups) { + if (!_security.getGroups) { throw new WebAPIException(errorcode.SECURITY_ERR); } @@ -81331,13 +83299,7 @@ ContactData = function () { ContactPublic = function (prop) { var _self; - if (!(new TypeCoerce(t.ContactId)).match(prop.id)) { - return undefined; - } - if (!(new TypeCoerce(t.Date)).match(prop.lastUpdated)) { - return undefined; - } - _self = new Contact(prop); + _self = new Contact(prop, _security); _self.__defineGetter__("id", function () { return prop.id; @@ -81354,6 +83316,11 @@ ContactPublic = function (prop) { _self.__defineGetter__("isFavorite", function () { return prop.isFavorite; }); + if (_self.name !== null) { + _self.name.__defineGetter__("displayName", function () { + return prop.name.displayName; + }); + } return _self; }; @@ -81361,11 +83328,31 @@ ContactPublic = function (prop) { ContactPrivate = function (prop, newID) { var _self; - _self = new Contact(prop); + _self = utils.copy(new Contact(prop, _security)); if (newID) { - _self.id = Math.uuid(null, 16); - _self.lastUpdated = new Date(); + _self.id = Math.uuid(null, 16); + _self.lastUpdated = new Date(); + + if (_self.name !== null) { + _self.name.__defineGetter__("displayName", function () { + var displayName = ""; + + if ((_self.name.firstName !== null) && + (_self.name.lastName !== null)) { + displayName = [_self.name.firstName, _self.name.middleName, + _self.name.lastName]; + displayName = displayName.join(" ").replace(/ +/g, " ").trim(); + } else if (_self.name.nicknames.length !== 0) { + _self.name.nicknames.some(function (nickname) { + displayName = nickname; + return displayName; + }); + } + + return displayName; + }); + } } else { _self.id = prop.id; _self.personId = prop.personId; @@ -81428,7 +83415,7 @@ Person = function (personInitDict) { for (idab in _data.contacts) { contact = _data.contacts[idab][this.displayContactId]; if (contact !== undefined) { - if (contact.name.displayName) { + if (contact.name && contact.name.displayName) { displayName = contact.name.displayName; } break; @@ -81468,15 +83455,12 @@ Person = function (personInitDict) { this.displayContactId = personInitDict.displayContactId; this.link = function (personId) { - if (!_security.all && !_security.link) { + if (!_security.link) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.PersonId)).match(personId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!personId) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.Person("link", arguments); + if (_data.persons[personId] === undefined) { throw new WebAPIException(errorcode.NOT_FOUND_ERR); } @@ -81488,15 +83472,11 @@ Person = function (personInitDict) { this.unlink = function (contactId) { var idab, contact, separated, i, dbAddressBook; - if (!_security.all && !_security.unlink) { + if (!_security.unlink) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContactId)).match(contactId)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!contactId) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } + + t.Person("unlink", arguments); for (idab in _data.contacts) { if (_data.contacts[idab][contactId] !== undefined) { @@ -81562,13 +83542,11 @@ define('ripple/platform/tizen/2.0/content', function (require, exports, module) var db = require('ripple/db'), utils = require('ripple/utils'), dbfs = require('ripple/platform/tizen/2.0/dbfs'), - filesystem = require('ripple/platform/tizen/2.0/filesystem'), - t = require('ripple/platform/tizen/2.0/typedef'), + t = require('ripple/platform/tizen/2.0/typecast'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), ContentDirectory, Content, VideoContent, @@ -81583,180 +83561,15 @@ var db = require('ripple/db'), dbStorage: {} }, _security = { - "http://tizen.org/privilege/content.read": ["getDirectories", "find", + "http://tizen.org/privilege/content.read": ["find", "setChangeListener", "unsetChangeListener"], "http://tizen.org/privilege/content.write": ["update", "updateBatch", - "scanFile"], - all: true + "scanFile"] }, _self; -function _defaultContent() { - var video1 = { - editableAttributes: ["title", "description", "rating", "geolocation", "album", "artists"], - id: Math.uuid(null, 16), - name: "olympic.avi", - type: "VIDEO", - mimeType: "video/x-msvideo", - title: "Olympic", - contentURI: "/opt/videos/olympic.avi", - thumbnailURIs: ["desktop/olympic.lnk"], - releaseDate: new Date(), - modifiedDate: new Date(), - size: 12583498, - description: "Olympic Games", - rating: 4, - - geolocation: null, - album: "olympic", - artists: ["Daniel"], - duration: 545, - width: 480, - height: 240 - }, - video2 = { - editableAttributes: ["title", "description", "rating", "album"], - id: Math.uuid(null, 16), - name: "galaxy.rmvb", - type: "VIDEO", - mimeType: "video/x-msvideo", - title: "Galaxy", - contentURI: "/opt/videos/galaxy.rmvb", - thumbnailURIs: ["desktop/galaxy.lnk"], - releaseDate: new Date(), - modifiedDate: new Date(), - size: 5096078, - description: "Universe View", - rating: 5, - - geolocation: null, - album: "galaxy", - artists: ["David"], - duration: 156, - width: 220, - height: 180 - }, - audio1 = { - editableAttributes: ["title", "description", "rating", "album", "genres", "artists", "composers"], - id: Math.uuid(null, 16), - name: "rock.mp3", - type: "AUDIO", - mimeType: "audio/x-msaudio", - title: "Rock", - contentURI: "/opt/music/rock.mp3", - thumbnailURIs: ["desktop/rock.lnk"], - releaseDate: new Date(), - modifiedDate: new Date(), - size: 3670016, - description: "Pop Song", - rating: 4, - - album: "rock", - genres: ["Rock & Roll"], - artists: ["Emile"], - composers: ["Emile"], - lyrics: null, - copyright: "Rocky Dream Works", - bitrate: 128, - trackNumber: 2, - duration: 230 - }, - audio2 = { - editableAttributes: ["title", "description", "rating", "album", "artists"], - id: Math.uuid(null, 16), - name: "jazz.acc", - type: "AUDIO", - mimeType: "audio/x-msaudio", - title: "Jazz", - contentURI: "/opt/music/jazz.acc", - thumbnailURIs: ["desktop/jazz.lnk"], - releaseDate: new Date(), - modifiedDate: new Date(), - size: 5662312, - description: "Creative Jazz", - rating: 3, - - album: "jazz", - genres: ["jazz"], - artists: ["Jackson"], - composers: ["Johnson"], - lyrics: null, - copyright: "J&J Studio", - bitrate: 128, - trackNumber: 1, - duration: 352 - }, - image1 = { - editableAttributes: ["title", "description", "rating", "geolocation", "orientation"], - id: Math.uuid(null, 16), - name: "greatwall.jpg", - type: "IMAGE", - mimeType: "image/jpeg", - title: "Great Wall", - contentURI: "/opt/images/greatwall.jpg", - thumbnailURIs: ["desktop/greatwall.lnk"], - releaseDate: new Date(), - modifiedDate: new Date(), - size: 479232, - description: "World Spectacle", - rating: 2, - - geolocaion: null, - width: 1024, - height: 768, - orientation: "NORMAL" - }, - image2 = { - editableAttributes: ["title", "rating", "orientation"], - id: Math.uuid(null, 16), - name: "seagull.gif", - type: "IMAGE", - mimeType: "image/gif", - title: "Seagull", - contentURI: "/opt/images/seagull.gif", - thumbnailURIs: ["desktop/seagull.lnk"], - releaseDate: new Date(), - modifiedDate: new Date(), - size: 391168, - description: "Natural Animation", - rating: 1, - - geolocaion: null, - width: 800, - height: 600, - orientation: "FLIP_HORIZONTAL" - }, - videoDir = { - id: Math.uuid(null, 16), - directoryURI: "/opt/videos/", - title: "Videos", - storageType: "INTERNAL", - modifiedDate: new Date() - }, - audioDir = { - id: Math.uuid(null, 16), - directoryURI: "/opt/music/", - title: "Music", - storageType: "EXTERNAL", - modifiedDate: new Date() - }, - imageDir = { - id: Math.uuid(null, 16), - directoryURI: "/opt/images/", - title: "Images", - storageType: "EXTERNAL", - modifiedDate: new Date() - }, - dbContent = { - directories: [videoDir, audioDir, imageDir], - contents: [video1, video2, audio1, audio2, image1, image2] - }; - - return dbContent; -} - function _get() { - _data.dbStorage = db.retrieveObject(_data.DB_CONTENT_KEY) || _defaultContent(); + _data.dbStorage = db.retrieveObject(_data.DB_CONTENT_KEY) || require('ripple/platform/tizen/2.0/dbinit').Content; } function _save() { @@ -81766,6 +83579,9 @@ function _save() { function _initialize() { _get(); + if (!_data.dbStorage) + return; + utils.forEach(_data.dbStorage.directories, function (directory) { _data.directories.push(new ContentDirectory(directory, true)); }); @@ -81776,10 +83592,7 @@ function _initialize() { _data.dbStorage.directories = _data.directories; _data.dbStorage.contents = _data.contents; - // Initialize dbfs - filesystem.resolve("images", function () {}); - filesystem.resolve("videos", function () {}); - filesystem.resolve("music", function () {}); + _save(); } _self = function () { @@ -81850,6 +83663,7 @@ _self = function () { case "mpeg": case "mpg": case "wmv": + case "mp4": type = "VIDEO"; break; @@ -81905,25 +83719,21 @@ _self = function () { // public function update(content) { - if (!_security.all && !_security.update) { + if (!_security.update) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.Content)).match(content)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContentManager("update", arguments); updateContents(content); } function updateBatch(contents, successCallback, errorCallback) { - if (!_security.all && !_security.updateBatch) { + if (!_security.updateBatch) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce([t.Content])).match(contents) || - (successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContentManager("updateBatch", arguments); window.setTimeout(function () { updateContents(contents, successCallback, errorCallback); @@ -81933,13 +83743,7 @@ _self = function () { function getDirectories(successCallback, errorCallback) { var result = []; - if (!_security.all && !_security.getDirectories) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } - if (!(new TypeCoerce(t.ContentDirectoryArraySuccessCallback)).match(successCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + t.ContentManager("getDirectories", arguments); if (_data.directories.length === 0) { if (errorCallback) { @@ -81954,24 +83758,19 @@ _self = function () { result.push(new ContentDirectory(directory)); }); - successCallback(result); + setTimeout(function () { + successCallback(result); + }, 1); } function find(successCallback, errorCallback, directoryId, filter, sortMode, count, offset) { var src = [], result = [], i, directoryURI, parentURI, contents; - if (!_security.all && !_security.find) { + if (!_security.find) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContentArraySuccessCallback)).match(successCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) || - (directoryId && !(new TypeCoerce(t.ContentDirectoryId)).match(directoryId)) || - (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) || - (sortMode && !(new TypeCoerce(t.SortMode)).match(sortMode)) || - (count && !(new TypeCoerce(t["unsigned long"])).match(count)) || - (offset && !(new TypeCoerce(t["unsigned long"])).match(offset))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContentManager("find", arguments); if (!directoryId) { src = _data.contents; @@ -82029,18 +83828,18 @@ _self = function () { } function scanFile(contentURI, successCallback, errorCallback) { - var i, contentId, isOutdated = false; + var i, index, isFound = false; function onStatSuccess(entry) { var contentInitDict, content, directoryURI; - contentInitDict = extractProperties(entry); - if (isOutdated) { - contentInitDict.id = contentId; + if (isFound) { + content = new ContentFactory(_data.contents[index], true); + } else { + contentInitDict = extractProperties(entry); + content = new ContentFactory(contentInitDict, true); + _data.contents.push(content); } - - content = new ContentFactory(contentInitDict, true); - _data.contents.push(content); _save(); if (successCallback) { @@ -82050,7 +83849,7 @@ _self = function () { successCallback(directoryURI); } if (_data.listener !== null) { - if (isOutdated) { + if (isFound) { _data.listener.oncontentupdated(new ContentFactory(content)); } else { _data.listener.oncontentadded(new ContentFactory(content)); @@ -82061,7 +83860,8 @@ _self = function () { function onStatError() { var directoryURI; - if (isOutdated) { + if (isFound) { + _data.contents.splice(index, 1); _save(); if (successCallback) { @@ -82071,7 +83871,7 @@ _self = function () { successCallback(directoryURI); } if (_data.listener !== null) { - _data.listener.oncontentremoved(contentId); + _data.listener.oncontentremoved(_data.contents[index].id); } } else if (errorCallback) { window.setTimeout(function () { @@ -82080,20 +83880,16 @@ _self = function () { } } - if (!_security.all && !_security.scanFile) { + if (!_security.scanFile) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.DOMString)).match(contentURI) || - (successCallback && !(new TypeCoerce(t.ContentScanSuccessCallback)).match(successCallback)) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContentManager("scanFile", arguments); for (i in _data.contents) { if (_data.contents[i].contentURI === contentURI) { - contentId = _data.contents[i].id; - _data.contents.splice(i, 1); - isOutdated = true; + isFound = true; + index = i; break; } } @@ -82102,18 +83898,17 @@ _self = function () { } function setChangeListener(changeCallback) { - if (!_security.all && !_security.setChangeListener) { + if (!_security.setChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.ContentChangeCallback)).match(changeCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + + t.ContentManager("setChangeListener", arguments); _data.listener = changeCallback; } function unsetChangeListener() { - if (!_security.all && !_security.unsetChangeListener) { + if (!_security.unsetChangeListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } @@ -82124,11 +83919,6 @@ _self = function () { var i, subFeature; for (subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; for (i in _security[subFeature]) { _security[_security[subFeature][i]] = true; } @@ -82188,20 +83978,20 @@ ContentDirectory = function (contentDirectoryInitDict, isInternal) { }; Content = function (contentInitDict, isInternal) { - var editableAttributes, id, type, mimeType, contentURI, thumbnailURIs, - releaseDate, modifiedDate, size; + var editableAttributes, id, type, mimeType, title, contentURI, + thumbnailURIs, releaseDate, modifiedDate, size; editableAttributes = contentInitDict.editableAttributes || []; id = contentInitDict.id || Math.uuid(null, 16); type = contentInitDict.type || "IMAGE"; mimeType = contentInitDict.mimeType || ""; + title = contentInitDict.title || ""; contentURI = contentInitDict.contentURI || ""; thumbnailURIs = contentInitDict.thumbnailURIs || null; releaseDate = new Date(contentInitDict.releaseDate); modifiedDate = new Date(contentInitDict.modifiedDate); size = contentInitDict.size || null; this.name = contentInitDict.name || ""; - this.title = contentInitDict.title || ""; this.description = contentInitDict.description || ""; this.rating = contentInitDict.rating || 0; @@ -82222,6 +84012,10 @@ Content = function (contentInitDict, isInternal) { return mimeType; }); + this.__defineGetter__("title", function () { + return title; + }); + this.__defineGetter__("contentURI", function () { return contentURI; }); @@ -82246,6 +84040,7 @@ Content = function (contentInitDict, isInternal) { this.id = id; this.type = type; this.mimeType = mimeType; + this.title = title; this.contentURI = contentURI; this.thumbnailURIs = thumbnailURIs; this.releaseDate = releaseDate; @@ -82419,10 +84214,9 @@ _initialize(); module.exports = _self; }); -define('ripple/platform/tizen/2.0/dbfs', function (require, exports, module) { +define('ripple/platform/tizen/2.0/datacontrol', function (require, exports, module) { /* - * Copyright 2011 Research In Motion Limited. - * Copyright 2012 Intel Corporation. + * Copyright 2013 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82439,261 +84233,695 @@ define('ripple/platform/tizen/2.0/dbfs', function (require, exports, module) { var db = require('ripple/db'), utils = require('ripple/utils'), - _console = require('ripple/console'), - _cache = {}, + t = require('ripple/platform/tizen/2.0/typecast'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + DataControlConsumerFactory, + DataControlConsumerObject, + SQLDataControlConsumer, + MappedDataControlConsumer, + SQLData, + MappedData, + _data = { + DB_DATACONTROL_KEY: "tizen1-db-datacontrol", + IDS_PROVIDER: ["http://tizen.org/datacontrol/provider/DictionaryDataControlProvider"], + IDS_DATA: ["Dictionary"], + PERSIST_DELAY: 1000, + SQL: null, + MAP: null, + dbStorage: null + }, + _security = { + "http://tizen.org/privilege/datacontrol.consumer": + ["getDataControlConsumer", "insert", "update", "remove", "select", + "addValue", "removeValue", "getValue", "updateValue"] + }, _self; -function _get(path) { - return path.replace(/^\//, '').split("/").reduce(function (obj, token) { - return token === "" ? obj : (obj.children ? obj.children[token] || null : null); - }, _cache); +function _get() { + _data.dbStorage = db.retrieveObject(_data.DB_DATACONTROL_KEY) || {}; } -function _getInfo(path) { - var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"), - name = parent.splice(parent.length - 1, 1).join(""); - - return { - name: name, - parent: parent.join("/") || "/" - }; +function _save() { + db.saveObject(_data.DB_DATACONTROL_KEY, _data.dbStorage); } -function _set(path, obj) { - var parent = _cache, - tokens = path.replace(/^\//, '').split("/"), - child = tokens.splice(tokens.length - 1, 1).join(""); +function _load(type) { + if (!_data.dbStorage[type]) + return; - tokens.forEach(function (token) { - parent = parent.children[token]; - }); + _data[type] = {}; - parent.children = parent.children || {}; - parent.children[child] = obj; -} + utils.forEach(_data.dbStorage[type], function (provider, id) { + var dataId; -function _delete(path) { - var parent = _cache, - tokens = path.replace(/^\//, '').split("/"), - child = tokens.splice(tokens.length - 1, 1).join(""); + _data[type][id] = {}; - tokens.forEach(function (token) { - parent = parent.children[token]; + for (dataId in provider) { + _data[type][id][dataId] = new DataControlConsumerFactory(type, + id, dataId, provider[dataId]); + } }); - - delete parent.children[child]; } -function _save() { - db.saveObject("tizen1-db-filesystem", _cache); +function _initialize() { + _get(); + + _load("SQL"); + _load("MAP"); } -function _walk(path, parent) { - _self.ls(path, function (entries) { - parent.children = parent.children || {}; +_self = function () { + var datacontrol; - entries.forEach(function (entry) { - parent.children[entry.name] = entry; + // private + function initConsumer(type) { + var providers; - if (entry.isDirectory) { - _walk(entry.fullPath, entry); - } else { - /* after getting Date out of DB, Date will become - a string, so need to recast it back to Date */ - if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined) - entry.lastModifiedDate = new Date(entry.lastModifiedDate); - if (entry.createdDate !== null && entry.createdDate !== undefined) - entry.createdDate = new Date(entry.createdDate); + _data.dbStorage[type] = {}; + providers = _data.dbStorage[type]; - _self.read(entry.fullPath, function (data) { - parent.children[entry.name].data = data; - }, function (e) { - _console.error(e); - }); - } + _data.IDS_PROVIDER.forEach(function (id) { + providers[id] = {}; + + _data.IDS_DATA.forEach(function (dataId) { + providers[id][dataId] = {}; + }); }); - }, function (e) { - _console.error(e); + + _load(type); + } + + // public + function getDataControlConsumer(providerId, dataId, type) { + if (!_security.getDataControlConsumer) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + t.DataControlManager("getDataControlConsumer", arguments); + + if (_data[type] === null) { + initConsumer(type); + } + if (!_data[type][providerId] || !_data[type][providerId][dataId]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } + + return _data[type][providerId][dataId]; + } + + function handleSubFeatures(subFeatures) { + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; + } + } + } + + datacontrol = { + getDataControlConsumer: getDataControlConsumer, + handleSubFeatures: handleSubFeatures + }; + + return datacontrol; +}; + +DataControlConsumerObject = function (type, providerId, dataId) { + this.__defineGetter__("type", function () { + return type; }); -} -function _createPath(path) { - var parts = path.replace(/^\//, '').split("/"), - workflow = jWorkflow.order(); + this.__defineGetter__("providerId", function () { + return providerId; + }); - parts.forEach(function (part, index) { - var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/"); + this.__defineGetter__("dataId", function () { + return dataId; + }); +}; - workflow.andThen(function (prev, baton) { - baton.take(); - _self.mkdir(dir, baton.pass, baton.pass); +SQLDataControlConsumer = function (providerId, dataId, dc) { + var self, privateData = new SQLData(dc); + + // public + function insert(reqId, insertionData, successCallback, errorCallback) { + if (!_security.insert) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + t.SQLDataControlConsumer("insert", arguments); + + privateData.insert(insertionData, function (rowId) { + if (successCallback) { + successCallback(reqId, rowId); + } + }, function (error) { + if (errorCallback) { + errorCallback(reqId, error); + } }); - }); + } - workflow.start(); -} + function update(reqId, updateData, where, successCallback, errorCallback) { + if (!_security.update) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -_self = { - // The order is consistent with _virtualRoots in filesystem.js - roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"], - initialize: function () { - // TODO: Initialize at bootstrap and emulatorBridge.link - _cache = db.retrieveObject("tizen1-db-filesystem") || {}; - // create real root paths if empty - _self.roots.every(function (root) { - _createPath(root); - return true; + t.SQLDataControlConsumer("update", arguments); + + privateData.update(updateData, where, function () { + if (successCallback) { + successCallback(reqId); + } + }, function (error) { + if (errorCallback) { + errorCallback(reqId, error); + } }); - // build the file system cache so that we could access information synchronously - _walk("/", _cache); - }, - ls: function (path, success, error) { - try { - var dir = _get(path), - items = []; + } - if (dir) { - utils.forEach(dir.children, function (item) { - items.push(item); - }); + function remove(reqId, where, successCallback, errorCallback) { + if (!_security.remove) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + t.SQLDataControlConsumer("remove", arguments); + + privateData.remove(where, function () { + if (successCallback) { + successCallback(reqId); } - else { - items = {}; + }, function (error) { + if (errorCallback) { + errorCallback(reqId, error); } + }); + } - success(items); + function select(reqId, columns, where, successCallback, errorCallback, page, + maxNumberPerPage) { + if (!_security.select) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - catch (e) { - e.code = 1; - error(e); + + t.SQLDataControlConsumer("select", arguments); + + privateData.select(columns, where, function (rows) { + successCallback(rows, reqId); + }, function (error) { + if (errorCallback) { + errorCallback(reqId, error); + } + }, page, maxNumberPerPage); + } + + self = new DataControlConsumerObject("SQL", providerId, dataId); + + self.insert = insert; + self.update = update; + self.remove = remove; + self.select = select; + + return self; +}; + +MappedDataControlConsumer = function (providerId, dataId, dc) { + var self, privateData = new MappedData(dc); + + function addValue(reqId, key, value, successCallback, errorCallback) { + if (!_security.addValue) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - }, - rm: function (path, success, error, options) { - _delete(path); - _save(); - success(); - }, - rmdir: function (path, success, error, options) { - _delete(path); - _save(); - success(); - }, - mkdir: function (path, success, error) { - var entry = _get(path), - info = _getInfo(path); - if (!entry) { - _set(path, { - lastModifiedDate: new Date(), - createdDate: new Date(), - name: info.name, - isDirectory: true, - fullPath: path - }); - entry = _get(path); - _save(); + t.MappedDataControlConsumer("addValue", arguments); + + window.setTimeout(function () { + if (privateData.insert(key, value)) { + if (successCallback) { + successCallback(reqId); + } + } else if (errorCallback) { + errorCallback(reqId, new WebAPIError(errorcode.UNKNOWN_ERR)); + } + }, 1); + } + + function removeValue(reqId, key, value, successCallback, errorCallback) { + if (!_security.removeValue) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - if (entry) { - success(entry); + t.MappedDataControlConsumer("removeValue", arguments); + + window.setTimeout(function () { + if (privateData.remove(key, value)) { + successCallback(reqId); + } else if (errorCallback) { + errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + }, 1); + } + + function getValue(reqId, key, successCallback, errorCallback) { + if (!_security.getValue) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - else { - error({code: 1}); + + t.MappedDataControlConsumer("getValue", arguments); + + window.setTimeout(function () { + var values; + + values = privateData.search(key); + + if (values !== null) { + successCallback(values, reqId); + } else if (errorCallback) { + errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + }, 1); + } + + function updateValue(reqId, key, oldValue, newValue, successCallback, + errorCallback) { + if (!_security.updateValue) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - }, - mv: function (from, to, success, error) { - try { - var fromEntry = _get(from), - toInfo = _getInfo(to); - fromEntry.fullPath = to; - fromEntry.name = toInfo.name; + t.MappedDataControlConsumer("updateValue", arguments); - _set(to, fromEntry); - _delete(from); + window.setTimeout(function () { + if (privateData.update(key, oldValue, newValue)) { + successCallback(reqId); + } else if (errorCallback) { + errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + }, 1); + } + + self = new DataControlConsumerObject("MAP", providerId, dataId); + + self.addValue = addValue; + self.removeValue = removeValue; + self.getValue = getValue; + self.updateValue = updateValue; + + return self; +}; + +DataControlConsumerFactory = function (type, providerId, dataId, dc) { + var self; + + switch (type) { + case "SQL": + self = new SQLDataControlConsumer(providerId, dataId, dc); + break; + + case "MAP": + self = new MappedDataControlConsumer(providerId, dataId, dc); + break; + } + + return self; +}; + +SQLData = function (dc) { + var self, data, columnNames, SQLErr2WebAPIErr; + + // private + function getDBTableName() { + return "DC_" + Math.uuid(8, 16); + } + + function getColumnNames(tx, results) { + columnNames = results.rows.item(0).sql + .replace(/^[^\(]+\(([^\)]+)\)/g, "$1") + .replace(/(^|(,) )([^ ,]+)([^,]*|$)/g, "$2$3") + .split(","); + } + + function queryColumns(columns) { + return columns.join("=?,") + "=?"; + } + + function queryValues(n) { + return (new Array(n)).join("?,") + "?"; + } + + function shedQuotes(values) { + return values.every(function (value, i, arr) { + arr[i] = value.replace(/^('|")(.*)\1$/g, "$2"); + + return (arr[i] !== value); + }); + } + + function isNull(p) { + return ((p === undefined) || (p === null)); + } + + function initialize() { + SQLErr2WebAPIErr = [ + 0, // 0: UNKNOWN_ERR 0: UNKNOWN_ERR + 100, // 1: DATABASE_ERR 100: IO_ERR + 100, // 2: VERSION_ERR 100: IO_ERR + 100, // 3: TOO_LARGE_ERR 100: IO_ERR + 22, // 4: QUOTA_ERR 22: QUOTA_EXCEEDED_ERR + 12, // 5: SYNTAX_ERR 12: SYNTAX_ERR + 100, // 6: CONSTRAINT_ERR 100: IO_ERR + 23 // 7: TIMEOUT_ERR 23: TIMEOUT_ERR + ]; + + if (!("table" in dc)) { + dc.table = getDBTableName(); + columnNames = ["id"]; _save(); - success(); } - catch (e) { - e.code = 1; - error(e); + + data = openDatabase('tinyHippos', '1.0', 'tiny Hippos persistence', + 2 * 1024 * 1024); + + data.transaction(function (tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS ' + dc.table + + ' (id unique)'); + tx.executeSql('SELECT sql FROM sqlite_master WHERE type="table" AND name=?', + [dc.table], getColumnNames); + }); + } + + // public + function insert(rowData, onSuccess, onError) { + if (rowData.columns.length > rowData.values.length) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } + if (!shedQuotes(rowData.values)) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } - }, - touch: function (path, success, error) { - var entry = _get(path), - info = _getInfo(path); - if (!entry) { - _set(path, { - lastModifiedDate: new Date(), - createdDate: new Date(), - name: info.name, - isDirectory: false, - fullPath: path, - data: "" + data.transaction(function (tx) { + rowData.columns.forEach(function (column) { + if (columnNames.indexOf(column) !== -1) + return; + + tx.executeSql('ALTER TABLE ' + dc.table + ' ADD ' + column + + ' TEXT', [], function () { + columnNames.push(column); + }, function (tx, error) { + onError(new WebAPIError( + SQLErr2WebAPIErr[error.code], + error.message)); + }); }); - entry = _get(path); - } - _save(); - success(entry); - }, - cp: function (from, to, success, error) { - try { - var fromEntry = _get(from), - copied = utils.copy(fromEntry); - copied.name = _getInfo(to).name; - copied.fullPath = to; - _set(to, copied); - _save(); - success(); + tx.executeSql('INSERT INTO ' + dc.table + ' (' + + rowData.columns.join() + ') VALUES (' + + queryValues(rowData.values.length) + ')', rowData.values, + function (tx, results) { + onSuccess(results.insertId); + }, function (tx, error) { + onError(new WebAPIError(SQLErr2WebAPIErr[error.code], + error.message)); + }); + }); + } + + function update(rowData, where, onSuccess, onError) { + if (rowData.columns.length > rowData.values.length) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } - catch (e) { - e.code = 1; - error(e); + if (!shedQuotes(rowData.values)) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } - }, - stat: function (path, success, error) { - var entry = _get(path); - if (entry) { - success(entry); + data.transaction(function (tx) { + tx.executeSql('UPDATE ' + dc.table + ' SET ' + + queryColumns(rowData.columns) + ' WHERE ' + where, + rowData.values, onSuccess, function (tx, error) { + onError(new WebAPIError(SQLErr2WebAPIErr[error.code], + error.message)); + }); + }); + } + + function remove(where, onSuccess, onError) { + data.transaction(function (tx) { + tx.executeSql('DELETE FROM ' + dc.table + ' WHERE ' + where, [], + onSuccess, function (tx, error) { + onError(new WebAPIError(SQLErr2WebAPIErr[error.code], + error.message)); + }); + }); + } + + function select(columns, where, onSuccess, onError, page, maxNumberPerPage) { + if (isNull(page)) { + page = 1; } else { - error({code: 1}); + if (page <= 0) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } + page = parseInt(page, 10); } - }, - write: function (path, contents, success, error, options) { - var entry = _get(path); - if (entry) { - entry.lastModifiedDate = new Date(); - entry.data = contents; - _save(); - success(); + if (isNull(maxNumberPerPage)) { + if (page > 1) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } } else { - error({code: 1}); + if (maxNumberPerPage <= 0) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } + maxNumberPerPage = parseInt(maxNumberPerPage, 10); } - }, - read: function (path, success, error) { - var entry = _get(path); + data.transaction(function (tx) { + tx.executeSql('SELECT ' + columns.join() + ' FROM ' + dc.table + + ' WHERE ' + where, [], function (tx, results) { + var rows = [], rowStart, rowData, r, c; - if (entry) { - success(utils.copy(entry.data)); + rowStart = maxNumberPerPage ? + (page - 1) * maxNumberPerPage : 0; + + for (r = rowStart; r < results.rows.length; ++r) { + rowData = { + columns: columns, + values: [] + }; + for (c in columns) { + rowData.values.push(results.rows + .item(r)[columns[c]]); + } + rows.push(rowData); + + if (maxNumberPerPage && (--maxNumberPerPage === 0)) + break; + } + + onSuccess(rows); + }, function (tx, error) { + onError(new WebAPIError(SQLErr2WebAPIErr[error.code], + error.message)); + }); + }); + } + + initialize(); + + self = { + insert: insert, + update: update, + remove: remove, + select: select + }; + + return self; +}; + +MappedData = function (dc) { + var self, data = {}, ioStamp = 0; + + // private + function addNode(tree, arr, i) { + var key, value; + + if (typeof arr[i] === "string") { + key = arr[i]; + value = 1; + } else { + key = arr[i][0]; + value = arr[i][1]; } - else { - error({code: 1}); + tree.insert(key, value); + } + + function bisearch(tree, arr, queue) { + var start, end, mid; + + if (queue.length === 0) + return; + + start = queue.shift(); + end = queue.shift(); + + if (start > end) + return; + + mid = start + parseInt((end - start) / 2, 10); + addNode(tree, arr, mid); + queue.push(start, mid - 1); + queue.push(mid + 1, end); + } + + function build(arr) { + var tree, mid, lTree = [], rTree = []; + + tree = redblack.tree(); + mid = parseInt(arr.length / 2, 10); + addNode(tree, arr, mid); + + lTree.push(0, mid - 1); + rTree.push(mid + 1, arr.length - 1); + + while ((lTree.length > 0) || (rTree.length > 0)) { + bisearch(tree, arr, lTree); + bisearch(tree, arr, rTree); } + + return tree; } -}; -module.exports = _self; + function initialize() { + for (var key in dc) { + data[key] = build(dc[key]); + } + } + function traverse(tree, key) { + dc[key] = []; + tree.forEach(function (count, value) { + dc[key].push((count === 1) ? value : [value, count]); + }); + } -}); -define('ripple/platform/tizen/2.0/download', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. + function persist() { + if (ioStamp !== 0) { + window.clearTimeout(ioStamp); + } + ioStamp = window.setTimeout(function () { + var key; + + for (key in data) { + traverse(data[key], key); + } + + _save(); + + ioStamp = 0; + }, _data.PERSIST_DELAY); + } + + // public + function insert(key, value) { + var tree, count; + + if (!(key in data)) { + data[key] = redblack.tree(); + } + + tree = data[key]; + + if (!tree) + return false; + + count = tree.get(value); + tree.insert(value, count ? (count + 1) : 1); + persist(); + + return true; + } + + function remove(key, value) { + var tree, count; + + if (!(key in data)) + return false; + + tree = data[key]; + count = tree.get(value); + if (count === null) + return false; + + tree.delete(value); + + if (tree.root === null) { + delete data[key]; + if (key in dc) { + delete dc[key]; + } + } + + persist(); + + return true; + } + + function search(key) { + var values = [], tree; + + if (!(key in data)) + return null; + + tree = data[key]; + tree.forEach(function (count, value) { + while (count--) { + values.push(value); + } + }); + + return values; + } + + function update(key, oldValue, newValue) { + var tree, count; + + if (!(key in data)) + return false; + + tree = data[key]; + count = tree.get(oldValue); + if (count === null) + return false; + + tree.delete(oldValue); + tree.insert(newValue, count); + persist(); + + return true; + } + + initialize(); + + self = { + insert: insert, + remove: remove, + search: search, + update: update + }; + + return self; +}; + +_initialize(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/datasync', function (require, exports, module) { +/* + * Copyright 2013 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82707,338 +84935,598 @@ define('ripple/platform/tizen/2.0/download', function (require, exports, module) * See the License for the specific language governing permissions and * limitations under the License. */ + var db = require('ripple/db'), utils = require('ripple/utils'), - event = require('ripple/event'), + ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'), + t = require('ripple/platform/tizen/2.0/typecast'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), - filesystem = require('ripple/platform/tizen/2.0/filesystem'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - DownloadRequest = require('ripple/platform/tizen/2.0/DownloadRequest'), - DownloadState = { - QUEUED: "QUEUED", - DOWNLOADING: "DOWNLOADING", - PAUSED: "PAUSED", - CANCELED: "CANCELED", - COMPLETED: "COMPLETED", - FAILED: "FAILED" + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + SyncInfoMod = require('ripple/platform/tizen/2.0/SyncInfo'), + SyncServiceInfoMod = require('ripple/platform/tizen/2.0/SyncServiceInfo'), + SyncProfileInfoMod = require('ripple/platform/tizen/2.0/SyncProfileInfo'), + SyncStatistics = require('ripple/platform/tizen/2.0/SyncStatistics'), + _data = { + DB_DATASYNC_ITEMS: "tizen1-db-datasync-items", + DB_DATASYNC_COUNTER: "tizen1-db-datasync-counter", + MAX_PROFILE_NUMBER: 5, + profile_num: 0, + profiles: {}, + sync_accounts: {}, + service_accounts: {}, + item_counter: 1000, + type_table: { + "TWO_WAY": 1, + "SLOW": 2, + "ONE_WAY_FROM_CLIENT": 3, + "REFRESH_FROM_CLIENT": 4, + "ONE_WAY_FROM_SERVER": 5, + "REFRESH_FROM_SERVER": 6 + }, + mode_table: { + "TWO_WAY": 200, + "SLOW": 201, + "ONE_WAY_FROM_CLIENT": 202, + "REFRESH_FROM_CLIENT": 203, + "ONE_WAY_FROM_SERVER": 204, + "REFRESH_FROM_SERVER": 205 + }, + items: {} }, _security = { - "http://tizen.org/privilege/download": ["start"], - all: true + "http://tizen.org/privilege/datasync": + ["add", "update", "remove", "getMaxProfilesNum", "getProfilesNum", + "get", "getAll", "startSync", "stopSync", "getLastSyncStatistics"] }, - DB_DOWNLOAD_KEY = "tizen1-db-download", - DownloadItem, _isInitialized = false, INTERVAL = 1000, - _downloads = [], _resources = [], _self; + _self, + syncml = { + adapter: require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'), + agent: require('ripple/platform/tizen/2.0/syncml-js-lib/agent'), + base64: require('ripple/platform/tizen/2.0/syncml-js-lib/base64'), + codec: require('ripple/platform/tizen/2.0/syncml-js-lib/codec'), + common: require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant: require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + context: require('ripple/platform/tizen/2.0/syncml-js-lib/context'), + ctype: require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'), + devinfo: require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'), + item: require('ripple/platform/tizen/2.0/syncml-js-lib/item'), + localadapter: require('ripple/platform/tizen/2.0/syncml-js-lib/localadapter'), + matcher: require('ripple/platform/tizen/2.0/syncml-js-lib/matcher'), + protocol: require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'), + remoteadapter: require('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter'), + router: require('ripple/platform/tizen/2.0/syncml-js-lib/router'), + state: require('ripple/platform/tizen/2.0/syncml-js-lib/state'), + storage: require('ripple/platform/tizen/2.0/syncml-js-lib/storage'), + store: require('ripple/platform/tizen/2.0/syncml-js-lib/store'), + synchronizer: require('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer'), + useragent: require('ripple/platform/tizen/2.0/syncml-js-lib/useragent') + }, + TizenAgent; -function _checkDownloadParamters(download, callback) { - if (download === undefined || download === null || download.url === null || download.url === undefined) { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } - if (callback !== undefined && callback !== null && - (typeof callback.onprogress !== 'function' || - typeof callback.onpaused !== 'function' || - typeof callback.oncanceled !== 'function' || - typeof callback.oncompleted !== 'function' || - typeof callback.onfailed !== 'function')) { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } +function _get() { + _data.item_counter = db.retrieveObject(_data.DB_DATASYNC_COUNTER) || 1000; + _data.items = db.retrieveObject(_data.DB_DATASYNC_ITEMS) || {}; } -function _initDownloadItem(download) { - var url, index, isExist = false; - url = download.url; - if (download.destination === null) { - download.destination = "downloads"; - } - if (download.fileName === null) { - index = url.lastIndexOf('\/') + 1; - download.fileName = url.substring(index); - } - if (!_isInitialized) { - initializeResource(); - } - _resources.some(function (value) { - if (value.url === url) { - download.size = value.size; - download.speed = Number(value.speed); - download.estimatedTime = Math.round(value.estimatedTime * 100) / 100; - download.MIMEType = value.MIMEType; - isExist = true; - return; - } - }); - if (!isExist) { - download.state = DownloadState.FAILED; - _exec(download.callback, 'onfailed', download.id, new WebAPIError(errorcode.NOT_FOUND_ERR)); - return; - } - return download; +function _save() { + db.saveObject(_data.DB_DATASYNC_COUNTER, _data.item_counter); + db.saveObject(_data.DB_DATASYNC_ITEMS, _data.items); } -function _exec(callback, name, downloadId, arg1, arg2) { - if (callback === null) { - return; - } - switch (name) { - case "onprogress" : - callback[name](downloadId, arg1, arg2); - break; - case "onpaused" : - callback[name](downloadId); - break; - case "oncanceled" : - callback[name](downloadId); - break; - case "oncompleted" : - callback[name](downloadId, arg1); - break; - case "onfailed" : - callback[name](downloadId, arg1); - break; - default: - break; +TizenAgent = syncml.agent.Agent.extend({ + constructor: function() { + }, + getContentTypes: function() { + return [ + new syncml.ctype.ContentTypeInfo('text/x-vcard', '2.1',{preferred: true}) + ]; + }, + dumpsItem: function(item, contentType, version, cb) { + var cdata = new ET.CdataElement(item.item); + cb(null, cdata); + }, + loadsItem: function(data, contentType, version, cb) { + return cb(null, {item: data._node.textContent}); + }, + getAllItems: function(cb) { + var items = []; + utils.forEach(_data.items, function(contact) { + items.push(contact); + }); + return cb(null, items); + }, + addItem: function(item, cb) { + _data.item_counter++; + item.id = _data.item_counter.toString(); + _data.items[item.id] = item; + _save(); + return cb(null, item); + }, + getItem: function(itemID, cb) { + return cb(null, _data.items[itemID]); + }, + replaceItem: function(item, reportChanges, cb) { + _data.items[item.id] = item; + _save(); + return cb(null, null); + }, + deleteItem: function(itemID, cb) { + delete _data.items[itemID]; + _save(); + return cb(null); } +}); +function _initialize() { + _data.agent = new TizenAgent(); + _get(); } -function _getDownloadObjById(id) { - var isFound = false, backObj; - if (typeof id !== "number") { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } - id = Number(id); - _downloads.some(function (obj) { - if (obj.id === id) { - backObj = obj; - isFound = true; - return; +_self = function () { + var datasync; + + // private + function checkProfile(profile) { + var sync_account; + + if (!profile || Object.prototype.toString.call(profile) !== "[object Object]") { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - }); - if (!isFound) { - throw new WebAPIError(errorcode.NOT_FOUND_ERR); + + + t.SyncProfileInfo(profile); + + if (profile.serviceInfo && + Object.prototype.toString.call(profile.serviceInfo) !== "[object Array]") { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + + // check "type" if mode is "MANUAL" + // check "interval" if mode is "PERIODIC" + switch (profile.syncInfo.mode) { + case "MANUAL": + // (syncInfo.type) null is acceptable due to spec + // Spec: + // ...the sync type 'SHOULD' be specified. The default value is TWO_WAY + if (profile.syncInfo.type) { + profile.syncInfo.type = t.SyncType(profile.syncInfo.type); + } + break; + case "PERIODIC": + // (syncInfo.interval) null is acceptable + // Spec: + // .. The sync interval 'SHOULD' be provided. + // Question: Spec don't tell the default value when interval is null + if (profile.syncInfo.interval) { + profile.syncInfo.interval = t.SyncInterval(profile.syncInfo.interval); + } + break; + } + // check unreadable parameter: syncInfo (id/password) + if (typeof profile.syncInfo.__syncInfoID__ !== "number") { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + } + sync_account = db.retrieveObject("save-syncinfo")[profile.syncInfo.__syncInfoID__]; + sync_account.id = t.DOMString(sync_account.id); + sync_account.password = t.DOMString(sync_account.password); } - return backObj; -} -function initializeResource() { - _resources = db.retrieveObject(DB_DOWNLOAD_KEY); - _isInitialized = true; -} + function createInternalProfile(profile) { + var _profile, sync_account, service_accounts; -function _saveFile(downloadObj, callback) { - var name, path, content; + sync_account = db.retrieveObject("save-syncinfo")[profile.syncInfo.__syncInfoID__]; - name = downloadObj.fileName; - path = downloadObj.destination; - content = 'size|' + downloadObj.size + ',speed|' + downloadObj.speed + ',url|' + downloadObj.url + ',estimatedTime|' + downloadObj.estimatedTime; - function onsuccess(fs) { - fs.write(content); - fs.close(); + _profile = { + profileName: profile.profileName, + syncInfo: { + url: profile.syncInfo.url, + id: sync_account.id, + password: sync_account.password, + mode: profile.syncInfo.mode + }, + serviceInfo: [] + }; + + switch (_profile.syncInfo.mode) { + case "MANUAL": + _profile.syncInfo.type = profile.syncInfo.type || "TWO_WAY"; + break; + case "PERIODIC": + //TODO: set 1_HOUR as default value + _profile.interval = profile.syncInfo.interval || "1_HOUR"; + _profile.syncInfo.type = "TWO_WAY"; + break; + case "PUSH": + _profile.syncInfo.type = "TWO_WAY"; + break; + } + + if (profile.serviceInfo) { + service_accounts = db.retrieveObject("save-syncserviceinfo"); + utils.forEach(profile.serviceInfo, function (service) { + _profile.serviceInfo.push({ + enable: service.enable, + serviceType: service.serviceType, + serverDatabaseUri: service.serverDatabaseUri, + id: service_accounts[service.__syncServiceInfoID__].id, + password: service_accounts[service.__syncServiceInfoID__].password + }); + }); + } + + return _profile; } - function onerror(e) { - _exec(downloadObj.callback, 'onfailed', downloadObj.id, e); + + function createExternalProfile(profileId) { + var profile, i, _syncinfo, _serviceinfo, p; + + p = _data.profiles[profileId]; + + switch (p.syncInfo.mode) { + case "MANUAL": + _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "MANUAL", p.syncInfo.type); + _syncinfo.interval = null; + break; + case "PERIODIC": + _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "PERIODIC", p.syncInfo.interval); + break; + case "PUSH": + _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "PUSH"); + break; + } + + if (p.serviceInfo) { + _serviceinfo = []; + for (i in p.serviceInfo) { + var info; + info = new SyncServiceInfoMod(p.serviceInfo[i].enable, + p.serviceInfo[i].serviceType, p.serviceInfo[i].serverDatabaseUri, + p.serviceInfo[i].id, p.serviceInfo[i].password); + _serviceinfo.push(info); + } + } + + profile = new SyncProfileInfoMod(p.profileName, _syncinfo, _serviceinfo); + Object.defineProperty(profile, "profileId", {value: p.profileId, writable: false}); + + return profile; } - function rename(name) { //index.html==>index_1.html - var index, c; - index = name.lastIndexOf('.'); - if (index < 0) { - index = name.length; + + // public + function add(profile) { + var _profile; + + if (!_security.add) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - c = name.substr(index - 2, 1); - if (c === '_') { - name = name.substr(0, index - 1) + (Number(name.substr(index - 1, 1)) + 1) + name.substring(index); - } else { - name = name.substr(0, index) + "_1" + name.substring(index); + + checkProfile(profile); + _profile = createInternalProfile(profile); + + if (_data.profile_num > _data.MAX_PROFILE_NUMBER) { + throw new WebAPIException(errorcode.QUOTA_EXCEEDED_ERR); } - return name; + + _profile.profileId = Math.uuid(null, 16); + _data.profiles[_profile.profileId] = _profile; + _data.profile_num++; + + Object.defineProperty(profile, "profileId", {value: _profile.profileId, writable: false}); } - filesystem.resolve(path, function (dir) { - var file, isExist = true; - while (isExist) { - try { - file = dir.resolve(name); - name = rename(name); - } catch (e) { - isExist = false; - } + function update(profile) { + var _profile; + if (!_security.update) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - file = dir.createFile(name); - file.openStream('w', onsuccess, onerror, 'UTF-8'); - callback(name); - }, onerror, "rw"); -} -DownloadItem = function (download, callback) { - var _self; - _self = { - id : Number(Math.uuid(8, 10)), - url : download.url, - state : DownloadState.QUEUED, - fileName : download.fileName || null, - destination : download.destination || null, - callback : callback || null - }; - return _self; -}; + checkProfile(profile); + _profile = createInternalProfile(profile); -_self = function () { - function start(downloadRequest, downloadCallback) { - if (!_security.all && !_security.start) { - throw new WebAPIError(errorcode.SECURITY_ERR); + if (!profile.profileId || !_data.profiles[profile.profileId]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); } - var downloadObj, fileSize, increment, receivedSize = 0, intervalId; - _checkDownloadParamters(downloadRequest, downloadCallback); - downloadObj = new DownloadItem(downloadRequest, downloadCallback); - _downloads.push(downloadObj); - downloadObj = _initDownloadItem(downloadObj); - if (downloadObj === null || downloadObj === undefined) { - return; + _profile.profileId = profile.profileId; + _data.profiles[_profile.profileId] = _profile; + } + + function remove(profileId) { + if (!_security.remove) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - downloadObj.state = DownloadState.DOWNLOADING; - fileSize = downloadObj.size; - increment = downloadObj.speed; - intervalId = setInterval(function () { - if (receivedSize >= fileSize) {//Finish downloading - receivedSize = fileSize; - downloadObj.state = DownloadState.COMPLETED; - _saveFile(downloadObj, function (fileName) { - _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName); - }); - clearInterval(intervalId); - } else { // Continue downloading - receivedSize += increment; - downloadObj.receivedSize = receivedSize; - _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize); - } - }, INTERVAL); - downloadObj.intervalId = intervalId; - return downloadObj.id; + profileId = t.DOMString(profileId); + + if (!_data.profiles[profileId]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } + + delete _data.profiles[profileId]; + _data.profile_num--; } - function cancel(downloadId) { - var downloadObj = _getDownloadObjById(downloadId); - clearInterval(downloadObj.intervalId); - if (downloadObj.state !== DownloadState.DOWNLOADING) { - _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR)); - return; + function getMaxProfilesNum() { + if (!_security.getMaxProfilesNum) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - downloadObj.state = DownloadState.CANCELED; - _exec(downloadObj.callback, 'oncanceled', downloadObj.id); + + return _data.MAX_PROFILE_NUMBER; } - function pause(downloadId) { - var downloadObj = _getDownloadObjById(downloadId); - clearInterval(downloadObj.intervalId); - if (downloadObj.state !== DownloadState.DOWNLOADING) { - _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR)); - return; + function getProfilesNum() { + if (!_security.getProfilesNum) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - downloadObj.state = DownloadState.PAUSED; - _exec(downloadObj.callback, 'onpaused', downloadObj.id); + + return _data.profile_num; } - function resume(downloadId) { - var downloadObj, fileSize, receivedSize, increment, intervalId; + function get(profileId) { + var profile; + if (!_security.get) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } - downloadObj = _getDownloadObjById(downloadId); - fileSize = downloadObj.size; - receivedSize = downloadObj.receivedSize; - increment = downloadObj.speed; + profileId = t.DOMString(profileId); - if (downloadObj.state !== DownloadState.PAUSED) { - _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR)); - return; + if (!_data.profiles[profileId]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); } - downloadObj.state = DownloadState.DOWNLOADING; - intervalId = setInterval(function () { - if (receivedSize >= fileSize) {//Finish downloading - receivedSize = fileSize; - downloadObj.state = DownloadState.COMPLETED; - _saveFile(downloadObj, function (fileName) { - _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName); - }); - clearInterval(intervalId); - } else {// Continue downloading - receivedSize += increment; - downloadObj.receivedSize = receivedSize; - _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize); - } - }, INTERVAL); - downloadObj.intervalId = intervalId; + + profile = createExternalProfile(profileId); + + return profile; } - function getState(downloadId) { - var downloadObj = _getDownloadObjById(downloadId); - return downloadObj.state; + function getAll() { + var profiles = [], i; + if (!_security.getAll) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + for (i in _data.profiles) { + profiles.push(createExternalProfile(_data.profiles[i].profileId)); + } + + return profiles; } - function getDownloadRequest(downloadId) { - var req, downloadObj; - downloadObj = _getDownloadObjById(downloadId); - req = new DownloadRequest(downloadObj.url, downloadObj.destination, downloadObj.fileName); - return req; + function startSync(profileId, progressCallback) { + var _profile, _stores, _routes, sync_peer; + if (!_security.startSync) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + profileId = t.DOMString(profileId); + if (arguments.length >= 2) { + if (Object.prototype.toString.call(progressCallback) !== "[object Object]" || + (progressCallback.hasOwnProperty("onprogress") && + typeof progressCallback.onprogress !== "function") || + (progressCallback.hasOwnProperty("oncompleted") && + typeof progressCallback.oncompleted !== "function") || + (progressCallback.hasOwnProperty("onstopped") && + typeof progressCallback.onstopped !== "function") || + (progressCallback.hasOwnProperty("onfailed") && + typeof progressCallback.onfailed !== "function") || + (!progressCallback.hasOwnProperty("onprogress") && + !progressCallback.hasOwnProperty("oncompleted") && + !progressCallback.hasOwnProperty("onstopped") && + !progressCallback.hasOwnProperty("onfailed")) + ) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + } + + if (!_data.profiles[profileId]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } + _data.profiles[profileId].stop_flag = false; + + sync_peer = function(adapter, store, peer, type) { + adapter.sync(peer, type, function(err, stats) { + var p, name, hereTotal, peerTotal; + p = _data.profiles[profileId]; + if (p.stop_flag === true) { + p.syncStatistics =[{ + syncStatus: "STOP", + serviceType: p.serviceInfo[0].serviceType, + lastSyncTime: new Date(), + serverToClientTotal: 0, + serverToClientAdded: 0, + serverToClientUpdated: 0, + serverToClientRemoved: 0, + clientToServerTotal: 0, + clientToServerAdded: 0, + clientToServerUpdated: 0, + clientToServerRemoved: 0 + }]; + p.stop_flag = false; + return; + } + if (err) { + if (progressCallback) { + if (progressCallback.onfailed) { + progressCallback.onfailed(profileId, new WebAPIError(errorcode.UNKNOWN_ERR)); + } + } + p.syncStatistics =[{ + syncStatus: "FAIL", + serviceType: p.serviceInfo[0].serviceType, + lastSyncTime: new Date(), + serverToClientTotal: 0, + serverToClientAdded: 0, + serverToClientUpdated: 0, + serverToClientRemoved: 0, + clientToServerTotal: 0, + clientToServerAdded: 0, + clientToServerUpdated: 0, + clientToServerRemoved: 0 + }]; + p.stop_flag = false; + return; + } + name = p.profileName + "-" + p.serviceInfo[0].serviceType; + hereTotal = stats[name].hereAdd + stats[name].hereDel + stats[name].hereMod; + peerTotal = stats[name].peerAdd + stats[name].peerDel + stats[name].peerMod; + p.syncStatistics =[{ + syncStatus: "SUCCESS", + serviceType: p.serviceInfo[0].serviceType, + lastSyncTime: new Date(), + serverToClientTotal: hereTotal, + serverToClientAdded: stats[name].hereAdd, + serverToClientUpdated: stats[name].hereMod, + serverToClientRemoved: stats[name].hereDel, + clientToServerTotal: peerTotal, + clientToServerAdded: stats[name].peerAdd, + clientToServerUpdated: stats[name].peerMod, + clientToServerRemoved: stats[name].peerDel + }]; + p.stop_flag = false; + + if (progressCallback) { + if (progressCallback.oncompleted) { + progressCallback.oncompleted(profileId); + } + } + }); + }; + _profile = _data.profiles[profileId]; + _profile.context = new syncml.context.Context({prefix: "tizen-"}); + _stores = []; + _routes = []; + utils.forEach(_profile.serviceInfo, function(service) { + var name = _profile.profileName + "-" + service.serviceType; + _stores.push({ + uri: name, + displayName: name, + maxGuidSize: 64, + maxObjSize: 4000000, + agent: _data.agent + }); + _routes.push([name, service.serverDatabaseUri]); + }); + _profile.context.getEasyClientAdapter({ + displayName: "Tizen syncML adapter", + devInfo: { + devID: "tizen-syncml-03", + devType: syncml.constant.DEVTYPE_WORKSTATION, + manufacturerName: "Tizen", + modelName: "tizen.syncml.client", + hierarchicalSync: false + }, + stores: _stores, + peer: { + url: _profile.syncInfo.url, + username: _profile.syncInfo.id, + password: _profile.syncInfo.password + }, + routes: _routes + }, function(err, adapter, stores, peer) { + if (err) { + console.log("[datasync.syncml] getEasyClientAdapter fail:", err); + return; + } + utils.forEach(stores, function(store) { + var args = { + data: _data.mode_table[_profile.syncInfo.type], + source: store.uri, + target: _profile.serviceInfo[0].serverDatabaseUri, + nextAnchor: syncml.common.ts() + }; + if (args.data === _data.mode_table["SLOW"]) { + args.lastAnchor = null; + } else if (peer.getStore(args.target)) { + args.lastAnchor = peer.getStore(args.target)._getBinding().localAnchor; + } + + db.saveObject("syncml-alert-args", args); + db.saveObject("syncml-first-flag", false); + sync_peer(adapter, store, peer, _data.type_table[_profile.syncInfo.type]); + }); + }); + } - function getMIMEType(downloadId) { - var downloadObj = _getDownloadObjById(downloadId); - return downloadObj.MIMEType; + function stopSync(profileId) { + if (!_security.stopSync) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + profileId = t.DOMString(profileId); + + if (!_data.profiles[profileId]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } + + _data.profiles[profileId].stop_flag = true; } - function setListener(downloadId, callback) { - var downloadObj = _getDownloadObjById(downloadId); - if (callback !== undefined && callback !== null && - (typeof callback.onprogress !== 'function' || - typeof callback.onpaused !== 'function' || - typeof callback.oncanceled !== 'function' || - typeof callback.oncompleted !== 'function' || - typeof callback.onfailed !== 'function')) { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + function getLastSyncStatistics(profileId) { + var s, statistics = [], i; + if (!_security.getLastSyncStatistics) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + profileId = t.DOMString(profileId); + + if (!_data.profiles[profileId]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } + + s = _data.profiles[profileId].syncStatistics; + + for (i in s) { + statistics.push( + new SyncStatistics(s[i].syncStatus, s[i].serviceType, s[i].lastSyncTime, + s[i].serverToClientTotal, s[i].serverToClientAdded, + s[i].serverToClientUpdated, s[i].serverToClientRemoved, + s[i].clientToServerTotal, s[i].clientToServerAdded, + s[i].clientToServerUpdated, s[i].clientToServerRemoved) + ); } - downloadObj.callback = callback; + + return statistics; } function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); } } - var download = { - start: start, - cancel: cancel, - pause: pause, - resume: resume, - getState: getState, - getDownloadRequest: getDownloadRequest, - getMIMEType: getMIMEType, - setListener: setListener, - handleSubFeatures : handleSubFeatures + datasync = { + add: add, + update: update, + remove: remove, + getMaxProfilesNum: getMaxProfilesNum, + getProfilesNum: getProfilesNum, + get: get, + getAll: getAll, + startSync: startSync, + stopSync: stopSync, + getLastSyncStatistics: getLastSyncStatistics, + handleSubFeatures: handleSubFeatures }; - return download; + return datasync; }; -event.on('downloadResourceChanged', function () { - _isInitialized = false; -}); -module.exports = _self; +_initialize(); +module.exports = _self; }); -define('ripple/platform/tizen/2.0/errorcode', function (require, exports, module) { +define('ripple/platform/tizen/2.0/dbfs', function (require, exports, module) { /* - * Copyright 2011 Intel Corporation. + * Copyright 2011 Research In Motion Limited. + * Copyright 2012 Intel Corporation. * - * Licensed under the Apache License, Version 2.0 (the "License"), + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -83051,131 +85539,262 @@ define('ripple/platform/tizen/2.0/errorcode', function (require, exports, module * limitations under the License. */ -var _self = {}; - -_self.__defineGetter__("UNKNOWN_ERR", function () { - return 0; -}); +var db = require('ripple/db'), + utils = require('ripple/utils'), + _console = require('ripple/console'), + _cache = {}, + _self; -_self.__defineGetter__("INDEX_SIZE_ERR", function () { - return 1; -}); +function _get(path) { + return path.replace(/^\//, '').split("/").reduce(function (obj, token) { + return token === "" ? obj : ((obj && obj.children) ? obj.children[token] || null : null); + }, _cache); +} -_self.__defineGetter__("DOMSTRING_SIZE_ERR", function () { - return 2; -}); +function _getInfo(path) { + var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"), + name = parent.splice(parent.length - 1, 1).join(""); -_self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () { - return 3; -}); + return { + name: name, + parent: parent.join("/") || "/" + }; +} -_self.__defineGetter__("WRONG_DOCUMENT_ERR", function () { - return 4; -}); +function _set(path, obj) { + var parent = _cache, + tokens = path.replace(/^\//, '').split("/"), + child = tokens.splice(tokens.length - 1, 1).join(""); -_self.__defineGetter__("INVALID_CHARACTER_ERR", function () { - return 5; -}); + tokens.forEach(function (token) { + parent = parent.children[token]; + }); -_self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () { - return 6; -}); + parent.children = parent.children || {}; + parent.children[child] = obj; +} -_self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () { - return 7; -}); +function _delete(path) { + var parent = _cache, + tokens = path.replace(/^\//, '').split("/"), + child = tokens.splice(tokens.length - 1, 1).join(""); -_self.__defineGetter__("NOT_FOUND_ERR", function () { - return 8; -}); + tokens.forEach(function (token) { + parent = parent.children[token]; + }); -_self.__defineGetter__("NOT_SUPPORTED_ERR", function () { - return 9; -}); + delete parent.children[child]; +} -_self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () { - return 10; -}); +function _save() { + db.saveObject("tizen1-db-filesystem", _cache); +} -_self.__defineGetter__("INVALID_STATE_ERR", function () { - return 11; -}); +function _walk(path, parent) { + _self.ls(path, function (entries) { + parent.children = parent.children || {}; -_self.__defineGetter__("SYNTAX_ERR", function () { - return 12; -}); + entries.forEach(function (entry) { + parent.children[entry.name] = entry; -_self.__defineGetter__("INVALID_MODIFICATION_ERR", function () { - return 13; -}); + if (entry.isDirectory) { + _walk(entry.fullPath, entry); + } else { + /* after getting Date out of DB, Date will become + a string, so need to recast it back to Date */ + if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined) + entry.lastModifiedDate = new Date(entry.lastModifiedDate); + if (entry.createdDate !== null && entry.createdDate !== undefined) + entry.createdDate = new Date(entry.createdDate); -_self.__defineGetter__("NAMESPACE_ERR", function () { - return 14; -}); + _self.read(entry.fullPath, function (data) { + parent.children[entry.name].data = data; + }, function (e) { + _console.error(e); + }); + } + }); + }, function (e) { + _console.error(e); + }); +} -_self.__defineGetter__("INVALID_ACCESS_ERR", function () { - return 15; -}); +function _createPath(path) { + var parts = path.replace(/^\//, '').split("/"), + workflow = jWorkflow.order(); -_self.__defineGetter__("VALIDATION_ERR", function () { - return 16; -}); + parts.forEach(function (part, index) { + var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/"); -_self.__defineGetter__("TYPE_MISMATCH_ERR", function () { - return 17; -}); + workflow.andThen(function (prev, baton) { + baton.take(); + _self.mkdir(dir, baton.pass, baton.pass); + }); + }); -_self.__defineGetter__("SECURITY_ERR", function () { - return 18; -}); + workflow.start(); +} -_self.__defineGetter__("NETWORK_ERR", function () { - return 19; -}); +_self = { + // The order is consistent with _virtualRoots in filesystem.js + roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"], + initialize: function () { + // TODO: Initialize at bootstrap and emulatorBridge.link + _cache = db.retrieveObject("tizen1-db-filesystem") || {}; + // create real root paths if empty + _self.roots.every(function (root) { + _createPath(root); + return true; + }); + // build the file system cache so that we could access information synchronously + _walk("/", _cache); + }, + ls: function (path, success, error) { + try { + var dir = _get(path), + items = []; -_self.__defineGetter__("ABORT_ERR", function () { - return 20; -}); + if (dir) { + utils.forEach(dir.children, function (item) { + items.push(item); + }); + } + else { + items = {}; + } -_self.__defineGetter__("URL_MISMATCH_ERR", function () { - return 21; -}); + success(items); + } + catch (e) { + e.code = 1; + error(e); + } + }, + rm: function (path, success, error, options) { + _delete(path); + _save(); + success(); + }, + rmdir: function (path, success, error, options) { + _delete(path); + _save(); + success(); + }, + mkdir: function (path, success, error) { + var entry = _get(path), + info = _getInfo(path); -_self.__defineGetter__("QUOTA_EXCEEDED_ERR", function () { - return 22; -}); + if (!entry) { + _set(path, { + lastModifiedDate: new Date(), + createdDate: new Date(), + name: info.name, + isDirectory: true, + fullPath: path + }); + entry = _get(path); + _save(); + } -_self.__defineGetter__("TIMEOUT_ERR", function () { - return 23; -}); + if (entry) { + success(entry); + } + else { + error({code: 1}); + } + }, + mv: function (from, to, success, error) { + try { + var fromEntry = _get(from), + toInfo = _getInfo(to); -_self.__defineGetter__("INVALID_NODE_TYPE_ERR", function () { - return 24; -}); + fromEntry.fullPath = to; + fromEntry.name = toInfo.name; -_self.__defineGetter__("DATA_CLONE_ERR", function () { - return 25; -}); + _set(to, fromEntry); + _delete(from); + _save(); + success(); + } + catch (e) { + e.code = 1; + error(e); + } + }, + touch: function (path, success, error) { + var entry = _get(path), + info = _getInfo(path); -_self.__defineGetter__("INVALID_VALUES_ERR", function () { - return 99; -}); + if (!entry) { + _set(path, { + lastModifiedDate: new Date(), + createdDate: new Date(), + name: info.name, + isDirectory: false, + fullPath: path, + data: "" + }); + entry = _get(path); + } + _save(); + success(entry); + }, + cp: function (from, to, success, error) { + try { + var fromEntry = _get(from), + copied = utils.copy(fromEntry); -_self.__defineGetter__("IO_ERR", function () { - return 100; -}); + copied.name = _getInfo(to).name; + copied.fullPath = to; + _set(to, copied); + _save(); + success(); + } + catch (e) { + e.code = 1; + error(e); + } + }, + stat: function (path, success, error) { + var entry = _get(path); -_self.__defineGetter__("SERVICE_NOT_AVAILABLE_ERR", function () { - return 111; -}); + if (entry) { + success(entry); + } else { + error({code: 1}); + } + }, + write: function (path, contents, success, error, options) { + var entry = _get(path); -module.exports = _self; + if (entry) { + entry.lastModifiedDate = new Date(); + entry.data = contents; + _save(); + success(); + } else { + error({code: 1}); + } + + }, + read: function (path, success, error) { + var entry = _get(path); + + if (entry) { + success(utils.copy(entry.data)); + } + else { + error({code: 1}); + } + } +}; +module.exports = _self; }); -define('ripple/platform/tizen/2.0/filesystem', function (require, exports, module) { +define('ripple/platform/tizen/2.0/dbinit', function (require, exports, module) { /* - * Copyright 2012 Intel Corporation. + * Copyright 2013 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83190,1011 +85809,830 @@ define('ripple/platform/tizen/2.0/filesystem', function (require, exports, modul * limitations under the License. */ -var event = require('ripple/event'), - errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - utils = require('ripple/utils'), - dbfs = require('ripple/platform/tizen/2.0/dbfs'), - tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - _maxPathLength = 256, - _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"], - _security = { - "http://tizen.org/privilege/filesystem": [], - "http://tizen.org/privilege/filesystem.read": ["copyTo", "moveTo", "createDirectory", "createFile", "deleteDirectory", "deleteFile", "openStreamR"], - "http://tizen.org/privilege/filesystem.write": ["readAsText", "openStreamW"], - all: true +var utils = require('ripple/utils'), + dbfs = require('ripple/platform/tizen/2.0/dbfs'), + exception = require('ripple/exception'), + filesystem = require('ripple/platform/tizen/2.0/filesystem'), + DBBuilder, + Content, + FileSystem, + _data = { + dbBuilder: null }, - _realRoots = dbfs.roots, - _r2vmap = {}, - _v2rmap = {}, - _initialized = false, - _readOnly = false, - _writeOnly = false, - _defaultMode = "rw", - _storages = [], // filesystem storages - _observers = [], - File, - FileStream, - FileFilter, - FileSystemStorage; + _self = {}; -function _isValidChar(c) { - return (c >= '0' && c <= '9') || - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c === ' ') || - (c === '_') || - (c === '-') || - (c === '.'); +function _initialize() { + _data.dbBuilder = new DBBuilder(); + + _data.dbBuilder.register("FileSystem", FileSystem); + _data.dbBuilder.register("Content", Content, "dbcontent.xml"); } -function _isValidFileName(name) { - var _valid = true, - _c; +DBBuilder = function () { + var self; - if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) { - _valid = false; - } else { - for (_c = 0; _c < name.length; _c++) { - if (!_isValidChar(name[_c])) { - _valid = false; - break; - } - } + // private + function formatString(str) { + return str.replace(/^\s+|[\t\n\r\v]+|\s+$/g, '').replace(/\s+/g, ' '); } - return _valid; -} + function getAttributeValue(attr, type) { + var i, value; -function _initialize() { - var _i; + if (("childNodes" in attr) && (typeof type !== 'object')) { + value = []; - _storages.push(FileSystemStorage("InternalFlash", "INTERNAL", "MOUNTED" )); - _storages.push(FileSystemStorage("MMC", "EXTERNAL", "REMOVED")); - dbfs.initialize(); + for (i in attr.childNodes) { + value.push(getAttributeValue(attr.childNodes[i], type)); + } - // set up the map between real path and virtual path - for (_i = 0; _i < _virtualRoots.length; _i++) { - _r2vmap[_realRoots[_i]] = _virtualRoots[_i]; - } + return value; + } - utils.forEach(_r2vmap, function (value, key) { - _v2rmap[value] = key; - }); -} + switch (type) { + case "Date": + value = new Date(formatString(attr.textContent)); + break; -function _resolveSync(srcLocation, onSuccess, onError, accessMode) { - var _parts = srcLocation.replace(/\/$/, '').split("/"), - _header, _fullPath, - _i; + case "DOMString": + value = formatString(attr.textContent); + break; - // TODO: Initialize at bootstrap and emulatorBridge.link - if (!_initialized) { - _initialize(); - _initialized = true; - } + case "Number": + value = Number(formatString(attr.textContent)); + break; - for (_i = 0; _i < _parts.length; _i++) { - if (!_isValidFileName(_parts[_i])) { - if (onError) { - onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + default: + if (("childNodes" in attr) && (typeof type === 'object')) { + value = {}; + + for (i in attr.childNodes) { + value[attr.childNodes[i].nodeName] = getAttributeValue( + attr.childNodes[i], type[attr.childNodes[i].nodeName]); + } } - return; + break; } - } - _header = _v2rmap[_parts[0]]; - if (_header === undefined) { - if (onError) { - onError(new WebAPIError(errorcode.NOT_FOUND_ERR)); - } - return; + return value; } - if (_parts.length === 1) { - _fullPath = _header; - } else { - _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/"); + // public + function register(type, Module, xmlFile) { + _data[type] = new Module(); + _self[type] = _data[type].initdb(xmlFile); } - dbfs.stat(_fullPath, - function (entry) { - onSuccess(new File(entry, accessMode)); - }, - function () { - if (onError) { - onError(new WebAPIError(errorcode.NOT_FOUND_ERR)); - } - }); -} - -function _resolveAsync(onSuccess, onError, srcLocation, accessMode) { - _resolveSync(srcLocation, - function (file) { - setTimeout(function () { - onSuccess(file); - }, 1); - }, - function (e) { - setTimeout(function () { - onError(e); - }, 1); - }, - accessMode); -} - -File = function (entry, mode) { - var _entry = entry, - _mode = mode, - _parent, - _self; + function build(obj, pattern) { + var i, type, self = {}; - function _r2v(rpath) { - var i, v, r, regExp; + for (i in obj.childNodes) { + type = pattern[obj.childNodes[i].nodeName]; - for (i = 0; i < _virtualRoots.length; i++) { - v = _virtualRoots[i]; - r = _v2rmap[v]; - if (rpath.match("^" + r)) { - regExp = new RegExp("^" + r); - return rpath.replace(regExp, v); + if (type && obj.childNodes[i]) { + self[obj.childNodes[i].nodeName] = getAttributeValue( + obj.childNodes[i], type); } } - return ""; + return self; } - function _v2r(vpath) { - var i, v, r, regExp; + function parseXml(obj) { + var i, res = {}; - for (i = 0; i < _virtualRoots.length; i++) { - v = _virtualRoots[i]; - r = _v2rmap[v]; - if (vpath.match("^" + v)) { - regExp = new RegExp("^" + v); - return vpath.replace(regExp, r); + res.nodeName = obj.nodeName; + + if (obj.childElementCount === 0) { + res.textContent = obj.textContent; + } else { + res.childNodes = []; + + for (i in obj.childNodes) { + if (obj.childNodes[i].attributes) { + res.childNodes.push(parseXml(obj.childNodes[i])); + } } } - return ""; + return res; } - function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) { - var _srcName = String(src), - _dstName = String(dst), - _src = null, - _dst = null, - _error = false, - _dstParent = null, - _dstParts = _dstName.split("/"), - _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/"); + self = { + register: register, + build: build, + parseXml: parseXml + }; - if (!_entry.isDirectory) { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - return undefined; - } + return self; +}; - _resolveSync(_srcName, - function (file) { - _src = file; - }, - function (e) { - setTimeout(function () { - onError(e); - }, 1); - }, - _mode); +/* + * FileSystem + */ - if (_src) { - if (_src.parent.fullPath === _self.fullPath) { - if (!_readOnly && _mode !== "r") { - _resolveSync(_dstParentName, - function (file) { - _dstParent = file; - }, - function (e) { - setTimeout(function () { - onError(e); - }, 1); - }, - _mode); +FileSystem = function () { + var self; - if (_dstParent === null) { - return undefined; - } + // private + function createPath(path) { + var parts = path.replace(/^\//, '').split("/"), + workflow = jWorkflow.order(); - _resolveSync(_dstName, - function (file) { - _dst = file; - }, - function (e) { - if (e.code !== errorcode.NOT_FOUND_ERR) { - setTimeout(function () { - onError(e); - }, 1); - _error = true; - } - }, - _mode); + parts.forEach(function (part, index) { + var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/"); - if (_error) { - return undefined; - } + workflow.andThen(function (prev, baton) { + baton.take(); + dbfs.mkdir(dir, baton.pass, baton.pass); + }); + }); - if (_src.isFile) { - if (_dst === null) { - func(_v2r(_srcName), _v2r(_dstName), - function () { - setTimeout(function () { - onSuccess(); - }, 1); - }, - function () {}); - return null; - } else { - if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) { - func(_v2r(_srcName), _v2r(_dstName), - function () { - setTimeout(function () { - onSuccess(); - }, 1); - }, - function () {}); - return null; - } else { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - } - } else { - if (_dst === null) { - func(_v2r(_srcName), _v2r(_dstName), - function () { - setTimeout(function () { - onSuccess(); - }, 1); - }, - function () {}); - return null; - } else { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - } - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.SECURITY_ERR)); - }, 1); - } - } - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - } - } - - return undefined; + workflow.start(); } - _self = { - toURI: function () { - return "file://" + _entry.fullPath; - }, - listFiles: function (onSuccess, onError, filter) { - var _filter, _filterName, _startCreated, _endCreated, _startModified, _endModified; - - if (filter !== null && filter !== undefined) { + // public + function initdb() { + filesystem.resolve("images", function () {}); + filesystem.resolve("videos", function () {}); + filesystem.resolve("music", function () {}); - if (typeof filter === 'number' || typeof filter === 'string') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - _filter = filter; - _filterName = _filter.name; - _startModified = _filter.startModified; - _endModified = _filter.endModified; - _startCreated = _filter.startCreated; - _endCreated = _filter.endCreated; + return null; + } - } - if ((_filterName !== undefined && typeof _filterName !== 'string') || - (_startModified !== undefined && !tizen1_utils.isValidDate(_startModified)) || - (_endModified !== undefined && !tizen1_utils.isValidDate(_endModified)) || - (_endCreated !== undefined && !tizen1_utils.isValidDate(_endCreated)) || - (_startCreated !== undefined && !tizen1_utils.isValidDate(_startCreated))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + function createFile(uri) { + var directoryURI; - function _matchName(fileName) { - var _matched = true, - _name1 = String(_filterName).toLowerCase(), - _name2 = fileName.toLowerCase(), - _pattern; + directoryURI = uri.slice(0, uri.lastIndexOf('/') + 1); + dbfs.stat(directoryURI, function () {}, function () { + createPath(directoryURI); + }); - if (_filterName !== undefined && _filterName !== null) { - if (!_name1.match("\\\\%")) { - if (_name1.match("%")) { - _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$"); - _matched = _name2.match(_pattern) ? true : false; - } else { - _matched = (_name1 === _name2); - } - } else { - // % is not allowed as a part of file name - _matched = false; - } - } + dbfs.touch(uri, function () {}); + } - return _matched; - } + self = { + initdb: initdb, + createFile: createFile + }; - function _matchDate(date) { - var _matched = true; + return self; +}; - if (date === undefined) return true; +/* + * Content + */ - if (_startModified !== undefined && _startModified !== null) { - _matched = (date.getTime() >= _startModified.getTime()); - } +Content = function () { + var self, ImageContent, VideoContent, AudioContent, + DirectoryContent, ContentFactory; + + VideoContent = { + editableAttributes: "DOMString", + id: "DOMString", + name: "DOMString", + type: "DOMString", + mimeType: "DOMString", + title: "DOMString", + contentURI: "DOMString", + thumbnailURIs: "DOMString", + releaseDate: "Date", + modifiedDate: "Date", + size: "Number", + description: "DOMString", + rating: "Number", + + geolocation: {latitude: "Number", longtitude: "Number"}, + album: "DOMString", + artists: "DOMString", + duration: "Number", + width: "Number", + height: "Number" + }; + + AudioContent = { + editableAttributes: "DOMString", + id: "DOMString", + name: "DOMString", + type: "DOMString", + mimeType: "DOMString", + title: "DOMString", + contentURI: "DOMString", + thumbnailURIs: "DOMString", + releaseDate: "Date", + modifiedDate: "Date", + size: "Number", + description: "DOMString", + rating: "Number", + + album: "DOMString", + genres: "DOMString", + artists: "DOMString", + composers: "DOMString", + lyrics: { + type: "DOMString", + timestamps: "DOMString", + texts: "DOMString" + }, + copyright: "DOMString", + bitrate: "Number", + trackNumber: "Number", + duration: "Number" + }; + + ImageContent = { + editableAttributes: "DOMString", + id: "DOMString", + name: "DOMString", + type: "DOMString", + mimeType: "DOMString", + title: "DOMString", + contentURI: "DOMString", + thumbnailURIs: "DOMString", + releaseDate: "Date", + modifiedDate: "Date", + size: "Number", + description: "DOMString", + rating: "Number", + + geolocation: {latitude: "Number", longtitude: "Number"}, + width: "Number", + height: "Number", + orientation: "DOMString" + }; + + DirectoryContent = { + id: "DOMString", + directoryURI: "DOMString", + title: "DOMString", + storageType: "DOMString", + modifiedDate: "Date" + }; + + ContentFactory = function (type) { + var pattern; - if (_matched && (_endModified !== undefined && _endModified !== null)) { - _matched = (date.getTime() <= _endModified.getTime()); - } + switch (type) { + case "video": + pattern = VideoContent; + break; - return _matched; - } + case "audio": + pattern = AudioContent; + break; - function _matchFilter(entry) { - return _matchName(entry.name) && _matchDate(entry.lastModifiedDate) && _matchDate(entry.createdDate); - } + case "image": + pattern = ImageContent; + break; - function _listFiles() { - var _files = []; + case "directory": + pattern = DirectoryContent; + break; + } - if (!_entry.isDirectory) { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - return undefined; - } + return pattern; + }; - utils.forEach(_entry.children, function (child) { - if (_matchFilter(child)) { - _files.push(new File(child, _mode)); - } - }); + // public + function initdb(dbFileName) { + var i, db, results, xmlHttp; - setTimeout(function () { - onSuccess(_files); - }, 1); + db = { + contents: [], + directories: [] + }; + try { + if (!utils.appLocation()) return null; - } - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles); - }, - openStream: function (mode, onSuccess, onError, encoding) { - function _openStream() { - var _openMode = String(mode), - _encoding = encoding ? String(encoding) : "UTF-8"; + xmlHttp = new XMLHttpRequest(); + xmlHttp.open("GET", utils.appLocation() + dbFileName, false); + xmlHttp.send(); - if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); - }, 1); - } - return undefined; - } + if (!xmlHttp.responseXML) { + xmlHttp.open("GET", "dbsamples/" + dbFileName, false); + xmlHttp.send(); + } + } catch (e) { + exception.handle(e); + } - if (!_security.all && ((!_security.openStreamR && _openMode === "r") || (!_security.openStreamW && _openMode === "w"))) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } + if (!xmlHttp.responseXML) { + return db; + } - if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); - }, 1); - } - return undefined; - } + results = _data.dbBuilder.parseXml(xmlHttp.responseXML.documentElement); + results.childNodes[0].childNodes.forEach(function (node) { + db.contents.push(_data.dbBuilder.build(node, + new ContentFactory(node.nodeName))); + }); + results.childNodes[1].childNodes.forEach(function (node) { + db.directories.push(_data.dbBuilder.build(node, + new ContentFactory(node.nodeName))); + }); - if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) || - (_writeOnly && _openMode === "r")) { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.SECURITY_ERR)); - }, 1); - } - return undefined; - } + for (i in db.contents) { + _data.FileSystem.createFile(db.contents[i].contentURI); + } - setTimeout(function () { - onSuccess(new FileStream(_entry, _openMode, _encoding)); - }, 1); + return db; + } - return null; - } + self = { + initdb: initdb + }; - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream); - }, - readAsText: function (onSuccess, onError, encoding) { - if (!_security.all && !_security.readAsText) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } + return self; +}; - function _readAsText() { - var _encoding = encoding ? String(encoding) : "UTF-8"; - if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); - }, 1); - } - return undefined; - } +_initialize(); - if (_writeOnly) { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.SECURITY_ERR)); - }, 1); - } - return undefined; - } +module.exports = _self; - if (_self.isFile) { - dbfs.read(_entry.fullPath, - function (data) { - setTimeout(function () { - onSuccess(data); - }, 1); - }, - function () {}); - return null; - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - } +}); +define('ripple/platform/tizen/2.0/download', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var db = require('ripple/db'), + event = require('ripple/event'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + filesystem = require('ripple/platform/tizen/2.0/filesystem'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + DownloadRequest = require('ripple/platform/tizen/2.0/DownloadRequest'), + DownloadState = { + QUEUED: "QUEUED", + DOWNLOADING: "DOWNLOADING", + PAUSED: "PAUSED", + CANCELED: "CANCELED", + COMPLETED: "COMPLETED", + FAILED: "FAILED" + }, + _security = { + "http://tizen.org/privilege/download": ["start"] + }, + DB_DOWNLOAD_KEY = "tizen1-db-download", + DownloadItem, _isInitialized = false, INTERVAL = 1000, + _downloads = [], _resources = [], _self; - return undefined; - } +function _checkDownloadParamters(download, callback) { + if (!download || !download.url) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + _checkDownloadCallback (callback); +} - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText); - }, - copyTo: function (src, dst, overwrite, onSuccess, onError) { - if (!_security.all && !_security.copyTo) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } +function _checkDownloadCallback (callback) { + var func = ['onprogress', 'onpaused', 'oncanceled', + 'oncompleted', 'onfailed']; - function _copyTo() { - return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp); + if (callback) { + func.forEach(function (name) { + if (callback.hasOwnProperty(name) && + typeof callback[name] !== 'function') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } + }); + } +} - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo); - }, - moveTo: function (src, dst, overwrite, onSuccess, onError) { - if (!_security.all && !_security.moveTo) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } +function _initDownloadItem(download) { + var url, index, isExist = false; + url = download.url; + if (download.destination === null) { + download.destination = "downloads"; + } + if (download.fileName === null) { + index = url.lastIndexOf('\/') + 1; + download.fileName = url.substring(index); + } + if (!_isInitialized) { + initializeResource(); + } + _resources.some(function (value) { + if (value.url === url) { + download.size = Number(value.size); + download.speed = Number(value.speed); + download.estimatedTime = Math.round(value.estimatedTime * 100) / 100; + download.MIMEType = value.MIMEType; + isExist = true; + return; + } + }); + if (!isExist) { + download.state = DownloadState.FAILED; + _exec(download.callback, 'onfailed', download.id, new WebAPIError(errorcode.NOT_FOUND_ERR)); + return; + } + return download; +} - function _moveTo() { - return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv); - } +function _exec(callback, name, downloadId, arg1, arg2) { + if (callback === null) { + return; + } + switch (name) { + case "onprogress" : + callback[name](downloadId, arg1, arg2); + break; + case "onpaused" : + callback[name](downloadId); + break; + case "oncanceled" : + callback[name](downloadId); + break; + case "oncompleted" : + callback[name](downloadId, arg1); + break; + case "onfailed" : + callback[name](downloadId, arg1); + break; + default: + break; + } +} - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo); - }, - createDirectory: function (dirPath) { - var _path = String(dirPath), - _parts = _path.replace(/\/$/, "").split("/"), - _dir = null, - _exist = null, - _current = _entry.fullPath, - _i; +function _getDownloadObjById(id) { + var isFound = false, backObj; + if (typeof id !== "number") { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + } + id = Number(id); + _downloads.some(function (obj) { + if (obj.id === id) { + backObj = obj; + isFound = true; + return; + } + }); + if (!isFound) { + throw new WebAPIError(errorcode.NOT_FOUND_ERR); + } + return backObj; +} - if (!_security.all && !_security.createDirectory) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } +function initializeResource() { + _resources = db.retrieveObject(DB_DOWNLOAD_KEY); + _isInitialized = true; +} - function onSuccess(entry) { - _dir = entry; - } +function _saveFile(downloadObj, callback) { + var name, path, content; - for (_i = 0; _i < _parts.length; _i++) { - if (!_isValidFileName(_parts[_i])) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } - } + name = downloadObj.fileName; + path = downloadObj.destination; + content = 'size|' + downloadObj.size + ',speed|' + downloadObj.speed + ',url|' + downloadObj.url + ',estimatedTime|' + downloadObj.estimatedTime; + function onsuccess(fs) { + fs.write(content); + fs.close(); + } + function onerror(e) { + _exec(downloadObj.callback, 'onfailed', downloadObj.id, e); + } + function rename(name) { //index.html==>index_1.html + var index, c; + index = name.lastIndexOf('.'); + if (index < 0) { + index = name.length; + } + c = name.substr(index - 2, 1); + if (c === '_') { + name = name.substr(0, index - 1) + (Number(name.substr(index - 1, 1)) + 1) + name.substring(index); + } else { + name = name.substr(0, index) + "_1" + name.substring(index); + } + return name; + } - if (!entry.isDirectory) { - throw new WebAPIException(errorcode.IO_ERR); + filesystem.resolve(path, function (dir) { + var file, isExist = true; + while (isExist) { + try { + file = dir.resolve(name); + name = rename(name); + } catch (e) { + isExist = false; } + } + file = dir.createFile(name); + file.openStream('w', onsuccess, onerror, 'UTF-8'); + callback(name); + }, onerror, "rw"); +} - _exist = _parts.reduce(function (obj, token) { - return token === "" ? obj : (obj.children ? obj.children[token] || null : null); - }, _entry); +DownloadItem = function (download, callback) { + var _self; + _self = { + id : Number(Math.uuid(8, 10)), + url : download.url, + state : DownloadState.QUEUED, + fileName : download.fileName || null, + destination : download.destination || null, + callback : callback || null + }; + return _self; +}; - if (_exist) { - throw new WebAPIException(errorcode.IO_ERR); - } +_self = function () { + function start(downloadRequest, downloadCallback) { + if (!_security.all && !_security.start) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + var downloadObj, fileSize, increment, receivedSize = 0, intervalId; - if (_readOnly || _mode === "r") { - throw new WebAPIException(errorcode.SECURITY_ERR); - } + _checkDownloadParamters(downloadRequest, downloadCallback); + downloadObj = new DownloadItem(downloadRequest, downloadCallback); + _downloads.push(downloadObj); + downloadObj = _initDownloadItem(downloadObj); + if (downloadObj === null || downloadObj === undefined) { + return; + } + downloadObj.state = DownloadState.DOWNLOADING; - for (_i = 0; _i < _parts.length; _i++) { - _current = _current + "/" + _parts[_i]; - dbfs.mkdir(_current, onSuccess); + fileSize = downloadObj.size; + increment = downloadObj.speed; + intervalId = setInterval(function () { + if (receivedSize >= fileSize) {//Finish downloading + receivedSize = fileSize; + downloadObj.state = DownloadState.COMPLETED; + _saveFile(downloadObj, function (fileName) { + _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName); + }); + clearInterval(intervalId); + } else { // Continue downloading + receivedSize += increment; + downloadObj.receivedSize = receivedSize; + _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize); } + }, INTERVAL); + downloadObj.intervalId = intervalId; + return downloadObj.id; + } - return new File(_dir, _mode); - }, - createFile: function (filePath) { - var _name = String(filePath), - _file = null; + function cancel(downloadId) { + var downloadObj = _getDownloadObjById(downloadId); + clearInterval(downloadObj.intervalId); + if (downloadObj.state !== DownloadState.DOWNLOADING && + downloadObj.state !== DownloadState.PAUSED) { + _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR)); + return; + } + downloadObj.state = DownloadState.CANCELED; + _exec(downloadObj.callback, 'oncanceled', downloadObj.id); + } - if (!_security.all && !_security.createFile) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } - - if (!_isValidFileName(_name)) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } - - if (!entry.isDirectory || (_entry.children && _entry.children[_name])) { - throw new WebAPIException(errorcode.IO_ERR); - } - - if (_readOnly || _mode === "r") { - throw new WebAPIException(errorcode.SECURITY_ERR); - } - - dbfs.touch(_entry.fullPath + "/" + _name, - function (entry) { - _file = new File(entry, _mode); - }, - function () {}); - - return _file; - }, - resolve: function (filePath) { - var _fullPath = _self.fullPath + "/" + String(filePath), - _file = null; - - if (!_entry.isDirectory) { - throw new WebAPIException(errorcode.IO_ERR); - } - - _resolveSync(_fullPath, - function (file) { - _file = file; - }, - function (e) { - throw (e); - }, - _mode); - - return _file; - }, - deleteDirectory: function (directory, recursive, onSuccess, onError) { - if (!_security.all && !_security.deleteDirectory) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } - - function _deleteDirectory() { - var _dir = null, - _dirName = String(directory); - _resolveSync(_dirName, - function (file) { - _dir = file; - }, - function (e) { - setTimeout(function () { - onError(e); - }, 1); - }, - _mode); + function pause(downloadId) { + var downloadObj = _getDownloadObjById(downloadId); + clearInterval(downloadObj.intervalId); + if (downloadObj.state !== DownloadState.DOWNLOADING) { + _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR)); + return; + } + downloadObj.state = DownloadState.PAUSED; + _exec(downloadObj.callback, 'onpaused', downloadObj.id); + } - if (_dir) { - if (_dir.isDirectory && - _dir.parent.fullPath === _self.fullPath && - (!recursive && _dir.length === 0)) { - if (!_readOnly && _mode !== "r") { - dbfs.rmdir(_v2r(_dirName), - function () { - setTimeout(function () { - onSuccess(); - }, 1); - }, - function () {}); - return null; - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.SECURITY_ERR)); - }, 1); - } - } - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - } - } + function resume(downloadId) { + var downloadObj, fileSize, receivedSize, increment, intervalId; - return undefined; - } + downloadObj = _getDownloadObjById(downloadId); + fileSize = downloadObj.size; + receivedSize = downloadObj.receivedSize; + increment = downloadObj.speed; - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory); - }, - deleteFile: function (fileName, onSuccess, onError) { - if (!_security.all && !_security.deleteFile) { - throw new WebAPIException(errorcode.SECURITY_ERR); + if (downloadObj.state !== DownloadState.PAUSED) { + _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR)); + return; + } + downloadObj.state = DownloadState.DOWNLOADING; + intervalId = setInterval(function () { + if (receivedSize >= fileSize) {//Finish downloading + receivedSize = fileSize; + downloadObj.state = DownloadState.COMPLETED; + _saveFile(downloadObj, function (fileName) { + _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName); + }); + clearInterval(intervalId); + } else {// Continue downloading + receivedSize += increment; + downloadObj.receivedSize = receivedSize; + _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize); } + }, INTERVAL); + downloadObj.intervalId = intervalId; + } - function _deleteFile() { - var _file = null; - _resolveSync(String(fileName), - function (file) { - _file = file; - }, - function (e) { - if (onError) { - setTimeout(function () { - onError(e); - }, 1); - } - }, - _mode); + function getState(downloadId) { + var downloadObj = _getDownloadObjById(downloadId); + return downloadObj.state; + } - if (_file) { - if (_file.isFile && _file.parent.fullPath === _self.fullPath) { - if (!_readOnly && _mode !== "r") { - dbfs.rm(_v2r(fileName), - function () { - setTimeout(function () { - onSuccess(); - }, 1); - }, - function () {}); - return null; - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.SECURITY_ERR)); - }, 1); - } - } - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.IO_ERR)); - }, 1); - } - } - } + function getDownloadRequest(downloadId) { + var req, downloadObj; + downloadObj = _getDownloadObjById(downloadId); + req = new DownloadRequest(downloadObj.url, downloadObj.destination, downloadObj.fileName); + return req; + } - return undefined; - } + function getMIMEType(downloadId) { + var downloadObj = _getDownloadObjById(downloadId); + return downloadObj.MIMEType; + } - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile); + function setListener(downloadId, callback) { + var downloadObj = _getDownloadObjById(downloadId); + if (downloadObj) { + _checkDownloadCallback (callback); + downloadObj.callback = callback; } - }; + } - _self.__defineGetter__("parent", function () { - var _parts = _self.fullPath.split("/"); + function handleSubFeatures(subFeatures) { + var i, subFeature; - if (_parent === undefined) { - if (_parts.length === 1) { - // virtual root's parent is null - _parent = null; - } else { - _resolveSync(_parts.splice(0, _parts.length - 1).join("/"), - function (file) { - _parent = file; - }, - function () {}, - _mode); + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - return _parent; - } else { - return _parent; } - }); + } - _self.__defineGetter__("readOnly", function () { - return false; - }); + var download = { + start: start, + cancel: cancel, + pause: pause, + resume: resume, + getState: getState, + getDownloadRequest: getDownloadRequest, + getMIMEType: getMIMEType, + setListener: setListener, + handleSubFeatures : handleSubFeatures + }; - _self.__defineGetter__("isFile", function () { - return !_entry.isDirectory; - }); + return download; +}; - _self.__defineGetter__("isDirectory", function () { - return _entry.isDirectory; - }); +event.on('downloadResourceChanged', function () { + _isInitialized = false; +}); +module.exports = _self; - _self.__defineGetter__("created", function () { - return _entry.createdDate; - }); - _self.__defineGetter__("modified", function () { - return _entry.lastModifiedDate; - }); +}); +define('ripple/platform/tizen/2.0/errorcode', function (require, exports, module) { +/* + * Copyright 2011 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"), + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - _self.__defineGetter__("path", function () { - var _parts = _self.fullPath.split("/"); +var _self = {}; - if (_parts.length === 1) { - // virtual root - return _parts.join(""); - } else { - return _parts.splice(0, _parts.length - 1).join("/") + "/"; - } - }); +_self.__defineGetter__("UNKNOWN_ERR", function () { + return 0; +}); - _self.__defineGetter__("name", function () { - return _entry.name; - }); +_self.__defineGetter__("INDEX_SIZE_ERR", function () { + return 1; +}); - _self.__defineGetter__("fullPath", function () { - return _r2v(_entry.fullPath); - }); +_self.__defineGetter__("DOMSTRING_SIZE_ERR", function () { + return 2; +}); - _self.__defineGetter__("fileSize", function () { - if (_entry.isDirectory) { - return undefined; - } else { - return _entry.data.length; - } - }); +_self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () { + return 3; +}); - _self.__defineGetter__("length", function () { - var _l = 0; - if (_entry.isDirectory) { - utils.forEach(_entry.children, function () { - _l++; - }); - return _l; - } else { - return undefined; - } - }); +_self.__defineGetter__("WRONG_DOCUMENT_ERR", function () { + return 4; +}); - return _self; -}; +_self.__defineGetter__("INVALID_CHARACTER_ERR", function () { + return 5; +}); -FileStream = function (entry, mode, encoding) { - var _entry = entry, - _data = entry.data, - _mode = mode, - _position = (_mode === "a" ? _data.length : 0), - _self; +_self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () { + return 6; +}); - _self = { - close: function () { - var _element; - if (mode === "a" || mode === "w") { - dbfs.write(_entry.fullPath, _data, function () {}, function () {}); - } - for (_element in _self) { - delete _self[_element]; - } - }, - read: function (charCount) { - var _count = charCount | 0, - _substr = _data.substring(_position, _position + _count); +_self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () { + return 7; +}); - if (_position + _count > _data.length) { - _position = _data.length; - } else { - _position += _count; - } +_self.__defineGetter__("NOT_FOUND_ERR", function () { + return 8; +}); - return _substr; - }, - readBytes: function (byteCount) { - var _substr = _self.read(byteCount), - _bytes = [], - _i; +_self.__defineGetter__("NOT_SUPPORTED_ERR", function () { + return 9; +}); - for (_i = 0; _i < _substr.length; _i++) { - _bytes.push(_substr.charCodeAt(_i)); - } +_self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () { + return 10; +}); - return _bytes; - }, - readBase64: function (byteCount) { - var _substr = _self.read(byteCount); +_self.__defineGetter__("INVALID_STATE_ERR", function () { + return 11; +}); - return window.atob(_substr); - }, - write: function (stringData) { - var _stringData = String(stringData), - _substr = _data.substring(0, _position); +_self.__defineGetter__("SYNTAX_ERR", function () { + return 12; +}); - _data = _substr.concat(_stringData); - _position = _data.length; - }, - writeBytes: function (byteData) { - _self.write(String.fromCharCode.apply(String, byteData)); - }, - writeBase64: function (base64Data) { - _self.write(window.btoa(String(base64Data))); - } - }; +_self.__defineGetter__("INVALID_MODIFICATION_ERR", function () { + return 13; +}); - _self.__defineGetter__("eof", function () { - return _position === _data.length; - }); +_self.__defineGetter__("NAMESPACE_ERR", function () { + return 14; +}); - _self.__defineGetter__("position", function () { - return _position; - }); +_self.__defineGetter__("INVALID_ACCESS_ERR", function () { + return 15; +}); - _self.__defineSetter__("position", function (value) { - var _value = value | 0; +_self.__defineGetter__("VALIDATION_ERR", function () { + return 16; +}); - if (_value >= 0 && _value <= _data.length) { - _position = _value; - } else { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } - }); +_self.__defineGetter__("TYPE_MISMATCH_ERR", function () { + return 17; +}); - _self.__defineGetter__("bytesAvailable", function () { - return (_data.length - _position) || -1; - }); +_self.__defineGetter__("SECURITY_ERR", function () { + return 18; +}); - return _self; -}; +_self.__defineGetter__("NETWORK_ERR", function () { + return 19; +}); -FileFilter = function (name, startModified, endModified, startCreated, endCreated) { - var _self = { - name: name, - startModified: utils.copy(startModified), - endModified: utils.copy(endModified), - endCreated: utils.copy(endCreated) - }; +_self.__defineGetter__("ABORT_ERR", function () { + return 20; +}); - return _self; -}; +_self.__defineGetter__("URL_MISMATCH_ERR", function () { + return 21; +}); -FileSystemStorage = function (label, type, state) { - var _self = { - label: label, - type: type, - state: state - }; +_self.__defineGetter__("QUOTA_EXCEEDED_ERR", function () { + return 22; +}); - return _self; -}; +_self.__defineGetter__("TIMEOUT_ERR", function () { + return 23; +}); -module.exports = { - maxPathLength: _maxPathLength, - resolve: function (srcLocation, onSuccess, onError, accessMode) { - function _resolve() { - var _mode = accessMode ? String(accessMode) : _defaultMode; +_self.__defineGetter__("INVALID_NODE_TYPE_ERR", function () { + return 24; +}); - if (_mode === "r" || _mode === "rw") { - _resolveAsync(onSuccess, onError, String(srcLocation), _mode); - return null; - } else { - if (onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); - }, 1); - } - } - return undefined; - } +_self.__defineGetter__("DATA_CLONE_ERR", function () { + return 25; +}); - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve); - }, +_self.__defineGetter__("INVALID_VALUES_ERR", function () { + return 99; +}); - getStorage: function (label, onSuccess, onError) { - var storage = null, _label = String(label); +_self.__defineGetter__("IO_ERR", function () { + return 100; +}); - _storages.some(function (value) { - if (value.label === _label) { - storage = utils.copy(value); - setTimeout(function () { - onSuccess(storage); - }, 1); - return true; - } - }); +_self.__defineGetter__("SERVICE_NOT_AVAILABLE_ERR", function () { + return 111; +}); - if (!storage) { - if(onError) { - setTimeout(function () { - onError(new WebAPIError(errorcode.NOT_FOUND_ERR)); - }, 1); - - } else { - throw new WebAPIException(errorcode.NOT_FOUND_ERR); - } - } - }, - - listStorages: function (onSuccess, onError) { - function _listStorages() { - setTimeout(function () { - onSuccess(utils.copy(_storages)); - }, 1); - } - - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listStorages", _listStorages); - }, - - addStorageStateChangeListener: function(onSuccess, onError) { - function _addStorageStateChangeListener() { - var watchId = (new Date()).getTime() || 0; - _observers[watchId] = function(storage) {//storage is which state is changed - onSuccess(storage); - }; - - // This event should be triggered from outside - event.on("StateChange", _observers[watchId]); - return Number(watchId); - } - - return tizen1_utils.validateTypeMismatch(onSuccess, onError, "addStorageStateChangeListener", _addStorageStateChangeListener); - }, - - removeStorageStateChangeListener: function (watchId) { - if (!watchId || typeof watchId !== "number") { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - watchId = String(watchId); - - if (_observers[watchId]) { - event.deleteEventHandler("StateChange", _observers[watchId]); - delete _observers[watchId]; - } else { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } - }, - - handleSubFeatures: function (subFeatures) { - function setSecurity(_security) { - return function (method) { - _security[method] = true; - }; - } - - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; - utils.forEach(_security[subFeature], setSecurity); - } - } -}; +module.exports = _self; }); -define('ripple/platform/tizen/2.0/geoBackend_local', function (require, exports, module) { +define('ripple/platform/tizen/2.0/filesystem', function (require, exports, module) { /* * Copyright 2012 Intel Corporation. * @@ -84211,1350 +86649,1013 @@ define('ripple/platform/tizen/2.0/geoBackend_local', function (require, exports, * limitations under the License. */ -var db = require('ripple/db'), - utils = require('ripple/utils'), - lbs = require('ripple/platform/tizen/2.0/lbs_utils'), +var event = require('ripple/event'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + utils = require('ripple/utils'), + dbfs = require('ripple/platform/tizen/2.0/dbfs'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - PendingObject = require('ripple/platform/tizen/2.0/pendingObject'), - PendingOperation = require('ripple/platform/tizen/2.0/pendingoperation'), - SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), - GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult'), - _GEO_OBJECTS = "tizen1.0-geocode-objects", - _get, _save, _geoList_init, GeoEntry, - _checkAddressType, _transAddressStr, - _geocodeByString, _findCoordsByString, _geocodeByAddress, - _reverseGeocodeBySimple, _reverseGeocodeByGeo, _checkCoordsType, - _self, _geoList = [], - _PENDING_TIME = 10; - -function _get() { - var geoList = [], - data = db.retrieveObject(_GEO_OBJECTS); - - utils.forEach(data, function (geo) { - geoList.push(geo); - }); - return geoList; -} + _maxPathLength = 256, + _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"], + _security = { + "http://tizen.org/privilege/filesystem": [], + "http://tizen.org/privilege/filesystem.read": ["copyTo", "moveTo", "createDirectory", "createFile", "deleteDirectory", "deleteFile", "openStreamR"], + "http://tizen.org/privilege/filesystem.write": ["readAsText", "openStreamW"], + all: true + }, + _realRoots = dbfs.roots, + _r2vmap = {}, + _v2rmap = {}, + _initialized = false, + _readOnly = false, + _writeOnly = false, + _defaultMode = "rw", + _storages = [], // filesystem storages + _observers = [], + File, + FileStream, + FileFilter, + FileSystemStorage; -function _save() { - db.saveObject(_GEO_OBJECTS, _geoList); +function _isValidChar(c) { + return (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c === ' ') || + (c === '_') || + (c === '-') || + (c === '.'); } -function _geoList_init() { - var entry; - _geoList = _get(); +function _isValidFileName(name) { + var _valid = true, + _c; - /* Put some default data if database is empty */ - if (_geoList.length === 0) { - entry = new GeoEntry(new lbs.StructuredAddress({ - country : "UK", - region : "London", - county : "Lambeth", - city : "London", - street : "Westminster Bridge Road", - streetNumber : "1", - premises : "Riverside Building", - additionalInformation : "London Eye", - postalCode : "SE1 7PB" - }), - new lbs.GeoCoordinates({ - latitude : 51.510452, - longitude : -0.119820, - altitude : 0, - accuracy : 0, - altitudeAccuracy : 0, - heading : 0, - speed : 0 - })); - _geoList.push(entry); - entry = new GeoEntry(new lbs.StructuredAddress({ - country : "UK", - city : "London", - street : "Baker Street", - streetNumber : "221B", - postalCode : "NW1 6XE" - }), - new lbs.GeoCoordinates({ - latitude : 51.524552, - longitude : -0.158615, - altitude : 0, - accuracy : 0, - altitudeAccuracy : 0, - heading : 0, - speed : 0 - })); - _geoList.push(entry); - entry = new GeoEntry(new lbs.StructuredAddress({ - country : "US", - region : "OR", - city : "Portland", - street : "SE Water Ave", - streetNumber : "1945", - additionalInformation : "OMSI", - }), - new lbs.GeoCoordinates({ - latitude : 45.508490, - longitude : -122.665953, - altitude : 0, - accuracy : 0, - altitudeAccuracy : 0, - heading : 0, - speed : 0 - })); - _geoList.push(entry); - entry = new GeoEntry(new lbs.StructuredAddress({ - country : "US", - region : "OR", - city : "Portland", - street : "NW Pittock Drive", - streetNumber : "3229", - additionalInformation : "Pittock Mansion", - }), - new lbs.GeoCoordinates({ - latitude : 45.531365, - longitude : -122.716255, - altitude : 0, - accuracy : 0, - altitudeAccuracy : 0, - heading : 0, - speed : 0 - })); - _geoList.push(entry); - entry = new GeoEntry(new lbs.StructuredAddress({ - region : "OR", - city : "Hillsboro", - street : "NE 25th St", - streetNumber : "2111", - postalCode : "97124" - }), - new lbs.GeoCoordinates({ - latitude : 45.543479, - longitude : -122.9621601, - altitude : 0, - accuracy : 0, - altitudeAccuracy : 0, - heading : 0, - speed : 0 - })); - _geoList.push(entry); - _save(); + if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) { + _valid = false; + } else { + for (_c = 0; _c < name.length; _c++) { + if (!_isValidChar(name[_c])) { + _valid = false; + break; + } + } } -} - -function _pendingOperate(operate) { - var pendingObj, pendingOperation, i, argumentVector = []; - - for (i = 0; i < arguments.length - 1; i++) - argumentVector[i] = arguments[i + 1]; - - pendingObj = new PendingObject(); - - pendingObj.pendingID = window.setTimeout(function () { - pendingObj.setCancelFlag(false); - operate.apply(this, argumentVector); - }, _PENDING_TIME); - pendingOperation = new PendingOperation(pendingObj); - - return pendingOperation; + return _valid; } -function GeoEntry(addr, coord) { - var _self; - _self = { - address : addr || null, - coordinate : coord || null - }; - return _self; -} +function _initialize() { + var _i; -function SortMode() { - var _self; - _self = { - attributeName : "", - order : "ASC" - }; - return _self; -} + _storages.push(FileSystemStorage("InternalFlash", "INTERNAL", "MOUNTED" )); + _storages.push(FileSystemStorage("MMC", "EXTERNAL", "REMOVED")); + dbfs.initialize(); -function _transAddressStr(addr) { - var str = ""; - if (addr.additionalInformation !== null && addr.additionalInformation !== undefined) - str = str + addr.additionalInformation + ", "; - if (addr.premises !== null && addr.premises !== undefined) - str = str + addr.premises + ", "; - if (addr.streetNumber !== null && addr.streetNumber !== undefined) - str = str + addr.streetNumber + " "; - if (addr.street !== null && addr.street !== undefined) - str = str + addr.street + ", "; - if (addr.city !== null && addr.city !== undefined) - str = str + addr.city + ", "; - if (addr.county !== null && addr.county !== undefined) - str = str + addr.county + ", "; - if (addr.region !== null && addr.region !== undefined) - str = str + addr.region + ", "; - if (addr.country !== null && addr.country !== undefined) - str = str + addr.country + ", "; - if (addr.postalCode !== null && addr.postalCode !== undefined) - str = str + addr.postalCode; + // set up the map between real path and virtual path + for (_i = 0; _i < _virtualRoots.length; _i++) { + _r2vmap[_realRoots[_i]] = _virtualRoots[_i]; + } - if (str.lastIndexOf(", ") === str.length - 2) - str = str.slice(0, -2); - return str; + utils.forEach(_r2vmap, function (value, key) { + _v2rmap[value] = key; + }); } -function _concatAddress(addr) { - var str = ""; - if (addr.additionalInformation !== null && addr.additionalInformation !== undefined) - str = str + addr.additionalInformation + " "; - if (addr.premises !== null && addr.premises !== undefined) - str = str + addr.premises + " "; - if (addr.streetNumber !== null && addr.streetNumber !== undefined) - str = str + addr.streetNumber + " "; - if (addr.street !== null && addr.street !== undefined) - str = str + addr.street + " "; - if (addr.city !== null && addr.city !== undefined) - str = str + addr.city + " "; - if (addr.county !== null && addr.county !== undefined) - str = str + addr.county + " "; - if (addr.region !== null && addr.region !== undefined) - str = str + addr.region + " "; - if (addr.country !== null && addr.country !== undefined) - str = str + addr.country + " "; - if (addr.postalCode !== null && addr.postalCode !== undefined) - str = str + addr.postalCode; +function _resolveSync(srcLocation, onSuccess, onError, accessMode) { + var _parts = srcLocation.replace(/\/$/, '').split("/"), + _header, _fullPath, + _i; - return str; -} + // TODO: Initialize at bootstrap and emulatorBridge.link + if (!_initialized) { + _initialize(); + _initialized = true; + } -function _findCoordsByString(address) { - var array = [], reg, str, searchAddr, pieces, i; - if (address.length === 0) - return array; + for (_i = 0; _i < _parts.length; _i++) { + if (!_isValidFileName(_parts[_i])) { + if (onError) { + onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + } + return; + } + } - pieces = address.split(","); - searchAddr = ""; - for (i = 0; i < pieces.length; i++) { - searchAddr = searchAddr + pieces[i]; + _header = _v2rmap[_parts[0]]; + if (_header === undefined) { + if (onError) { + onError(new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + return; } - reg = new RegExp(searchAddr, "i"); - - utils.forEach(_geoList, function (item) { - str = _concatAddress(item.address); - if (str.search(reg) !== -1) - array.push(new GeocodeResult(item.coordinate.latitude, item.coordinate.longitude)); - }); - return array; + if (_parts.length === 1) { + _fullPath = _header; + } else { + _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/"); + } + + dbfs.stat(_fullPath, + function (entry) { + onSuccess(new File(entry, accessMode)); + }, + function () { + if (onError) { + onError(new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + }); } -function _geocodeByString(address, successCB, errorCB, options) { - var array; - array = _findCoordsByString(address); - successCB(array); +function _resolveAsync(onSuccess, onError, srcLocation, accessMode) { + _resolveSync(srcLocation, + function (file) { + setTimeout(function () { + onSuccess(file); + }, 1); + }, + function (e) { + setTimeout(function () { + onError(e); + }, 1); + }, + accessMode); } -function _findCoordsByAddress(addr) { - var array = [], select = false, i; - for (i = 0; i < _geoList.length; i++) { - select = false; - if (addr.country !== null && addr.country !== undefined) { - if (addr.country === _geoList[i].address.country) - select = true; - else - continue; - } - - if (addr.region !== null && addr.region !== undefined) { - if (addr.region === _geoList[i].address.region) - select = true; - else - continue; - } +File = function (entry, mode) { + var _entry = entry, + _mode = mode, + _parent, + _self; - if (addr.county !== null && addr.county !== undefined) { - if (addr.county === _geoList[i].address.county) - select = true; - else - continue; - } + function _r2v(rpath) { + var i, v, r, regExp; - if (addr.city !== null && addr.city !== undefined) { - if (addr.city === _geoList[i].address.city) - select = true; - else - continue; + for (i = 0; i < _virtualRoots.length; i++) { + v = _virtualRoots[i]; + r = _v2rmap[v]; + if (rpath.match("^" + r)) { + regExp = new RegExp("^" + r); + return rpath.replace(regExp, v); + } } - if (addr.street !== null && addr.street !== undefined) { - if (addr.street === _geoList[i].address.street) - select = true; - else - continue; - } + return ""; + } - if (addr.streetNumber !== null && addr.streetNumber !== undefined) { - if (addr.streetNumber === _geoList[i].address.streetNumber) - select = true; - else - continue; - } + function _v2r(vpath) { + var i, v, r, regExp; - if (addr.premises !== null && addr.premises !== undefined) { - if (addr.premises === _geoList[i].address.premises) - select = true; - else - continue; + for (i = 0; i < _virtualRoots.length; i++) { + v = _virtualRoots[i]; + r = _v2rmap[v]; + if (vpath.match("^" + v)) { + regExp = new RegExp("^" + v); + return vpath.replace(regExp, r); + } } - if (addr.additionalInformation !== null && - addr.additionalInformation !== undefined) { - if (addr.additionalInformation === _geoList[i].address.additionalInformation) - select = true; - else - continue; - } + return ""; + } - if (addr.postalCode !== null && addr.postalCode !== undefined) { - if (addr.postalCode === _geoList[i].address.postalCode) - select = true; - else - continue; - } + function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) { + var _srcName = String(src), + _dstName = String(dst), + _src = null, + _dst = null, + _error = false, + _dstParent = null, + _dstParts = _dstName.split("/"), + _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/"); - if (select === true) { - array.push(new GeocodeResult(_geoList[i].coordinate.latitude, _geoList[i].coordinate.longitude)); + if (!_entry.isDirectory) { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } + return undefined; } - } - - return array; -} -function _geocodeByAddress(address, successCB, errorCB, options) { - var array; - array = _findCoordsByAddress(address); - successCB(array); -} + _resolveSync(_srcName, + function (file) { + _src = file; + }, + function (e) { + setTimeout(function () { + onError(e); + }, 1); + }, + _mode); -function _checkAddressType(address) { - var str; - if (typeof address === "string") { - str = "string"; - } else if (typeof address === "object") { - str = "StructuredAddress"; - } else { - str = "typeMismatch"; - } - return str; -} + if (_src) { + if (_src.parent.fullPath === _self.fullPath) { + if (!_readOnly && _mode !== "r") { + _resolveSync(_dstParentName, + function (file) { + _dstParent = file; + }, + function (e) { + setTimeout(function () { + onError(e); + }, 1); + }, + _mode); -function _checkCoordsType(coord) { - var str; - /* SimpleCoordinates is a subset of GeoCoordinates. - SimpleCoordinates includes latitude, longitude as mandatory fields only. - GeoCoordinates not only includes latitude, longitude as mandatory fields - but also at least includes one more other optional fields */ - if (typeof coord !== "object") { - str = "typeMismatch"; - } else if (typeof coord.latitude === "number" && - typeof coord.longitude === "number") { - str = "simpleCoordinates"; - if (typeof coord.altitude === "number" || - typeof coord.accuracy === "number" || - typeof coord.altitudeAccuracy === "number" || - typeof coord.heading === "number" || - typeof coord.speed === "number") { - str = "geoCoordinates"; - } - } else { - str = "typeMismatch"; - } + if (_dstParent === null) { + return undefined; + } - return str; -} + _resolveSync(_dstName, + function (file) { + _dst = file; + }, + function (e) { + if (e.code !== errorcode.NOT_FOUND_ERR) { + setTimeout(function () { + onError(e); + }, 1); + _error = true; + } + }, + _mode); -function _findReverseGeocode(coords, options) { - var array = [], _isStructured = false, i; - if (options !== null && options !== undefined) { - if (options.resultType === "STRUCTURED") { - _isStructured = true; - } - } - for (i = 0; i < _geoList.length; i++) { - if (_geoList[i].coordinate.latitude === coords.latitude && - _geoList[i].coordinate.longitude === coords.longitude) { - if (coords.altitude) { - if (_geoList[i].coordinate.altitude !== coords.altitude) - continue; - } - if (coords.accuracy) { - if (_geoList[i].coordinate.accuracy !== coords.accuracy) - continue; - } - if (coords.altitudeAccuracy) { - if (_geoList[i].coordinate.altitudeAccuracy !== coords.altitudeAccuracy) - continue; - } - if (coords.heading) { - if (_geoList[i].coordinate.heading !== coords.heading) - continue; - } - if (coords.speed) { - if (_geoList[i].coordinate.speed !== coords.speed) - continue; - } + if (_error) { + return undefined; + } - if (_isStructured === true) { - array.push(new lbs.StructuredAddress(_geoList[i].address)); + if (_src.isFile) { + if (_dst === null) { + func(_v2r(_srcName), _v2r(_dstName), + function () { + setTimeout(function () { + onSuccess(); + }, 1); + }, + function () {}); + return null; + } else { + if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) { + func(_v2r(_srcName), _v2r(_dstName), + function () { + setTimeout(function () { + onSuccess(); + }, 1); + }, + function () {}); + return null; + } else { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } + } + } else { + if (_dst === null) { + func(_v2r(_srcName), _v2r(_dstName), + function () { + setTimeout(function () { + onSuccess(); + }, 1); + }, + function () {}); + return null; + } else { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } + } + } else { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.SECURITY_ERR)); + }, 1); + } + } } else { - array.push(_transAddressStr(_geoList[i].address)); + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } } } + + return undefined; } - return array; -} -function _reverseGeocodeByGeo(coordinates, successCB, errorCB, options) { - var array, coord; - coord = new lbs.GeoCoordinates(coordinates); - array = _findReverseGeocode(coord, options); - return successCB(array); -} + _self = { + toURI: function () { + return "file://" + _entry.fullPath; + }, + listFiles: function (onSuccess, onError, filter) { + var _filter, _filterName, _startCreated, _endCreated, _startModified, _endModified; -function _reverseGeocodeBySimple(coordinates, successCB, errorCB, options) { - var array, coord; - coord = new lbs.GeoCoordinates({ - latitude : coordinates.latitude, - longitude : coordinates.longitude - }); - array = _findReverseGeocode(coord, options); - return successCB(array); -} + if (filter !== null && filter !== undefined) { -module.exports = function (prop) { - var _self = new lbs.LocationServiceProvider(prop); - _geoList_init(); - - _self.geocode = function (address, successCB, errorCB, options) { - function _geocode() { - var ret; - - ret = _pendingOperate(function () { - /* address: its type is AbstractAddress. - It could be StructuredAddress or String */ - if (_checkAddressType(address) === "string") { - _geocodeByString(address, successCB, errorCB, options); - } else if (_checkAddressType(address) === "StructuredAddress") { - _geocodeByAddress(address, successCB, errorCB, options); - } else { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + if (typeof filter === 'number' || typeof filter === 'string') { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - }); - } + _filter = filter; + _filterName = _filter.name; + _startModified = _filter.startModified; + _endModified = _filter.endModified; + _startCreated = _filter.startCreated; + _endCreated = _filter.endCreated; - tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode); - }; + } + if ((_filterName !== undefined && typeof _filterName !== 'string') || + (_startModified !== undefined && !tizen1_utils.isValidDate(_startModified)) || + (_endModified !== undefined && !tizen1_utils.isValidDate(_endModified)) || + (_endCreated !== undefined && !tizen1_utils.isValidDate(_endCreated)) || + (_startCreated !== undefined && !tizen1_utils.isValidDate(_startCreated))) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } - _self.reverseGeocode = function (coordinates, successCB, errorCB, options) { - function _reverseGeocode() { - var ret; - - ret = _pendingOperate(function () { - /* coordinates: Its type is AbstractCoordinates. - It could be SimpleCoordinates or GeoCoordinates */ - if (_checkCoordsType(coordinates) === "simpleCoordinates") { - _reverseGeocodeBySimple(coordinates, successCB, errorCB, options); - } else if (_checkCoordsType(coordinates) === "geoCoordinates") { - _reverseGeocodeByGeo(coordinates, successCB, errorCB, options); - } else { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } - }); - } + function _matchName(fileName) { + var _matched = true, + _name1 = String(_filterName).toLowerCase(), + _name2 = fileName.toLowerCase(), + _pattern; - tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode); - }; + if (_filterName !== undefined && _filterName !== null) { + if (!_name1.match("\\\\%")) { + if (_name1.match("%")) { + _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$"); + _matched = _name2.match(_pattern) ? true : false; + } else { + _matched = (_name1 === _name2); + } + } else { + // % is not allowed as a part of file name + _matched = false; + } + } - return _self; -}; + return _matched; + } + function _matchDate(date) { + var _matched = true; -}); -define('ripple/platform/tizen/2.0/geoBackend_nominatim', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + if (date === undefined) return true; -var lbs = require('ripple/platform/tizen/2.0/lbs_utils'), - errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult'); + if (_startModified !== undefined && _startModified !== null) { + _matched = (date.getTime() >= _startModified.getTime()); + } -function _concatAddrString(addr) { - var ret = "", i, pieces; - if (typeof addr === "string") { - pieces = addr.split(" "); - for (i = 0; i < pieces.length; i++) { - ret = ret + pieces[i] + "+"; - } - } else if (typeof addr === "object") { - if (addr.premises !== null && addr.premises !== undefined) { - ret = ret + addr.premises + "+"; - } - if (addr.streetNumber !== null && addr.streetNumber !== undefined) { - ret = ret + addr.streetNumber + "+"; - } - if (addr.street !== null && addr.street !== undefined) { - ret = ret + addr.street + "+"; - } - if (addr.city !== null && addr.city !== undefined) { - ret = ret + addr.city + "+"; - } - if (addr.county !== null && addr.county !== undefined) { - ret = ret + addr.county + "+"; - } - if (addr.region !== null && addr.region !== undefined) { - ret = ret + addr.region + "+"; - } - if (addr.postalCode !== null && addr.postalCode !== undefined) { - ret = ret + addr.postalCode + "+"; - } - if (addr.country !== null && addr.country !== undefined) { - ret = ret + addr.country + "+"; - } - } else { - return undefined; - } - ret = ret.slice(0, -1); - return ret; -} + if (_matched && (_endModified !== undefined && _endModified !== null)) { + _matched = (date.getTime() <= _endModified.getTime()); + } -module.exports = function (prop) { - var _self = new lbs.LocationServiceProvider(prop); - - _self.geocode = function (address, successCB, errorCB, options) { - function _geocode() { - var i, searchStr, coordinates = [], result; + return _matched; + } - searchStr = _concatAddrString(address); - if (searchStr === undefined) { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + function _matchFilter(entry) { + return _matchName(entry.name) && _matchDate(entry.lastModifiedDate) && _matchDate(entry.createdDate); } - searchStr = "http://nominatim.openstreetmap.org/search?q=" + searchStr + "&format=json&polygon=1&addressdetails=1"; - /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */ - $.getJSON(searchStr, function (data) { - for (i = 0; i < data.length; i++) { - result = new GeocodeResult(parseFloat(data[i].lat), parseFloat(data[i].lon)); - coordinates.push(result); - } - successCB(coordinates); - }).error(function () { - if (errorCB) { - setTimeout(function () { - errorCB(new WebAPIError(errorcode.NETWORK_ERR)); - }, 1); + function _listFiles() { + var _files = []; + + if (!_entry.isDirectory) { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } + return undefined; } - }); - } - tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode); - }; + utils.forEach(_entry.children, function (child) { + if (_matchFilter(child)) { + _files.push(new File(child, _mode)); + } + }); - _self.reverseGeocode = function (coordinates, successCB, errorCB, options) { - function _reverseGeocode() { - var searchStr = ""; - if (typeof coordinates !== "object" || - typeof coordinates.latitude !== "number" || - typeof coordinates.longitude !== "number") { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + setTimeout(function () { + onSuccess(_files); + }, 1); + + return null; } - searchStr = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" + - coordinates.latitude + "&lon=" + coordinates.longitude + "&zoom=18&addressdetails=1"; - /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */ - $.getJSON(searchStr, function (data) { - var addr; + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles); + }, + openStream: function (mode, onSuccess, onError, encoding) { + function _openStream() { + var _openMode = String(mode), + _encoding = encoding ? String(encoding) : "UTF-8"; - if (options && options.resultType === "STRUCTURED") { - addr = new lbs.StructuredAddress({ - country : data.address.country, - region : data.address.state, - county : data.address.county, - city : data.address.city, - street : data.address.road, - streetNumber : data.address.streetNumber, - postalCode : data.address.postcode - }); - } else { - addr = data.display_name; - } - successCB([addr]); - }).error(function () { - if (errorCB) { - setTimeout(function () { - errorCB(new WebAPIError(errorcode.NETWORK_ERR)); - }, 1); + if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + }, 1); + } + return undefined; } - }); - } - tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode); - }; - - return _self; -}; + if (!_security.all && ((!_security.openStreamR && _openMode === "r") || (!_security.openStreamW && _openMode === "w"))) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + }, 1); + } + return undefined; + } -}); -define('ripple/platform/tizen/2.0/geocoder', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) || + (_writeOnly && _openMode === "r")) { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.SECURITY_ERR)); + }, 1); + } + return undefined; + } -var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), - ProviderLocal = require('ripple/platform/tizen/2.0/geoBackend_local'), - ProviderNominatim = require('ripple/platform/tizen/2.0/geoBackend_nominatim'), // Nominatim geocode service - _getProviders, - _providers, - _self; + setTimeout(function () { + onSuccess(new FileStream(_entry, _openMode, _encoding)); + }, 1); -function _initialize() { - _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"}) - /* ,new ProviderLocal({name : "Tizen Database", connectivity : "OFFLINE"}) */]; -} + return null; + } -_initialize(); + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream); + }, + readAsText: function (onSuccess, onError, encoding) { + if (!_security.all && !_security.readAsText) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -_self = { - getDefaultProvider : function () { - return _providers[0]; - }, - getProviders : function () { - return _providers; - } -}; + function _readAsText() { + var _encoding = encoding ? String(encoding) : "UTF-8"; + if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + }, 1); + } + return undefined; + } -module.exports = _self; + if (_writeOnly) { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.SECURITY_ERR)); + }, 1); + } + return undefined; + } -}); -define('ripple/platform/tizen/2.0/lbs_utils', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - _self; + if (_self.isFile) { + dbfs.read(_entry.fullPath, + function (data) { + setTimeout(function () { + onSuccess(data); + }, 1); + }, + function () {}); + return null; + } else { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } + } -function CoordinateProperties(prop) { - var _self; - _self = { - latitude : prop.latitude || 0, - longitude : prop.longitude || 0, - altitude : prop.altitude || 0, - accuracy : prop.accuracy || 0, - altitudeAccuracy : prop.altitudeAccuracy || 0, - heading : prop.heading || 0, - speed : prop.speed || 0 - }; - return _self; -} + return undefined; + } -function _checkAddressProperties(p, dst) { - if (p.country !== null && p.country !== undefined) - dst.country = String(p.country); - if (p.region !== null && p.region !== undefined) - dst.region = String(p.region); - if (p.county !== null && p.county !== undefined) - dst.county = String(p.county); - if (p.city !== null && p.city !== undefined) - dst.city = String(p.city); - if (p.street !== null && p.street !== undefined) - dst.street = String(p.street); - if (p.streetNumber !== null && p.streetNumber !== undefined) - dst.streetNumber = String(p.streetNumber); - if (p.premises !== null && p.premises !== undefined) - dst.premises = String(p.premises); - if (p.additionalInformation !== null && - p.additionalInformation !== undefined) - dst.additionalInformation = String(p.additionalInformation); - if (p.postalCode !== null && p.postalCode !== undefined) - dst.postalCode = String(p.postalCode); -} + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText); + }, + copyTo: function (src, dst, overwrite, onSuccess, onError) { + if (!_security.all && !_security.copyTo) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -function AddressProperties(prop) { - var _self; - _self = { - country : null, - region : null, - county : null, - city : null, - street : null, - streetNumber : null, - premises : null, - additionalInformation : null, - postalCode : null - }; - if (prop) { - if (_checkAddressProperties(prop, _self) === false) - return undefined; - } - return _self; -} + function _copyTo() { + return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp); + } -_self = { - LocationServiceProvider : function (prop) { - var _self; - _self = { - name : "", - metaData : Object, - attribution : "", - supportedOptions : [], - setOptions : function (options, successCB, errorCB) {}, - connectivity : "" // "ONLINE" "OFFLINE" "HYBRID" - }; + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo); + }, + moveTo: function (src, dst, overwrite, onSuccess, onError) { + if (!_security.all && !_security.moveTo) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } - if (prop.name !== null && prop.name !== undefined) - _self.name = String(prop.name); - if (prop.metaData !== null && prop.metaData !== undefined) - _self.metaData = prop.metaData; + function _moveTo() { + return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv); + } - if (prop.attribution !== null && prop.attribution !== undefined) - _self.attribution = String(prop.attribution); + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo); + }, + createDirectory: function (dirPath) { + var _path = String(dirPath), + _parts = _path.replace(/\/$/, "").split("/"), + _dir = null, + _exist = null, + _current = _entry.fullPath, + _i; - if (prop.supportedOptions !== null && prop.supportedOptions !== undefined) - _self.supportedOptions = [prop.supportedOptions]; + if (!_security.all && !_security.createDirectory) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } - if (prop.setOptions !== null && prop.setOptions !== undefined) - _self.setOptions = prop.setOptions; + function onSuccess(entry) { + _dir = entry; + } - if (prop.connectivity !== null && prop.connectivity !== undefined) - _self.connectivity = String(prop.connectivity); + for (_i = 0; _i < _parts.length; _i++) { + if (!_isValidFileName(_parts[_i])) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } + } - return _self; - }, + if (!entry.isDirectory) { + throw new WebAPIException(errorcode.IO_ERR); + } - GeoCoordinates : function (prop) { - var _self = new CoordinateProperties(prop); - if (tizen1_utils.isEmptyObject(_self)) { - return undefined; - } + _exist = _parts.reduce(function (obj, token) { + return token === "" ? obj : (obj.children ? obj.children[token] || null : null); + }, _entry); - return _self; - }, - - StructuredAddress : function (prop) { - var _self; - _self = new AddressProperties(prop); - if (tizen1_utils.isEmptyObject(_self)) { - return undefined; - } + if (_exist) { + throw new WebAPIException(errorcode.IO_ERR); + } - return _self; - } -}; + if (_readOnly || _mode === "r") { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -module.exports = _self; + for (_i = 0; _i < _parts.length; _i++) { + _current = _current + "/" + _parts[_i]; + dbfs.mkdir(_current, onSuccess); + } -}); -define('ripple/platform/tizen/2.0/map', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + return new File(_dir, _mode); + }, + createFile: function (filePath) { + var _name = String(filePath), + _file = null; -var lbs = require('ripple/platform/tizen/2.0/lbs_utils'), - mapProviders = [], - MapStyle, - MapProvider, - _self; + if (!_security.all && !_security.createFile) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -function _initialize() { - // EPSG:3857 is a Spherical Mercator projection coordinate system popularized by web services such as Google and later OpenStreetMap - // mapStyles are from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames - var projection = "EPSG:3857", - mapStyle1 = new MapStyle("Mapnik", "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png"), - mapStyle2 = new MapStyle("Cycle", "http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png"); + if (!_isValidFileName(_name)) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } - mapProviders = [new MapProvider({name: "OpenStreetMap", connectivity: "ONLINE"}, projection, [mapStyle1, mapStyle2])]; -} + if (!entry.isDirectory || (_entry.children && _entry.children[_name])) { + throw new WebAPIException(errorcode.IO_ERR); + } -_self = { - getDefaultProvider: function () { - return mapProviders[0]; - }, - getProviders: function () { - return mapProviders; - } -}; + if (_readOnly || _mode === "r") { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -MapStyle = function (name, url) { - return { - name: name, - url: url - }; -}; + dbfs.touch(_entry.fullPath + "/" + _name, + function (entry) { + _file = new File(entry, _mode); + }, + function () {}); -MapProvider = function (prop, projection, mapStyles) { - var mapProvider = new lbs.LocationServiceProvider(prop); + return _file; + }, + resolve: function (filePath) { + var _fullPath = _self.fullPath + "/" + String(filePath), + _file = null; - mapProvider.__defineGetter__("projection", function () { - return projection; - }); + if (!_entry.isDirectory) { + throw new WebAPIException(errorcode.IO_ERR); + } - mapProvider.__defineGetter__("mapStyles", function () { - return mapStyles; - }); + _resolveSync(_fullPath, + function (file) { + _file = file; + }, + function (e) { + throw (e); + }, + _mode); - return mapProvider; -}; + return _file; + }, + deleteDirectory: function (directory, recursive, onSuccess, onError) { + if (!_security.all && !_security.deleteDirectory) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -_initialize(); + function _deleteDirectory() { + var _dir = null, + _dirName = String(directory); + _resolveSync(_dirName, + function (file) { + _dir = file; + }, + function (e) { + setTimeout(function () { + onError(e); + }, 1); + }, + _mode); -module.exports = _self; + if (_dir) { + if (_dir.isDirectory && + _dir.parent.fullPath === _self.fullPath && + (!recursive && _dir.length === 0)) { + if (!_readOnly && _mode !== "r") { + dbfs.rmdir(_v2r(_dirName), + function () { + setTimeout(function () { + onSuccess(); + }, 1); + }, + function () {}); + return null; + } else { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.SECURITY_ERR)); + }, 1); + } + } + } else { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } + } + } -}); -define('ripple/platform/tizen/2.0/messaging', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + return undefined; + } -var _self, - errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - MessagingService = require('ripple/platform/tizen/2.0/MessagingService'), - tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - t = require('ripple/platform/tizen/2.0/typedef'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), - TIZEN_MESSAGING_SMS = "messaging.sms", - TIZEN_MESSAGING_MMS = "messaging.mms", - TIZEN_MESSAGING_EMAIL = "messaging.email", - _security_check = {send: false, read: false, write: false}, - _sms_service = null, - _mms_service = null, - _email_service = null; + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory); + }, + deleteFile: function (fileName, onSuccess, onError) { + if (!_security.all && !_security.deleteFile) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } -_self = function () { - this.getMessageServices = function (messageServiceType, onSuccess, onError) { - var service; + function _deleteFile() { + var _file = null; + _resolveSync(String(fileName), + function (file) { + _file = file; + }, + function (e) { + if (onError) { + setTimeout(function () { + onError(e); + }, 1); + } + }, + _mode); - if (!(new TypeCoerce(t.MessageServiceTag)).match(messageServiceType)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!(new TypeCoerce(t.MessageServiceArraySuccessCallback)).match(onSuccess)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + if (_file) { + if (_file.isFile && _file.parent.fullPath === _self.fullPath) { + if (!_readOnly && _mode !== "r") { + dbfs.rm(_v2r(fileName), + function () { + setTimeout(function () { + onSuccess(); + }, 1); + }, + function () {}); + return null; + } else { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.SECURITY_ERR)); + }, 1); + } + } + } else { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.IO_ERR)); + }, 1); + } + } + } - switch (messageServiceType) { - case "messaging.sms": - if (_sms_service === null) { - _sms_service = [new MessagingService("Tizen SMS Service 1", TIZEN_MESSAGING_SMS, _security_check), new MessagingService("Tizen SMS Service 2", TIZEN_MESSAGING_SMS, _security_check)]; - } - service = _sms_service; - break; - case "messaging.mms": - if (_mms_service === null) { - _mms_service = [new MessagingService("Tizen MMS Service", TIZEN_MESSAGING_MMS, _security_check)]; - } - service = _mms_service; - break; - case "messaging.email": - if (_email_service === null) { - _email_service = [new MessagingService("Tizen Email Service", TIZEN_MESSAGING_EMAIL, _security_check)]; + return undefined; } - service = _email_service; - break; - default: - throw (new WebAPIException(errorcode.INVALID_VALUES_ERR)); - } - setTimeout(function () { - onSuccess(service); - }, 1); - }; - this.handleSubFeatures = function (subFeatures) { - if (tizen1_utils.isEmptyObject(subFeatures)) { - // all ok - _security_check.send = true; - _security_check.read = true; - _security_check.write = true; - return; - } - if (subFeatures["http://tizen.org/privilege/messaging.send"]) { - _security_check.send = true; - } - if (subFeatures["http://tizen.org/privilege/messaging.read"]) { - _security_check.read = true; - } - if (subFeatures["http://tizen.org/privilege/messaging.write"]) { - _security_check.write = true; + + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile); } }; -}; -module.exports = _self; + _self.__defineGetter__("parent", function () { + var _parts = _self.fullPath.split("/"); -}); -define('ripple/platform/tizen/2.0/msg_utils', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + if (_parent === undefined) { + if (_parts.length === 1) { + // virtual root's parent is null + _parent = null; + } else { + _resolveSync(_parts.splice(0, _parts.length - 1).join("/"), + function (file) { + _parent = file; + }, + function () {}, + _mode); + } + return _parent; + } else { + return _parent; + } + }); + _self.__defineGetter__("readOnly", function () { + return false; + }); -var db = require('ripple/db'), - utils = require('ripple/utils'), - tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - MessageBody = require('ripple/platform/tizen/2.0/MessageBody'), - _TIZEN_MESSAGE_DB_KEY = "tizen_db_messages", - MessageElement = function (_type, _id) { - return { - type: _type, - id: _id, - msg: {}, - conv: {} - }; - }, + _self.__defineGetter__("isFile", function () { + return !_entry.isDirectory; + }); - _conversationCount = function (msg, cid, rst) { - var old_time = new Date(0), t; + _self.__defineGetter__("isDirectory", function () { + return _entry.isDirectory; + }); - utils.forEach(msg.msg, function (o) { - if (o.priv.conversationId === cid && - o.priv.messageStatus !== "DRAFT") { - rst.cnt += 1; - t = new Date(o.priv.timestamp); - if (t > old_time) { - rst.lastid = o.priv.id; - old_time = t; - } - if (o.isRead === false) { - rst.unread++; - } - } - }); - }, - - _updateConversation = function (msg, cid) { - var privConv = {}, lastm, rst = {}; + _self.__defineGetter__("created", function () { + return _entry.createdDate; + }); - rst.cnt = 0; - rst.unread = 0; - rst.lastid = ""; - _conversationCount(msg, cid, rst); - if (rst.cnt === 0) { - if (msg.conv[cid] !== undefined) { - delete msg.conv[cid]; - } - return; - } - lastm = msg.msg[rst.lastid]; + _self.__defineGetter__("modified", function () { + return _entry.lastModifiedDate; + }); - privConv.id = cid; - privConv.type = msg.type; - privConv.timestamp = new Date(lastm.priv.timestamp); - privConv.messageCount = rst.cnt; - privConv.unreadMessages = rst.unread; - privConv.preview = lastm.body.plainBody; - privConv.subject = lastm.subject; - privConv.isRead = lastm.isRead; - privConv.from = lastm.priv.from; - privConv.to = lastm.to.slice(0); - privConv.cc = lastm.cc.slice(0); - privConv.bcc = lastm.bcc.slice(0); - privConv.lastMessageId = rst.lastid; - msg.conv[cid] = privConv; - }; + _self.__defineGetter__("path", function () { + var _parts = _self.fullPath.split("/"); -module.exports = { - conversationCount: _conversationCount, - setMsg: function (m, newm) { - if ((m.to === null) || (m.to === undefined)) { - newm.to = []; + if (_parts.length === 1) { + // virtual root + return _parts.join(""); } else { - if (tizen1_utils.isValidArray(m.to)) { - newm.to = m.to.slice(0); - } else { - return false; - } + return _parts.splice(0, _parts.length - 1).join("/") + "/"; } + }); - if ((m.cc === null) || (m.cc === undefined)) { - newm.cc = []; + _self.__defineGetter__("name", function () { + return _entry.name; + }); + + _self.__defineGetter__("fullPath", function () { + return _r2v(_entry.fullPath); + }); + + _self.__defineGetter__("fileSize", function () { + if (_entry.isDirectory) { + return undefined; } else { - if (tizen1_utils.isValidArray(m.cc)) { - newm.cc = m.cc.slice(0); - } else { - return false; - } + return _entry.data.length; } + }); - if ((m.bcc === null) || (m.bcc === undefined)) { - newm.bcc = []; + _self.__defineGetter__("length", function () { + var _l = 0; + if (_entry.isDirectory) { + utils.forEach(_entry.children, function () { + _l++; + }); + return _l; } else { - if (tizen1_utils.isValidArray(m.bcc)) { - newm.bcc = m.bcc.slice(0); - } else { - return false; - } + return undefined; } + }); - if ((m.body === null) || (m.body === undefined)) { - if (m.htmlBody === null || m.htmlBody === undefined) { - m.htmlBody = ""; + return _self; +}; + +FileStream = function (entry, mode, encoding) { + var _entry = entry, + _data = entry.data, + _mode = mode, + _position = (_mode === "a" ? _data.length : 0), + _self; + + _self = { + close: function () { + var _element; + if (mode === "a" || mode === "w") { + dbfs.write(_entry.fullPath, _data, function () {}, function () {}); } - if (m.plainBody === null || m.plainBody === undefined) { - m.plainBody = ""; + for (_element in _self) { + delete _self[_element]; } - if (typeof m.plainBody !== 'string' || typeof m.htmlBody !== 'string') { - return false; + }, + read: function (charCount) { + var _count = charCount | 0, + _substr = _data.substring(_position, _position + _count); + + if (_position + _count > _data.length) { + _position = _data.length; + } else { + _position += _count; } - m.body = new MessageBody(null, true, m.plainBody, m.htmlBody, []); - } else { - if (typeof m.body.plainBody !== 'string' || typeof m.body.htmlBody !== 'string') { - return false; + + return _substr; + }, + readBytes: function (byteCount) { + var _substr = _self.read(byteCount), + _bytes = [], + _i; + + for (_i = 0; _i < _substr.length; _i++) { + _bytes.push(_substr.charCodeAt(_i)); } - m.body = new MessageBody(null, true, m.body.plainBody, m.body.htmlBody, []); - } - newm.body = utils.copy(m.body); - if (typeof m.isRead === 'boolean') { - newm.isRead = m.isRead; - } else { - newm.isRead = false; - } + return _bytes; + }, + readBase64: function (byteCount) { + var _substr = _self.read(byteCount); - if (typeof m.isHighPriority === 'boolean') { - newm.isHighPriority = m.isHighPriority; - } else { - newm.isHighPriority = false; - } + return window.atob(_substr); + }, + write: function (stringData) { + var _stringData = String(stringData), + _substr = _data.substring(0, _position); - if ((m.subject === null) || (m.subject === undefined)) { - newm.subject = ""; - } else { - newm.subject = String(m.subject); + _data = _substr.concat(_stringData); + _position = _data.length; + }, + writeBytes: function (byteData) { + _self.write(String.fromCharCode.apply(String, byteData)); + }, + writeBase64: function (base64Data) { + _self.write(window.btoa(String(base64Data))); } + }; - if ((m.inResponseTo === null) || (m.inResponseTo === undefined)) { - newm.inResponseTo = null; - } else { - newm.inResponseTo = String(m.inResponseTo); - } + _self.__defineGetter__("eof", function () { + return _position === _data.length; + }); - if ((m.attachments === null) || (m.attachments === undefined)) { - newm.attachments = []; - } else { - newm.attachments = utils.copy(m.attachments); - } - return true; - }, + _self.__defineGetter__("position", function () { + return _position; + }); - loadMsg: function (type, id) { - var i, ret, msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || null; - if (msg === null) { - ret = new MessageElement(type, id); - } else { - for (i = 0; i < msg.length; i++) { - if (msg[i].type === type && msg[i].id === id) { - ret = msg[i]; - break; - } - } - if (ret === undefined) { - ret = new MessageElement(type, id); - } else { - /* after getting Date out of DB, Date will become - a string, so need to recast it back to Date */ - for (i in ret.msg) { - ret.msg[i].priv.timestamp = new Date(ret.msg[i].priv.timestamp); - } - } - } - return ret; - }, + _self.__defineSetter__("position", function (value) { + var _value = value | 0; - delMsg: function (m) { // m is a PrivMessage - var i, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || []; - if (_msg.length === 0) { - return; + if (_value >= 0 && _value <= _data.length) { + _position = _value; } else { - for (i = 0; i < _msg.length; i++) { - if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) { - delete _msg[i].msg[m.priv.id]; - if (m.priv.messageStatus !== "DRAFT") { - _updateConversation(_msg[i], m.priv.conversationId); - } - db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg); - return; - } - } + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } - }, + }); - saveMsg: function (m) { // m is a PrivMessage - var i, new_msg, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || []; - if (_msg.length === 0) { - _msg = new MessageElement(m.priv.type, m.priv.serviceId); - _msg.msg[m.priv.id] = m; - if (m.priv.messageStatus !== "DRAFT") { - _updateConversation(_msg, m.priv.conversationId); - } - db.saveObject(_TIZEN_MESSAGE_DB_KEY, [_msg]); - } else { - for (i = 0; i < _msg.length; i++) { - if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) { - _msg[i].msg[m.priv.id] = m; - if (m.priv.messageStatus !== "DRAFT") { - _updateConversation(_msg[i], m.priv.conversationId); - } - db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg); - break; - } - } - if (i === _msg.length) { - new_msg = new MessageElement(m.priv.type, m.priv.serviceId); - new_msg.msg[m.priv.id] = m; - if (m.priv.messageStatus !== "DRAFT") { - _updateConversation(new_msg, m.priv.conversationId); - } - _msg.push(new_msg); - db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg); - } - } - }, + _self.__defineGetter__("bytesAvailable", function () { + return (_data.length - _position) || -1; + }); - loadConv: function (type, id) { - var i, ret; - ret = this.loadMsg(type, id).conv; - for (i in ret) { - ret[i].timestamp = new Date(ret[i].timestamp); - } - return ret; - } + return _self; }; -}); -define('ripple/platform/tizen/2.0/navigator', function (require, exports, module) { -/* - * Copyright 2011 Research In Motion Limited. - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var _original = window.navigator, - utils = require('ripple/utils'), - devices = require('ripple/devices'), - constants = require('ripple/constants'), - vibration = require('ripple/platform/tizen/2.0/vibration'), - _self = {}; - -(function () { - var key, - nav = window.navigator; +FileFilter = function (name, startModified, endModified, startCreated, endCreated) { + var _self = { + name: name, + startModified: utils.copy(startModified), + endModified: utils.copy(endModified), + endCreated: utils.copy(endCreated) + }; - function _handle(obj, key) { - return typeof obj[key] !== "function" ? obj[key] : function () { - return obj[key].apply(obj, Array.prototype.slice.call(arguments)); - }; - } + return _self; +}; - for (key in nav) { - _self[key] = _handle(nav, key); - } -}()); +FileSystemStorage = function (label, type, state) { + var _self = { + label: label, + type: type, + state: state + }; -_self.__defineGetter__('userAgent', function () { - var currentUserAgent = devices.getCurrentDevice().userAgent; + return _self; +}; - return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ? - _original.userAgent : currentUserAgent; -}); +module.exports = { + maxPathLength: _maxPathLength, + resolve: function (srcLocation, onSuccess, onError, accessMode) { + function _resolve() { + var _mode = accessMode ? String(accessMode) : _defaultMode; -_self.__defineGetter__('vibrate', function () { - return vibration.vibrate; -}); + if (_mode === "r" || _mode === "rw") { + _resolveAsync(onSuccess, onError, String(srcLocation), _mode); + return null; + } else { + if (onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + }, 1); + } + } + return undefined; + } -module.exports = _self; + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve); + }, -}); -define('ripple/platform/tizen/2.0/networkbearerselection', function (require, exports, module) { -/* - * Copyright 2013 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + getStorage: function (label, onSuccess, onError) { + var storage = null, _label = String(label); -var event = require('ripple/event'), - t = require('ripple/platform/tizen/2.0/typedef'), - errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), - _security = { - "http://tizen.org/privilege/networkbearerselection": - ["requestRouteToHost", "releaseRouteToHost"], - all: true - }, - _self; + _storages.some(function (value) { + if (value.label === _label) { + storage = utils.copy(value); + setTimeout(function () { + onSuccess(storage); + }, 1); + return true; + } + }); -_self = { - requestRouteToHost: function (networkType, domainName, successCallback, errorCallback) { - var evNetworkOpened = "NO_" + networkType + "_" + domainName, - evNetworkDisconnected = "ND_" + networkType + "_" + domainName; + if (!storage) { + if(onError) { + setTimeout(function () { + onError(new WebAPIError(errorcode.NOT_FOUND_ERR)); + }, 1); - if (!_security.all && !_security.requestRouteToHost) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } - if (!(new TypeCoerce(t.NetworkType)).match(networkType) || - !(new TypeCoerce(t.DOMString)).match(domainName) || - !(new TypeCoerce(t.NetworkSuccessCallback)).match(successCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!domainName) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + } else { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); } - return; } + }, - event.once(evNetworkOpened, function (isOpened) { - if (!isOpened) - return; + listStorages: function (onSuccess, onError) { + function _listStorages() { + setTimeout(function () { + onSuccess(utils.copy(_storages)); + }, 1); + } - successCallback.onsuccess(); - }); - event.once(evNetworkDisconnected, successCallback.ondisconnected); - event.trigger("NetworkRequest", [networkType, domainName]); + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listStorages", _listStorages); }, - releaseRouteToHost: function (networkType, domainName, successCallback, errorCallback) { - var evNetworkDisconnected = "ND_" + networkType + "_" + domainName; + addStorageStateChangeListener: function(onSuccess, onError) { + function _addStorageStateChangeListener() { + var watchId = (new Date()).getTime() || 0; + _observers[watchId] = function(storage) {//storage is which state is changed + onSuccess(storage); + }; - if (!_security.all && !_security.releaseRouteToHost) { - throw new WebAPIException(errorcode.SECURITY_ERR); + // This event should be triggered from outside + event.on("StateChange", _observers[watchId]); + return Number(watchId); } - if (!(new TypeCoerce(t.NetworkType)).match(networkType) || - !(new TypeCoerce(t.DOMString)).match(domainName) || - !(new TypeCoerce(t.SuccessCallback)).match(successCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { + + return tizen1_utils.validateTypeMismatch(onSuccess, onError, "addStorageStateChangeListener", _addStorageStateChangeListener); + }, + + removeStorageStateChangeListener: function (watchId) { + if (!watchId || typeof watchId !== "number") { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (!domainName) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR)); - } - return; + watchId = String(watchId); + + if (_observers[watchId]) { + event.deleteEventHandler("StateChange", _observers[watchId]); + delete _observers[watchId]; + } else { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); } + }, - event.once(evNetworkDisconnected, successCallback); - event.trigger("NetworkRelease", [networkType, domainName]); + handleSubFeatures: function (subFeatures) { + function setSecurity(_security) { + return function (method) { + _security[method] = true; + }; + } + + for (var subFeature in subFeatures) { + if (_security[subFeature].length === 0) { + _security.all = true; + return; + } + _security.all = false; + utils.forEach(_security[subFeature], setSecurity); + } } }; -module.exports = _self; }); -define('ripple/platform/tizen/2.0/nfc', function (require, exports, module) { +define('ripple/platform/tizen/2.0/geoBackend_local', function (require, exports, module) { /* - * Copyright 2012 Intel Corporation + * Copyright 2012 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85570,651 +87671,617 @@ define('ripple/platform/tizen/2.0/nfc', function (require, exports, module) { */ var db = require('ripple/db'), - event = require('ripple/event'), utils = require('ripple/utils'), + lbs = require('ripple/platform/tizen/2.0/lbs_utils'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecord'), - NDEFMessage = require('ripple/platform/tizen/2.0/NDEFMessage'), - _NFC_TAG = "tizen1.0-nfc-tag", - _NFC_PEER = "tizen1.0-nfc-peer", - _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message", - NFCAdapter, NFCTag, NFCPeer, - tag, - peer, - isPeerConnected = false, - _data = { - INTERVAL : 1000, - listener : { - onCardEmulationChanged : null, - onTagDetected : null, - onPeerDetected : null, - onNDEFReceived : null - }, - pairedNFC : null, - nfcAdapter : {}, - nfcCardEmulation : {}, - nfcTags : [], - nfcTag: {}, - nfcPeer : {}, - isNear : false, // Identify the device is whether near - isDetectTag : false, // Identify NFC tag is detected - connectedState : false - }, - _security = { - "http://tizen.org/privilege/nfc.admin": ["setPowered"], - "http://tizen.org/privilege/nfc.common": ["getDefaultAdapter", "setExclusiveMode", "getCachedMessage", "toByte"], - "http://tizen.org/privilege/nfc.p2p": ["setPeerListener", "unsetPeerListener", "setReceiveNDEFListener", "unsetReceiveNDEFListener", "sendNDEF"], - "http://tizen.org/privilege/nfc.tag": ["setTagListener", "unsetTagListener", "readNDEF", "writeNDEF", "transceive"], - all: true - }, - _self; + PendingObject = require('ripple/platform/tizen/2.0/pendingObject'), + PendingOperation = require('ripple/platform/tizen/2.0/pendingoperation'), + GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult'), + _GEO_OBJECTS = "tizen1.0-geocode-objects", + _get, _save, _geoList_init, GeoEntry, + _checkAddressType, _transAddressStr, + _geocodeByString, _findCoordsByString, _geocodeByAddress, + _reverseGeocodeBySimple, _reverseGeocodeByGeo, _checkCoordsType, + _geoList = [], + _PENDING_TIME = 10; -//validate the type match -function _validateCallbackType(onSuccess) { - if (onSuccess && - typeof onSuccess !== "function" && - typeof onSuccess !== "object") { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } - tizen1_utils.validateArgumentType(onSuccess.onattach, "function", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - tizen1_utils.validateArgumentType(onSuccess.ondetach, "function", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); +function _get() { + var geoList = [], + data = db.retrieveObject(_GEO_OBJECTS); + + utils.forEach(data, function (geo) { + geoList.push(geo); + }); + return geoList; } -_self = function () { - var nfc, _exclusiveMode = false; - function getDefaultAdapter() { - if (!_security.all && !_security.getDefaultAdapter) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - if (arguments.length > 0) { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } +function _save() { + db.saveObject(_GEO_OBJECTS, _geoList); +} - if (!_data.nfcAdapter) { - throw new WebAPIError(errorcode.UNKNOWN_ERR); - } +function _geoList_init() { + var entry; + _geoList = _get(); - return _data.nfcAdapter; + /* Put some default data if database is empty */ + if (_geoList.length === 0) { + entry = new GeoEntry(new lbs.StructuredAddress({ + country : "UK", + region : "London", + county : "Lambeth", + city : "London", + street : "Westminster Bridge Road", + streetNumber : "1", + premises : "Riverside Building", + additionalInformation : "London Eye", + postalCode : "SE1 7PB" + }), + new lbs.GeoCoordinates({ + latitude : 51.510452, + longitude : -0.119820, + altitude : 0, + accuracy : 0, + altitudeAccuracy : 0, + heading : 0, + speed : 0 + })); + _geoList.push(entry); + entry = new GeoEntry(new lbs.StructuredAddress({ + country : "UK", + city : "London", + street : "Baker Street", + streetNumber : "221B", + postalCode : "NW1 6XE" + }), + new lbs.GeoCoordinates({ + latitude : 51.524552, + longitude : -0.158615, + altitude : 0, + accuracy : 0, + altitudeAccuracy : 0, + heading : 0, + speed : 0 + })); + _geoList.push(entry); + entry = new GeoEntry(new lbs.StructuredAddress({ + country : "US", + region : "OR", + city : "Portland", + street : "SE Water Ave", + streetNumber : "1945", + additionalInformation : "OMSI", + }), + new lbs.GeoCoordinates({ + latitude : 45.508490, + longitude : -122.665953, + altitude : 0, + accuracy : 0, + altitudeAccuracy : 0, + heading : 0, + speed : 0 + })); + _geoList.push(entry); + entry = new GeoEntry(new lbs.StructuredAddress({ + country : "US", + region : "OR", + city : "Portland", + street : "NW Pittock Drive", + streetNumber : "3229", + additionalInformation : "Pittock Mansion", + }), + new lbs.GeoCoordinates({ + latitude : 45.531365, + longitude : -122.716255, + altitude : 0, + accuracy : 0, + altitudeAccuracy : 0, + heading : 0, + speed : 0 + })); + _geoList.push(entry); + entry = new GeoEntry(new lbs.StructuredAddress({ + region : "OR", + city : "Hillsboro", + street : "NE 25th St", + streetNumber : "2111", + postalCode : "97124" + }), + new lbs.GeoCoordinates({ + latitude : 45.543479, + longitude : -122.9621601, + altitude : 0, + accuracy : 0, + altitudeAccuracy : 0, + heading : 0, + speed : 0 + })); + _geoList.push(entry); + _save(); } +} - /* API Description: - * If it gets priority and it is in foreground, system doesn't - * send app controls that are usually sent when detecting NFC Tag - * or receiving NDEF Message from the connected NFC peer-to-peer target - * - * Implementation detail: - * due to simulator only support single running instance and doesn't have - * other app controls which be called by design. we just put some system - * exclusive mode info on the 'System Summary' panel - */ - function setExclusiveMode(mode) { - if (!_security.all && !_security.setExclusiveMode) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } +function _pendingOperate(operate) { + var pendingObj, pendingOperation, i, argumentVector = []; - if (typeof mode !== "boolean") { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } - _exclusiveMode = mode; - jQuery("#NFCExclusiveModeValue").text(_exclusiveMode); - } + for (i = 0; i < arguments.length - 1; i++) + argumentVector[i] = arguments[i + 1]; - function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); - } - } + pendingObj = new PendingObject(); - nfc = { - getDefaultAdapter: getDefaultAdapter, - setExclusiveMode: setExclusiveMode, - handleSubFeatures: handleSubFeatures + pendingObj.pendingID = window.setTimeout(function () { + pendingObj.setCancelFlag(false); + operate.apply(this, argumentVector); + }, _PENDING_TIME); + + pendingOperation = new PendingOperation(pendingObj); + + return pendingOperation; +} + +function GeoEntry(addr, coord) { + var _self; + _self = { + address : addr || null, + coordinate : coord || null }; + return _self; +} - nfc.__defineGetter__("NFC_RECORD_TNF_EMPTY", function () { - return 0; - }); +function SortMode() { + var _self; + _self = { + attributeName : "", + order : "ASC" + }; + return _self; +} - nfc.__defineGetter__("NFC_RECORD_TNF_WELL_KNOWN", function () { - return 1; - }); +function _transAddressStr(addr) { + var str = ""; + if (addr.additionalInformation !== null && addr.additionalInformation !== undefined) + str = str + addr.additionalInformation + ", "; + if (addr.premises !== null && addr.premises !== undefined) + str = str + addr.premises + ", "; + if (addr.streetNumber !== null && addr.streetNumber !== undefined) + str = str + addr.streetNumber + " "; + if (addr.street !== null && addr.street !== undefined) + str = str + addr.street + ", "; + if (addr.city !== null && addr.city !== undefined) + str = str + addr.city + ", "; + if (addr.county !== null && addr.county !== undefined) + str = str + addr.county + ", "; + if (addr.region !== null && addr.region !== undefined) + str = str + addr.region + ", "; + if (addr.country !== null && addr.country !== undefined) + str = str + addr.country + ", "; + if (addr.postalCode !== null && addr.postalCode !== undefined) + str = str + addr.postalCode; - nfc.__defineGetter__("NFC_RECORD_TNF_MIME_MEDIA", function () { - return 2; - }); + if (str.lastIndexOf(", ") === str.length - 2) + str = str.slice(0, -2); + return str; +} - nfc.__defineGetter__("NFC_RECORD_TNF_URI", function () { - return 3; - }); +function _concatAddress(addr) { + var str = ""; + if (addr.additionalInformation !== null && addr.additionalInformation !== undefined) + str = str + addr.additionalInformation + " "; + if (addr.premises !== null && addr.premises !== undefined) + str = str + addr.premises + " "; + if (addr.streetNumber !== null && addr.streetNumber !== undefined) + str = str + addr.streetNumber + " "; + if (addr.street !== null && addr.street !== undefined) + str = str + addr.street + " "; + if (addr.city !== null && addr.city !== undefined) + str = str + addr.city + " "; + if (addr.county !== null && addr.county !== undefined) + str = str + addr.county + " "; + if (addr.region !== null && addr.region !== undefined) + str = str + addr.region + " "; + if (addr.country !== null && addr.country !== undefined) + str = str + addr.country + " "; + if (addr.postalCode !== null && addr.postalCode !== undefined) + str = str + addr.postalCode; - nfc.__defineGetter__("NFC_RECORD_TNF_EXTERNAL_RTD", function () { - return 4; - }); + return str; +} - nfc.__defineGetter__("NFC_RECORD_TNF_UNKNOWN", function () { - return 5; - }); +function _findCoordsByString(address) { + var array = [], reg, str, searchAddr, pieces, i; + if (address.length === 0) + return array; - nfc.__defineGetter__("NFC_RECORD_TNF_UNCHANGED", function () { - return 6; + pieces = address.split(","); + searchAddr = ""; + for (i = 0; i < pieces.length; i++) { + searchAddr = searchAddr + pieces[i]; + } + reg = new RegExp(searchAddr, "i"); + + utils.forEach(_geoList, function (item) { + str = _concatAddress(item.address); + if (str.search(reg) !== -1) + array.push(new GeocodeResult(item.coordinate.latitude, item.coordinate.longitude)); }); - return nfc; -}; + return array; +} +function _geocodeByString(address, successCB, errorCB, options) { + var array; + array = _findCoordsByString(address); + successCB(array); +} -NFCAdapter = function () { - var nfcAdapter, - interval, - powered = false, // Identify the device on or off - polling = false, // Identify the device is polled - seType = "NONE"; // Identify card emulation type - - event.trigger("nfc-power-changed", [powered]); - event.on("nfc-power-setting", function (status) { - _updatePowerStatus(status); - }); - event.on("nfc-attach-setting", function (type, isAttached) { - var isDetectTag; - isDetectTag = type === "Tag" ? true : false; - _updateIsNear(isDetectTag, isAttached); - }); - event.on("nfc-tag-send", function (status) { - if (status) { - tag = db.retrieveObject(_NFC_TAG); - if (tag.isSupportedNDEF) { - _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF, tag.ndefSize, null, true, tag.ndefs); - } else { - _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF, tag.ndefSize, null, true, tag.rawData); - } - if (_data.listener.onTagDetected) { - _data.listener.onTagDetected.onattach(_data.nfcTag); - } - } else { - tag = {}; - if (_data.listener.onTagDetected) { - _data.listener.onTagDetected.ondetach(); - } - } - }); - event.on("nfc-peer-send", function (status) { - if (status) { - _data.nfcPeer = new NFCPeer(true); - if (_data.listener.onPeerDetected) { - _data.listener.onPeerDetected.onattach(_data.nfcPeer); - } - isPeerConnected = true; - } else { - if (_data.listener.onPeerDetected) { - _data.listener.onPeerDetected.ondetach(); - } - isPeerConnected = false; - } - }); - event.on("nfc-peer-sending-ndef", function () { - var _records = [], rec, _ndef, i; - if (isPeerConnected) { - peer = db.retrieveObject(_NFC_PEER); - for (i in peer.ndef.records) { - rec = peer.ndef.records[i]; - _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload, rec.id)); - } - _ndef = new NDEFMessage(_records); - if (_data.listener.onNDEFReceived) { - _data.listener.onNDEFReceived(_ndef); - } +function _findCoordsByAddress(addr) { + var array = [], select = false, i; + for (i = 0; i < _geoList.length; i++) { + select = false; + if (addr.country !== null && addr.country !== undefined) { + if (addr.country === _geoList[i].address.country) + select = true; + else + continue; } - }); - // private - function _updatePowerStatus(status) { - if (powered === status) { - return; - } - if (!status) { - _updateIsNear(_data.isDetectTag, false); - _data.listener.onTagDetected = null; - _data.listener.onPeerDetected = null; - _data.listener.onNDEFReceived = null; - _data.listener.onCardEmulationChanged = null; + if (addr.region !== null && addr.region !== undefined) { + if (addr.region === _geoList[i].address.region) + select = true; + else + continue; } - powered = status; - _updatePollingStatus(status); - event.trigger("nfc-power-changed", [powered]); - } - function _updatePollingStatus(status) { - if (!powered) - return; - if (polling === status) { - return; - } - polling = status; - event.trigger("nfc-polling-changed", [polling]); - if (polling) { - interval = setInterval(poll, _data.INTERVAL); - } else { - clearInterval(interval); - } - } - function _updateIsNear(isDetectTag, isAttached) { - _data.isDetectTag = isDetectTag; - _data.isNear = isAttached; - if (!_data.isNear) { - _data.connectedState = false; - event.trigger("nfc-connectedState-changed", [false]); - } - } - function poll() { - if (!_data.isNear) { - return; + if (addr.county !== null && addr.county !== undefined) { + if (addr.county === _geoList[i].address.county) + select = true; + else + continue; } - if (!_data.connectedState) { - _data.connectedState = true; - event.trigger("nfc-connectedState-changed", [true]); + if (addr.city !== null && addr.city !== undefined) { + if (addr.city === _geoList[i].address.city) + select = true; + else + continue; } - } - // public - // Turns NFC adapter on or off. - function setPowered(state, successCallback, errorCallback) { - if (!_security.all && !_security.setPowered) { - throw new WebAPIError(errorcode.SECURITY_ERR); + if (addr.street !== null && addr.street !== undefined) { + if (addr.street === _geoList[i].address.street) + select = true; + else + continue; } - tizen1_utils.validateArgumentType(state, "boolean", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - - tizen1_utils.validateCallbackType(successCallback, errorCallback); - - _updatePowerStatus(state); - if (successCallback) { - successCallback(); - } - } -/* - function setCardEmulation(_seType, successCallback, errorCallback) { - var originalType; - if (!_security.all && !_security.setCardEmulation) { - throw new WebAPIError(errorcode.SECURITY_ERR); + if (addr.streetNumber !== null && addr.streetNumber !== undefined) { + if (addr.streetNumber === _geoList[i].address.streetNumber) + select = true; + else + continue; } - tizen1_utils.validateCallbackType(successCallback, errorCallback); - switch (_seType) { - case "NONE": - case "UICC": - break; - default: - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + if (addr.premises !== null && addr.premises !== undefined) { + if (addr.premises === _geoList[i].address.premises) + select = true; + else + continue; } - if (!powered) { - return; + if (addr.additionalInformation !== null && + addr.additionalInformation !== undefined) { + if (addr.additionalInformation === _geoList[i].address.additionalInformation) + select = true; + else + continue; } - originalType = seType; - seType = _seType; - - if (_data.listener.onCardEmulationChanged && originalType !== seType) { - _data.listener.onCardEmulationChanged(seType); - } - if (successCallback) { - successCallback(); - } - } - function setCardEmulationChangeListener(changeCallback) { - if (!_security.all && !_security.setCardEmulationChangeListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); + if (addr.postalCode !== null && addr.postalCode !== undefined) { + if (addr.postalCode === _geoList[i].address.postalCode) + select = true; + else + continue; } - tizen1_utils.validateArgumentType(changeCallback, "function", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - if (!powered) { - return; + + if (select === true) { + array.push(new GeocodeResult(_geoList[i].coordinate.latitude, _geoList[i].coordinate.longitude)); } - _data.listener.onCardEmulationChanged = changeCallback; } - function unsetCardEmulationChangeListener() { - if (!_security.all && !_security.unsetCardEmulationChangeListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - if (!powered || !_data.listener.onCardEmulationChanged) { - return; - } + return array; +} - _data.listener.onCardEmulationChanged = null; +function _geocodeByAddress(address, successCB, errorCB, options) { + var array; + array = _findCoordsByAddress(address); + successCB(array); +} + +function _checkAddressType(address) { + var str; + if (typeof address === "string") { + str = "string"; + } else if (typeof address === "object") { + str = "StructuredAddress"; + } else { + str = "typeMismatch"; } -*/ + return str; +} - // Registers a callback function to invoke when NFC tag is detected. - function setTagListener(detectCallback, tagFilter) { - if (!_security.all && !_security.setTagListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); +function _checkCoordsType(coord) { + var str; + /* SimpleCoordinates is a subset of GeoCoordinates. + SimpleCoordinates includes latitude, longitude as mandatory fields only. + GeoCoordinates not only includes latitude, longitude as mandatory fields + but also at least includes one more other optional fields */ + if (typeof coord !== "object") { + str = "typeMismatch"; + } else if (typeof coord.latitude === "number" && + typeof coord.longitude === "number") { + str = "simpleCoordinates"; + if (typeof coord.altitude === "number" || + typeof coord.accuracy === "number" || + typeof coord.altitudeAccuracy === "number" || + typeof coord.heading === "number" || + typeof coord.speed === "number") { + str = "geoCoordinates"; } + } else { + str = "typeMismatch"; + } - _validateCallbackType(detectCallback); + return str; +} - if (tagFilter) { - tizen1_utils.validateArgumentType(tagFilter, "array", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } - //TODO: tagFilter support - if (!powered) { - return; +function _findReverseGeocode(coords, options) { + var array = [], _isStructured = false, i; + if (options !== null && options !== undefined) { + if (options.resultType === "STRUCTURED") { + _isStructured = true; } - _data.listener.onTagDetected = detectCallback; } + for (i = 0; i < _geoList.length; i++) { + if (_geoList[i].coordinate.latitude === coords.latitude && + _geoList[i].coordinate.longitude === coords.longitude) { + if (coords.altitude) { + if (_geoList[i].coordinate.altitude !== coords.altitude) + continue; + } + if (coords.accuracy) { + if (_geoList[i].coordinate.accuracy !== coords.accuracy) + continue; + } + if (coords.altitudeAccuracy) { + if (_geoList[i].coordinate.altitudeAccuracy !== coords.altitudeAccuracy) + continue; + } + if (coords.heading) { + if (_geoList[i].coordinate.heading !== coords.heading) + continue; + } + if (coords.speed) { + if (_geoList[i].coordinate.speed !== coords.speed) + continue; + } - // Registers a callback function to be invoked when NFC peer-to-peer target is detected. - function setPeerListener(detectCallback) { - if (!_security.all && !_security.setPeerListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - - _validateCallbackType(detectCallback); - - if (!powered) { - return; + if (_isStructured === true) { + array.push(new lbs.StructuredAddress(_geoList[i].address)); + } else { + array.push(_transAddressStr(_geoList[i].address)); + } } - _data.listener.onPeerDetected = detectCallback; } + return array; +} - // Unregisters the listener for detecting an NFC tag. - function unsetTagListener() { - if (!_security.all && !_security.unsetTagListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } +function _reverseGeocodeByGeo(coordinates, successCB, errorCB, options) { + var array, coord; + coord = new lbs.GeoCoordinates(coordinates); + array = _findReverseGeocode(coord, options); + return successCB(array); +} - if (!powered || !_data.listener.onTagDetected) { - return; - } +function _reverseGeocodeBySimple(coordinates, successCB, errorCB, options) { + var array, coord; + coord = new lbs.GeoCoordinates({ + latitude : coordinates.latitude, + longitude : coordinates.longitude + }); + array = _findReverseGeocode(coord, options); + return successCB(array); +} - _data.listener.onTagDetected = null; - } +module.exports = function (prop) { + var _self = new lbs.LocationServiceProvider(prop); + _geoList_init(); - // Unregisters the listener for detecting an NFC peer-to-peer target. - function unsetPeerListener() { - if (!_security.all && !_security.unsetPeerListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } + _self.geocode = function (address, successCB, errorCB, options) { + function _geocode() { + var ret; - if (!powered || !_data.listener.onPeerDetected) { - return; + ret = _pendingOperate(function () { + /* address: its type is AbstractAddress. + It could be StructuredAddress or String */ + if (_checkAddressType(address) === "string") { + _geocodeByString(address, successCB, errorCB, options); + } else if (_checkAddressType(address) === "StructuredAddress") { + _geocodeByAddress(address, successCB, errorCB, options); + } else { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } + }); } - _data.listener.onPeerDetected = null; - } + tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode); + }; - // Gets NDEF message cached when the tag is detected. - function getCachedMessage() { - if (!_security.all && !_security.getCachedMessage) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } + _self.reverseGeocode = function (coordinates, successCB, errorCB, options) { + function _reverseGeocode() { + var ret; - return _data.pairedNFC || new NDEFMessage([]); - } + ret = _pendingOperate(function () { + /* coordinates: Its type is AbstractCoordinates. + It could be SimpleCoordinates or GeoCoordinates */ + if (_checkCoordsType(coordinates) === "simpleCoordinates") { + _reverseGeocodeBySimple(coordinates, successCB, errorCB, options); + } else if (_checkCoordsType(coordinates) === "geoCoordinates") { + _reverseGeocodeByGeo(coordinates, successCB, errorCB, options); + } else { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } + }); + } - nfcAdapter = { - setPowered : setPowered, - //setCardEmulation: setCardEmulation, - //setCardEmulationChangeListener: setCardEmulationChangeListener, - //unsetCardEmulationChangeListener: unsetCardEmulationChangeListener, - setTagListener : setTagListener, - setPeerListener : setPeerListener, - unsetTagListener : unsetTagListener, - unsetPeerListener : unsetPeerListener, - getCachedMessage : getCachedMessage + tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode); }; - nfcAdapter.__defineGetter__("powered", function () { - return powered; - }); - - nfcAdapter.__defineGetter__("seType", function () { - return seType; - }); - - return nfcAdapter; + return _self; }; -NFCTag = function (type, isSupportedNDEF, ndefSize, properties, isConnected, ndefs) { - var nfcTag, i, j, - _ndefs, - rec, - _records, - _ndefs_index = 0; - - type = type || null; - isSupportedNDEF = isSupportedNDEF || false; - ndefSize = ndefSize || 1; - properties = null; - isConnected = isConnected || false; - _ndefs = []; - for (i in ndefs) { - _records = []; - for (j in ndefs[i].records) { - rec = ndefs[i].records[j]; - _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload, rec.id)); - } - _ndefs.push(new NDEFMessage(_records)); - } +}); +define('ripple/platform/tizen/2.0/geoBackend_nominatim', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - // Reads NDEF data. - function readNDEF(readCallback, errorCallback) { - if (!_security.all && !_security.readNDEF) { - throw new WebAPIError(errorcode.SECURITY_ERR); +var lbs = require('ripple/platform/tizen/2.0/lbs_utils'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), + GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult'); + +function _concatAddrString(addr) { + var ret = "", i, pieces; + if (typeof addr === "string") { + pieces = addr.split(" "); + for (i = 0; i < pieces.length; i++) { + ret = ret + pieces[i] + "+"; } - function _readNDEF() { - if (!isConnected || !isSupportedNDEF) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - } - return; - } - if (_ndefs_index >= ndefSize) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - } else { - _data.pairedNFC = _ndefs[_ndefs_index]; - readCallback(_ndefs[_ndefs_index]); - _ndefs_index++; - } + } else if (typeof addr === "object") { + if (addr.premises !== null && addr.premises !== undefined) { + ret = ret + addr.premises + "+"; } - - tizen1_utils.validateTypeMismatch(readCallback, errorCallback, "nfc:readNDEF", _readNDEF); - } - - // Writes NDEF data. - function writeNDEF(ndefMessage, successCallback, errorCallback) { - if (!_security.all && !_security.writeNDEF) { - throw new WebAPIError(errorcode.SECURITY_ERR); + if (addr.streetNumber !== null && addr.streetNumber !== undefined) { + ret = ret + addr.streetNumber + "+"; } - - tizen1_utils.validateCallbackType(successCallback, errorCallback); - - tizen1_utils.validateArgumentType(ndefMessage, "object", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - - if (!isConnected || !isSupportedNDEF) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - } - return; + if (addr.street !== null && addr.street !== undefined) { + ret = ret + addr.street + "+"; } - db.saveObject(_NFC_OUTPUT_MESSAGE, ndefMessage); - event.trigger("nfc-output-msg", []); - if (successCallback) { - successCallback(); + if (addr.city !== null && addr.city !== undefined) { + ret = ret + addr.city + "+"; } - } - - // Access the raw format card. - function transceive(data, dataCallback, errorCallback) { - if (!_security.all && !_security.transceive) { - throw new WebAPIError(errorcode.SECURITY_ERR); + if (addr.county !== null && addr.county !== undefined) { + ret = ret + addr.county + "+"; } - function _transceive() { - if (!tizen1_utils.isValidArray(data)) - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - - if (!isConnected || isSupportedNDEF) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - } - return; - } - db.saveObject(_NFC_OUTPUT_MESSAGE, data); - event.trigger("nfc-output-msg", []); - dataCallback(ndefs); + if (addr.region !== null && addr.region !== undefined) { + ret = ret + addr.region + "+"; } - - tizen1_utils.validateTypeMismatch(dataCallback, errorCallback, "nfc:transceive", _transceive); - } - - // Formats the detected tag that can store NDEF messages. - /* - function formatNDEF(successCallback, errorCallback, key) { - - tizen1_utils.validateCallbackType(successCallback, errorCallback); - - if (key) { - tizen1_utils.validateArgumentType(key, "array", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + if (addr.postalCode !== null && addr.postalCode !== undefined) { + ret = ret + addr.postalCode + "+"; } - - if (!isConnected || !isSupportedNDEF) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - } - return; + if (addr.country !== null && addr.country !== undefined) { + ret = ret + addr.country + "+"; } - - successCallback(); + } else { + return undefined; } - */ - - nfcTag = { - readNDEF : readNDEF, - writeNDEF : writeNDEF, - transceive : transceive, - //formatNDEF : formatNDEF - }; - - nfcTag.__defineGetter__("type", function () { - return type; - }); - - nfcTag.__defineGetter__("isSupportedNDEF", function () { - return isSupportedNDEF; - }); - - nfcTag.__defineGetter__("ndefSize", function () { - return ndefSize; - }); - - nfcTag.__defineGetter__("properties", function () { - return properties; - }); - - nfcTag.__defineGetter__("isConnected", function () { - return isConnected; - }); - - return nfcTag; -}; + ret = ret.slice(0, -1); + return ret; +} -NFCPeer = function (isConnected) { - var nfcPeer; +module.exports = function (prop) { + var _self = new lbs.LocationServiceProvider(prop); - isConnected = isConnected || false; + _self.geocode = function (address, successCB, errorCB, options) { + function _geocode() { + var i, searchStr, coordinates = [], result; - // Registers a callback function to be invoked when NDEF message is received from NFC peer-to-peer target connected. - function setReceiveNDEFListener(successCallback, errorCallback) { - if (!_security.all && !_security.setReceiveNDEFListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - function _setReceiveNDEFListener() { - if (!isConnected) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - } - return; + searchStr = _concatAddrString(address); + if (searchStr === undefined) { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); } - _data.listener.onNDEFReceived = successCallback; - } - - tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "nfc:setReceiveNDEFListener", _setReceiveNDEFListener); - } - - // Unregisters the listener for receiving NDEFMessage from NFC peer-to-peer target connected. - function unsetReceiveNDEFListener() { - if (!_security.all && !_security.unsetReceiveNDEFListener) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - - _data.listener.onNDEFReceived = null; - } + searchStr = "http://nominatim.openstreetmap.org/search?q=" + searchStr + "&format=json&polygon=1&addressdetails=1"; - // Sends data to NFC peer-to-peer target. - function sendNDEF(ndefMessage, successCallback, errorCallback) { - if (!_security.all && !_security.sendNDEF) { - throw new WebAPIError(errorcode.SECURITY_ERR); + /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */ + $.getJSON(searchStr, function (data) { + for (i = 0; i < data.length; i++) { + result = new GeocodeResult(parseFloat(data[i].lat), parseFloat(data[i].lon)); + coordinates.push(result); + } + successCB(coordinates); + }).error(function () { + if (errorCB) { + setTimeout(function () { + errorCB(new WebAPIError(errorcode.NETWORK_ERR)); + }, 1); + } + }); } - tizen1_utils.validateCallbackType(successCallback, errorCallback); - - tizen1_utils.validateArgumentType(ndefMessage, "object", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode); + }; - if (!isConnected) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); + _self.reverseGeocode = function (coordinates, successCB, errorCB, options) { + function _reverseGeocode() { + var searchStr = ""; + if (typeof coordinates !== "object" || + typeof coordinates.latitude !== "number" || + typeof coordinates.longitude !== "number") { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); } - return; - } + searchStr = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" + + coordinates.latitude + "&lon=" + coordinates.longitude + "&zoom=18&addressdetails=1"; - db.saveObject(_NFC_OUTPUT_MESSAGE, ndefMessage); - event.trigger("nfc-output-msg", []); - if (successCallback) { - successCallback(); + /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */ + $.getJSON(searchStr, function (data) { + var addr; + + if (options && options.resultType === "STRUCTURED") { + addr = new lbs.StructuredAddress({ + country : data.address.country, + region : data.address.state, + county : data.address.county, + city : data.address.city, + street : data.address.road, + streetNumber : data.address.streetNumber, + postalCode : data.address.postcode + }); + } else { + addr = data.display_name; + } + successCB([addr]); + }).error(function () { + if (errorCB) { + setTimeout(function () { + errorCB(new WebAPIError(errorcode.NETWORK_ERR)); + }, 1); + } + }); } - } - nfcPeer = { - setReceiveNDEFListener : setReceiveNDEFListener, - unsetReceiveNDEFListener : unsetReceiveNDEFListener, - sendNDEF : sendNDEF + tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode); }; - nfcPeer.__defineGetter__("isConnected", function () { - return isConnected; - }); - - return nfcPeer; + return _self; }; -function _initialize() { - _data.nfcAdapter = new NFCAdapter(); -} -_initialize(); - -module.exports = _self; - }); -define('ripple/platform/tizen/2.0/notification', function (require, exports, module) { +define('ripple/platform/tizen/2.0/geocoder', function (require, exports, module) { /* * Copyright 2012 Intel Corporation. * @@ -86231,172 +88298,234 @@ define('ripple/platform/tizen/2.0/notification', function (require, exports, mod * limitations under the License. */ -var db = require('ripple/db'), - utils = require('ripple/utils'), - event = require('ripple/event'), - errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - _notificationStack, - _security = { - "http://tizen.org/privilege/notification": ["post", "update", "remove", "removeAll"], - all: true - }, +var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), + ProviderLocal = require('ripple/platform/tizen/2.0/geoBackend_local'), + ProviderNominatim = require('ripple/platform/tizen/2.0/geoBackend_nominatim'), // Nominatim geocode service + _getProviders, + _providers, _self; -function _validateNotification(notification) { - if (typeof notification !== "object") { - return false; - } +function _initialize() { + _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"}) + /* ,new ProviderLocal({name : "Tizen Database", connectivity : "OFFLINE"}) */]; +} - if (typeof notification.id !== "string") { - return false; - } +_initialize(); - if (typeof notification.type !== "string" || notification.type !== "STATUS") { - return false; +_self = { + getDefaultProvider : function () { + return _providers[0]; + }, + getProviders : function () { + return _providers; } +}; - if (typeof notification.title !== "string") { - return false; - } +module.exports = _self; - if (notification.content && typeof notification.content !== "string") { - return false; - } +}); +define('ripple/platform/tizen/2.0/lbs_utils', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - return true; -} +var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), + _self; -_self = function () { - function post(notification) { - if (!_security.all && !_security.post) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - if (!_validateNotification(notification)) { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } +function CoordinateProperties(prop) { + var _self; + _self = { + latitude : prop.latitude || 0, + longitude : prop.longitude || 0, + altitude : prop.altitude || 0, + accuracy : prop.accuracy || 0, + altitudeAccuracy : prop.altitudeAccuracy || 0, + heading : prop.heading || 0, + speed : prop.speed || 0 + }; + return _self; +} - if (notification.statusType === "PROGRESS" && notification.progressValue && - (notification.progressValue < 1 || notification.progressValue > 100)) { - throw new WebAPIError(errorcode.INVALID_VALUES_ERR); - } +function _checkAddressProperties(p, dst) { + if (p.country !== null && p.country !== undefined) + dst.country = String(p.country); + if (p.region !== null && p.region !== undefined) + dst.region = String(p.region); + if (p.county !== null && p.county !== undefined) + dst.county = String(p.county); + if (p.city !== null && p.city !== undefined) + dst.city = String(p.city); + if (p.street !== null && p.street !== undefined) + dst.street = String(p.street); + if (p.streetNumber !== null && p.streetNumber !== undefined) + dst.streetNumber = String(p.streetNumber); + if (p.premises !== null && p.premises !== undefined) + dst.premises = String(p.premises); + if (p.additionalInformation !== null && + p.additionalInformation !== undefined) + dst.additionalInformation = String(p.additionalInformation); + if (p.postalCode !== null && p.postalCode !== undefined) + dst.postalCode = String(p.postalCode); +} - if (!_notificationStack[notification.id]) { - Object.defineProperty(notification, "postedTime", {value: new Date().toString(), writable: false}); - _notificationStack[notification.id] = utils.copy(notification); - db.saveObject("posted-notifications", _notificationStack); - event.trigger("refreshNotificationUI", [], true); - } +function AddressProperties(prop) { + var _self; + _self = { + country : null, + region : null, + county : null, + city : null, + street : null, + streetNumber : null, + premises : null, + additionalInformation : null, + postalCode : null + }; + if (prop) { + if (_checkAddressProperties(prop, _self) === false) + return undefined; } + return _self; +} - function update(notification) { - if (!_security.all && !_security.update) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - if (!_validateNotification(notification)) { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } +_self = { + LocationServiceProvider : function (prop) { + var _self; + _self = { + name : "", + metaData : Object, + attribution : "", + supportedOptions : [], + setOptions : function (options, successCB, errorCB) {}, + connectivity : "" // "ONLINE" "OFFLINE" "HYBRID" + }; - if (notification.statusType === "PROGRESS" && notification.progressValue && - (notification.progressValue < 1 || notification.progressValue > 100)) { - throw new WebAPIError(errorcode.INVALID_VALUES_ERR); - } + if (prop.name !== null && prop.name !== undefined) + _self.name = String(prop.name); + if (prop.metaData !== null && prop.metaData !== undefined) + _self.metaData = prop.metaData; - if (_notificationStack[notification.id]) { - _notificationStack[notification.id] = utils.copy(notification); - db.saveObject("posted-notifications", _notificationStack); - event.trigger("refreshNotificationUI", [], true); - } + if (prop.attribution !== null && prop.attribution !== undefined) + _self.attribution = String(prop.attribution); - } + if (prop.supportedOptions !== null && prop.supportedOptions !== undefined) + _self.supportedOptions = [prop.supportedOptions]; - function remove(id) { - if (!_security.all && !_security.remove) { - throw new WebAPIError(errorcode.SECURITY_ERR); - } - if (typeof id !== "string") { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } + if (prop.setOptions !== null && prop.setOptions !== undefined) + _self.setOptions = prop.setOptions; - if (!_notificationStack[id]) { - throw (new WebAPIError(errorcode.NOT_FOUND_ERR)); - } + if (prop.connectivity !== null && prop.connectivity !== undefined) + _self.connectivity = String(prop.connectivity); - delete _notificationStack[id]; - db.saveObject("posted-notifications", _notificationStack); - event.trigger('refreshNotificationUI', [], true); - } + return _self; + }, - function removeAll() { - if (!_security.all && !_security.removeAll) { - throw new WebAPIError(errorcode.SECURITY_ERR); + GeoCoordinates : function (prop) { + var _self = new CoordinateProperties(prop); + if (tizen1_utils.isEmptyObject(_self)) { + return undefined; } - _notificationStack = {}; - db.saveObject("posted-notifications", _notificationStack); - event.trigger('refreshNotificationUI', [], true); - } - function get(id) { - if (typeof id !== "string") { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } + return _self; + }, - if (!_notificationStack[id]) { - throw (new WebAPIError(errorcode.NOT_FOUND_ERR)); + StructuredAddress : function (prop) { + var _self; + _self = new AddressProperties(prop); + if (tizen1_utils.isEmptyObject(_self)) { + return undefined; } - return utils.copy(_notificationStack[id]); + return _self; } +}; - function getAll() { - var notifications = []; - utils.forEach(_notificationStack, function (item) { - notifications.push(utils.copy(item)); - }); - return notifications; - } +module.exports = _self; - function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; - } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); - } +}); +define('ripple/platform/tizen/2.0/map', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var lbs = require('ripple/platform/tizen/2.0/lbs_utils'), + mapProviders = [], + MapStyle, + MapProvider, + _self; + +function _initialize() { + // EPSG:3857 is a Spherical Mercator projection coordinate system popularized by web services such as Google and later OpenStreetMap + // mapStyles are from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames + var projection = "EPSG:3857", + mapStyle1 = new MapStyle("Mapnik", "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png"), + mapStyle2 = new MapStyle("Cycle", "http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png"); + + mapProviders = [new MapProvider({name: "OpenStreetMap", connectivity: "ONLINE"}, projection, [mapStyle1, mapStyle2])]; +} + +_self = { + getDefaultProvider: function () { + return mapProviders[0]; + }, + getProviders: function () { + return mapProviders; } +}; - var notification = { - post: post, - update: update, - remove: remove, - removeAll: removeAll, - get: get, - getAll: getAll, - handleSubFeatures: handleSubFeatures +MapStyle = function (name, url) { + return { + name: name, + url: url }; - - return notification; }; -function _initilize() { - _notificationStack = db.retrieveObject("posted-notifications") || {}; - event.on("refreshNotificationStack", function () { - _notificationStack = db.retrieveObject("posted-notifications"); +MapProvider = function (prop, projection, mapStyles) { + var mapProvider = new lbs.LocationServiceProvider(prop); + + mapProvider.__defineGetter__("projection", function () { + return projection; }); -} -_initilize(); + mapProvider.__defineGetter__("mapStyles", function () { + return mapStyles; + }); + + return mapProvider; +}; + +_initialize(); module.exports = _self; }); -define('ripple/platform/tizen/2.0/package', function (require, exports, module) { +define('ripple/platform/tizen/2.0/messaging', function (require, exports, module) { /* - * Copyright 2013 Intel Corporation. + * Copyright 2012 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86410,298 +88539,329 @@ define('ripple/platform/tizen/2.0/package', function (require, exports, module) * See the License for the specific language governing permissions and * limitations under the License. */ -var db = require('ripple/db'), - event = require('ripple/event'), - utils = require('ripple/utils'), + +var _self, errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), - PackageInformation = require('ripple/platform/tizen/2.0/PackageInformation'), + MessagingService = require('ripple/platform/tizen/2.0/MessagingService'), t = require('ripple/platform/tizen/2.0/typedef'), - _security = { - "http://tizen.org/privilege/packagemanager.install": ["install", "uninstall"], - "http://tizen.org/privilege/package.info": ["getPackagesInfo", "getPackageInfo", - "setPackageInfoEventListener", "unsetPackageInfoEventListener"], - all: true - }, - DB_PACKAGE_KEY = "tizen-db-package", - _listeners = [], - _data = { - packageList: {}, - installedList: {} - }, - INTERVAL = 1000, // INTERVAL = 1sec - INSTALL_AMOUNT = 3072, // installation speed amount = 3072 (KB/sec) - _self; - -function _get() { - _data = db.retrieveObject(DB_PACKAGE_KEY); - utils.forEach(_data.installedList, function (item) { - item.lastModified = new Date(item.lastModified); - }); -} - -function _save() { - db.saveObject(DB_PACKAGE_KEY, _data); -} - -function _exec(callback, name, id, arg1) { - switch (name) { - case "onprogress": - callback[name](id, arg1); - break; - case "oncomplete": - callback[name](id); - break; - default: - break; - } -} + TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), + TIZEN_MESSAGING_SMS = "messaging.sms", + TIZEN_MESSAGING_MMS = "messaging.mms", + TIZEN_MESSAGING_EMAIL = "messaging.email", + _security_check = {read: false, write: false}, + _sms_service = null, + _mms_service = null, + _email_service = null; _self = function () { - var _package; - //public - function install(path, progressCallback, errorCallback) { - var intervalId, installedSize = 0, packageSize, updateFlag = false, item, info, progress; - if (!_security.all && !_security.install) { - throw new WebAPIException(errorcode.SECURITY_ERR); + this.getMessageServices = function (messageServiceType, onSuccess, onError) { + var service; + + if (!(new TypeCoerce(t.MessageServiceTag)).match(messageServiceType)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (!(new TypeCoerce(t.DOMString)).match(path) || - !(new TypeCoerce(t.PackageProgressCallback)).match(progressCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { + if (!(new TypeCoerce(t.MessageServiceArraySuccessCallback)).match(onSuccess)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (!_data.packageList[path]) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR)); + if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + + switch (messageServiceType) { + case "messaging.sms": + if (_sms_service === null) { + _sms_service = [new MessagingService("Tizen SMS Service 1", TIZEN_MESSAGING_SMS, _security_check), new MessagingService("Tizen SMS Service 2", TIZEN_MESSAGING_SMS, _security_check)]; } - return; + service = _sms_service; + break; + case "messaging.mms": + if (_mms_service === null) { + _mms_service = [new MessagingService("Tizen MMS Service", TIZEN_MESSAGING_MMS, _security_check)]; + } + service = _mms_service; + break; + case "messaging.email": + if (_email_service === null) { + _email_service = [new MessagingService("Tizen Email Service", TIZEN_MESSAGING_EMAIL, _security_check)]; + } + service = _email_service; + break; + default: + throw (new WebAPIException(errorcode.INVALID_VALUES_ERR)); } - item = _data.packageList[path]; - //check package has been installed or not - if (_data.installedList[item.id]) { - updateFlag = true; + setTimeout(function () { + onSuccess(service); + }, 1); + }; + this.handleSubFeatures = function (subFeatures) { + if (subFeatures.hasOwnProperty('http://tizen.org/privilege/messaging.read')) { + _security_check.read = true; } - packageSize = item.totalSize; - intervalId = setInterval(function () { - if (installedSize >= packageSize) { - //install complete - _data.installedList[item.id] = new PackageInformation( - item.id, item.name, item.iconPath, item.version, - item.totalSize, item.dataSize, new Date(), - item.author, item.description, item.appIds - ); - event.trigger("install-apps", [item.appIds]); - _save(); - _exec(progressCallback, "oncomplete", item.id); - clearInterval(intervalId); - item = _data.installedList[item.id]; - utils.forEach(_listeners, function (listener) { - info = new PackageInformation( - item.id, item.name, item.iconPath, item.version, - item.totalSize, item.dataSize, item.lastModified, - item.author, item.description, item.appIds); - if (!updateFlag) { - listener.oninstalled(info); - } else { - listener.onupdated(info); - } - }); - event.trigger("installedList-updated"); - } else { - installedSize += INSTALL_AMOUNT; - if (installedSize > packageSize) { - progress = 100; - } else { - progress = Math.floor(installedSize * 100 / packageSize); + if (subFeatures.hasOwnProperty('http://tizen.org/privilege/messaging.write')) { + _security_check.write = true; + } + }; +}; + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/msg_utils', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var db = require('ripple/db'), + utils = require('ripple/utils'), + tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), + MessageBody = require('ripple/platform/tizen/2.0/MessageBody'), + _TIZEN_MESSAGE_DB_KEY = "tizen_db_messages", + MessageElement = function (_type, _id) { + return { + type: _type, + id: _id, + msg: {}, + conv: {} + }; + }, + + _conversationCount = function (msg, cid, rst) { + var old_time = new Date(0), t; + + utils.forEach(msg.msg, function (o) { + if (o.priv.conversationId === cid && + o.priv.messageStatus !== "DRAFT") { + rst.cnt += 1; + t = new Date(o.priv.timestamp); + if (t > old_time) { + rst.lastid = o.priv.id; + old_time = t; + } + if (o.isRead === false) { + rst.unread++; } - _exec(progressCallback, "onprogress", item.id, progress); } + }); + }, - }, INTERVAL); - } + _updateConversation = function (msg, cid) { + var privConv = {}, lastm, rst = {}; - function uninstall(id, progressCallback, errorCallback) { - var intervalId, removedSize = 0, packageSize, item, progress; - if (!_security.all && !_security.uninstall) { - throw new WebAPIException(errorcode.SECURITY_ERR); - } - if (!(new TypeCoerce(t.PackageId)).match(id) || - !(new TypeCoerce(t.PackageProgressCallback)).match(progressCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (!_data.installedList[id]) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR)); + rst.cnt = 0; + rst.unread = 0; + rst.lastid = ""; + _conversationCount(msg, cid, rst); + if (rst.cnt === 0) { + if (msg.conv[cid] !== undefined) { + delete msg.conv[cid]; } return; } - item = _data.installedList[id]; - packageSize = item.totalSize; - intervalId = setInterval(function () { - if (removedSize >= packageSize) { - //remove complete - utils.forEach(_data.packageList, function (_package) { - if (_package.id === id) { - event.trigger("remove-apps", [_package.appIds]); - } - }); - delete _data.installedList[item.id]; - _save(); - _exec(progressCallback, "oncomplete", item.id); - clearInterval(intervalId); - item = _data.installedList[item.id]; - utils.forEach(_listeners, function (listener) { - listener.onuninstalled(id); - }); - event.trigger("installedList-updated"); + lastm = msg.msg[rst.lastid]; + + privConv.id = cid; + privConv.type = msg.type; + privConv.timestamp = new Date(lastm.priv.timestamp); + privConv.messageCount = rst.cnt; + privConv.unreadMessages = rst.unread; + privConv.preview = lastm.body.plainBody; + privConv.subject = lastm.subject; + privConv.isRead = lastm.isRead; + privConv.from = lastm.priv.from; + privConv.to = lastm.to.slice(0); + privConv.cc = lastm.cc.slice(0); + privConv.bcc = lastm.bcc.slice(0); + privConv.lastMessageId = rst.lastid; + msg.conv[cid] = privConv; + }; + +module.exports = { + conversationCount: _conversationCount, + setMsg: function (m, newm) { + if ((m.to === null) || (m.to === undefined)) { + newm.to = []; + } else { + if (tizen1_utils.isValidArray(m.to)) { + newm.to = m.to.slice(0); } else { - removedSize += INSTALL_AMOUNT * 10; - if (removedSize > packageSize) { - progress = 100; - } else { - progress = Math.floor(removedSize * 100 / packageSize); - } - _exec(progressCallback, "onprogress", item.id, progress); + return false; } - }, INTERVAL); - } + } - function getPackagesInfo(successCallback, errorCallback) { - var packageArray = []; - if (!_security.all && !_security.getPackagesInfo) { - throw new WebAPIException(errorcode.SECURITY_ERR); + if ((m.cc === null) || (m.cc === undefined)) { + newm.cc = []; + } else { + if (tizen1_utils.isValidArray(m.cc)) { + newm.cc = m.cc.slice(0); + } else { + return false; + } } - if (!(new TypeCoerce(t.PackageInformationArraySuccessCallback)).match(successCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + + if ((m.bcc === null) || (m.bcc === undefined)) { + newm.bcc = []; + } else { + if (tizen1_utils.isValidArray(m.bcc)) { + newm.bcc = m.bcc.slice(0); + } else { + return false; + } } - utils.forEach(_data.installedList, function (item) { - var i; - i = new PackageInformation( - item.id, item.name, item.iconPath, item.version, - item.totalSize, item.dataSize, item.lastModified, - item.author, item.description, item.appIds - ); - packageArray.push(i); - }); - successCallback(packageArray); - } - function getPackageInfo(id) { - var p, item; - if (!_security.all && !_security.getPackageInfo) { - throw new WebAPIException(errorcode.SECURITY_ERR); + if ((m.body === null) || (m.body === undefined)) { + if (m.htmlBody === null || m.htmlBody === undefined) { + m.htmlBody = ""; + } + if (m.plainBody === null || m.plainBody === undefined) { + m.plainBody = ""; + } + if (typeof m.plainBody !== 'string' || typeof m.htmlBody !== 'string') { + return false; + } + m.body = new MessageBody(null, true, m.plainBody, m.htmlBody, []); + } else { + if (typeof m.body.plainBody !== 'string' || typeof m.body.htmlBody !== 'string') { + return false; + } + m.body = new MessageBody(null, true, m.body.plainBody, m.body.htmlBody, []); } - if (!(new TypeCoerce(t.PackageId)).match(id)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + newm.body = utils.copy(m.body); + + if (typeof m.isRead === 'boolean') { + newm.isRead = m.isRead; + } else { + newm.isRead = false; } - if (!_data.installedList[id]) { - throw new WebAPIException(errorcode.NOT_FOUND_ERR); + + if (typeof m.isHighPriority === 'boolean') { + newm.isHighPriority = m.isHighPriority; + } else { + newm.isHighPriority = false; } - item = _data.installedList[id]; - p = new PackageInformation( - item.id, item.name, item.iconPath, item.version, - item.totalSize, item.dataSize, item.lastModified, - item.author, item.description, item.appIds - ); - return p; - } - function setPackageInfoEventListener(eventCallback) { - if (!_security.all && !_security.setPackageInfoEventListener) { - throw new WebAPIException(errorcode.SECURITY_ERR); + if ((m.subject === null) || (m.subject === undefined)) { + newm.subject = ""; + } else { + newm.subject = String(m.subject); } - if (!(new TypeCoerce(t.PackageInfomationEventCallback)).match(eventCallback)) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + + if ((m.inResponseTo === null) || (m.inResponseTo === undefined)) { + newm.inResponseTo = null; + } else { + newm.inResponseTo = String(m.inResponseTo); } - _listeners.push(eventCallback); - } - function unsetPackageInfoEventListener() { - if (!_security.all && !_security.unsetPackageInfoEventListener) { - throw new WebAPIException(errorcode.SECURITY_ERR); + if ((m.attachments === null) || (m.attachments === undefined)) { + newm.attachments = []; + } else { + newm.attachments = utils.copy(m.attachments); } - _listeners = []; - } + return true; + }, - function handleSubFeatures(subFeatures) { - var i, subFeature; - for (subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; + loadMsg: function (type, id) { + var i, ret, msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || null; + if (msg === null) { + ret = new MessageElement(type, id); + } else { + for (i = 0; i < msg.length; i++) { + if (msg[i].type === type && msg[i].id === id) { + ret = msg[i]; + break; + } } - _security.all = false; - for (i in _security[subFeature]) { - _security[_security[subFeature][i]] = true; + if (ret === undefined) { + ret = new MessageElement(type, id); + } else { + /* after getting Date out of DB, Date will become + a string, so need to recast it back to Date */ + for (i in ret.msg) { + ret.msg[i].priv.timestamp = new Date(ret.msg[i].priv.timestamp); + } } } - } + return ret; + }, - function updatePackage(path, updateFlag) { - var item, p, info; - if (!_data.packageList[path]) { + delMsg: function (m) { // m is a PrivMessage + var i, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || []; + if (_msg.length === 0) { return; - } - _get(); - p = _data.packageList[path]; - item = _data.installedList[p.id]; - utils.forEach(_listeners, function (listener) { - info = new PackageInformation( - item.id, item.name, item.iconPath, item.version, - item.totalSize, item.dataSize, item.lastModified, - item.author, item.description, item.appIds); - if (!updateFlag) { - listener.oninstalled(info); - } else { - listener.onupdated(info); + } else { + for (i = 0; i < _msg.length; i++) { + if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) { + delete _msg[i].msg[m.priv.id]; + if (m.priv.messageStatus !== "DRAFT") { + _updateConversation(_msg[i], m.priv.conversationId); + } + db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg); + return; + } } - }); - } - - event.on("install-packge", function (path) { - updatePackage(path, false); - }); - event.on("update-package", function (path) { - updatePackage(path, true); - }); - - event.on("uninstall-package", function (id) { - _get(); - utils.forEach(_listeners, function (listener) { - listener.onuninstalled(id); - }); - }); + } + }, - _package = { - install: install, - uninstall: uninstall, - getPackagesInfo: getPackagesInfo, - getPackageInfo: getPackageInfo, - setPackageInfoEventListener: setPackageInfoEventListener, - unsetPackageInfoEventListener: unsetPackageInfoEventListener, - handleSubFeatures: handleSubFeatures - }; + saveMsg: function (m) { // m is a PrivMessage + var i, new_msg, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || []; + if (_msg.length === 0) { + _msg = new MessageElement(m.priv.type, m.priv.serviceId); + _msg.msg[m.priv.id] = m; + if (m.priv.messageStatus !== "DRAFT") { + _updateConversation(_msg, m.priv.conversationId); + } + db.saveObject(_TIZEN_MESSAGE_DB_KEY, [_msg]); + } else { + for (i = 0; i < _msg.length; i++) { + if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) { + _msg[i].msg[m.priv.id] = m; + if (m.priv.messageStatus !== "DRAFT") { + _updateConversation(_msg[i], m.priv.conversationId); + } + db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg); + break; + } + } + if (i === _msg.length) { + new_msg = new MessageElement(m.priv.type, m.priv.serviceId); + new_msg.msg[m.priv.id] = m; + if (m.priv.messageStatus !== "DRAFT") { + _updateConversation(new_msg, m.priv.conversationId); + } + _msg.push(new_msg); + db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg); + } + } + }, - return _package; + loadConv: function (type, id) { + var i, ret; + ret = this.loadMsg(type, id).conv; + for (i in ret) { + ret[i].timestamp = new Date(ret[i].timestamp); + } + return ret; + } }; -function _initialize() { - _get(); -} - -_initialize(); - -module.exports = _self; - - }); -define('ripple/platform/tizen/2.0/pendingObject', function (require, exports, module) { +define('ripple/platform/tizen/2.0/navigator', function (require, exports, module) { /* - * Copyright 2011 Intel Corporation. + * Copyright 2011 Research In Motion Limited. + * Copyright 2012 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86715,64 +88875,45 @@ define('ripple/platform/tizen/2.0/pendingObject', function (require, exports, mo * See the License for the specific language governing permissions and * limitations under the License. */ +var _original = window.navigator, + utils = require('ripple/utils'), + devices = require('ripple/devices'), + constants = require('ripple/constants'), + vibration = require('ripple/platform/tizen/2.0/vibration'), + _self = {}; -module.exports = function (pendingObj) { - var cancelFlag = true; - this.setCancelFlag = function (flag) { - cancelFlag = flag; - }; - this.getCancelFlag = function () { - return cancelFlag; - }; - this.userCancel = null; - this.pendingID = null; -}; +(function () { + var key, + nav = window.navigator; + + function _handle(obj, key) { + return typeof obj[key] !== "function" ? obj[key] : function () { + return obj[key].apply(obj, Array.prototype.slice.call(arguments)); + }; + } + + for (key in nav) { + _self[key] = _handle(nav, key); + } +}()); + +_self.__defineGetter__('userAgent', function () { + var currentUserAgent = devices.getCurrentDevice().userAgent; + return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ? + _original.userAgent : currentUserAgent; }); -define('ripple/platform/tizen/2.0/pendingoperation', function (require, exports, module) { -/* - * Copyright 2011 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -module.exports = function (pendingObj) { - var pending = true; - this.cancel = function () { - if (pending === true) { - if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) { - pending = false; - // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout - clearTimeout(pendingObj.pendingID); - return false; - } - if (typeof (pendingObj.userCancel) === "function") { - pendingObj.userCancel(); - } - clearTimeout(pendingObj.pendingID); - pending = false; - return true; - } else { - return false; - } - }; -}; +_self.__defineGetter__('vibrate', function () { + return vibration.vibrate; +}); +module.exports = _self; }); -define('ripple/platform/tizen/2.0/poi', function (require, exports, module) { +define('ripple/platform/tizen/2.0/networkbearerselection', function (require, exports, module) { /* - * Copyright 2012 Intel Corporation. + * Copyright 2013 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86787,55 +88928,99 @@ define('ripple/platform/tizen/2.0/poi', function (require, exports, module) { * limitations under the License. */ -var OpenMapQuestProvider = require('ripple/platform/tizen/2.0/poiBackend_openmapquest'), // opne.MapQuest.xapi service - _providers, +var event = require('ripple/event'), + t = require('ripple/platform/tizen/2.0/typecast'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), _security = { - "http://tizen.org/api/poi": [], - "http://tizen.org/api/poi.read": ["find"], - "http://tizen.org/api/poi.write": ["add", "remove", "update"], - all: true + "http://tizen.org/privilege/networkbearerselection": + ["requestRouteToHost", "releaseRouteToHost"] }, _self; -function _initialize() { - _providers = [new OpenMapQuestProvider({name : "MapQuest", connectivity : "ONLINE", metaData : _security})]; -} - _self = function () { - var poi; + var networkBearerSelection; - poi = { - getDefaultProvider : function () { - return _providers[0]; - }, - getProviders : function () { - return _providers; - }, - handleSubFeatures: function (subFeatures) { - var i, subFeature; - for (subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - break; - } - _security.all = false; - for (i = 0; i < _security[subFeature].length; i++) { - _security[_security[subFeature][i]] = true; - } + function requestRouteToHost(networkType, domainName, successCallback, errorCallback) { + var evNetworkOpened = "NO_" + networkType + "_" + domainName, + evNetworkDisconnected = "ND_" + networkType + "_" + domainName; + + if (!_security.requestRouteToHost) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + networkType = t.NetworkType(networkType); + domainName = t.DOMString(domainName); + successCallback = t.NetworkSuccessCallback(successCallback); + errorCallback = t.ErrorCallback(errorCallback, "?"); + + if (!domainName) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + } + return; + } + + event.once(evNetworkOpened, function (isOpened) { + if (!isOpened) + return; + + successCallback.onsuccess(); + }); + event.once(evNetworkDisconnected, successCallback.ondisconnected); + event.trigger("NetworkRequest", [networkType, domainName]); + } + + function releaseRouteToHost(networkType, domainName, successCallback, errorCallback) { + var evNetworkDisconnected = "ND_" + networkType + "_" + domainName; + + if (!_security.releaseRouteToHost) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + + networkType = t.NetworkType(networkType); + domainName = t.DOMString(domainName); + successCallback = t.SuccessCallback(successCallback); + errorCallback = t.ErrorCallback(errorCallback, "?"); + + if (!domainName) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR)); + } + return; + } + + event.once(evNetworkDisconnected, successCallback); + event.trigger("NetworkRelease", [networkType, domainName]); + } + + function handleSubFeatures(subFeatures) { + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - _initialize(); } + } + + networkBearerSelection = { + requestRouteToHost: requestRouteToHost, + releaseRouteToHost: releaseRouteToHost, + handleSubFeatures: handleSubFeatures }; - return poi; + return networkBearerSelection; }; module.exports = _self; }); -define('ripple/platform/tizen/2.0/poiBackend_openmapquest', function (require, exports, module) { +define('ripple/platform/tizen/2.0/nfc', function (require, exports, module) { /* - * Copyright 2012 Intel Corporation. + * Copyright 2012 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86850,540 +89035,649 @@ define('ripple/platform/tizen/2.0/poiBackend_openmapquest', function (require, e * limitations under the License. */ -var lbs = require('ripple/platform/tizen/2.0/lbs_utils'), +var db = require('ripple/db'), + event = require('ripple/event'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - POIGeometry = require('ripple/platform/tizen/2.0/POIGeometry'), - SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), - _security; + NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecord'), + NDEFMessage = require('ripple/platform/tizen/2.0/NDEFMessage'), + _NFC_TAG = "tizen1.0-nfc-tag", + _NFC_PEER = "tizen1.0-nfc-peer", + _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message", + NFCAdapter, NFCTag, NFCPeer, + tag, + peer, + isPeerConnected = false, + _data = { + INTERVAL : 1000, + listener : { + onCardEmulationChanged : null, + onTagDetected : null, + onPeerDetected : null, + onNDEFReceived : null + }, + pairedNFC : null, + nfcAdapter : {}, + nfcCardEmulation : {}, + nfcTags : [], + nfcTag: {}, + nfcPeer : {}, + isNear : false, // Identify the device is whether near + isDetectTag : false, // Identify NFC tag is detected + connectedState : false + }, + _security = { + "http://tizen.org/privilege/nfc.admin": ["setPowered"], + "http://tizen.org/privilege/nfc.common": ["getDefaultAdapter", "setExclusiveMode", "getCachedMessage"], + "http://tizen.org/privilege/nfc.p2p": ["setPeerListener", "unsetPeerListener", "setReceiveNDEFListener", "unsetReceiveNDEFListener", "sendNDEF"], + "http://tizen.org/privilege/nfc.tag": ["setTagListener", "unsetTagListener", "readNDEF", "writeNDEF", "transceive"] + }, + _self; -function POIPublic(prop) { - /* This is created for public use */ - var _self, i, copy, attr, _id = null, _providerName = null; - if (prop.id) { - _id = prop.id; - } - if (prop.providerName) { - _providerName = prop.providerName; +//validate the type match +function _validateCallbackType(onSuccess) { + if (onSuccess && + typeof onSuccess !== "function" && + typeof onSuccess !== "object") { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); } - _self = { - name : null, - categories : [], - address : null, - phoneNumbers : [], - geometry : null, - urls : [], - rating : null, - tags : null, - toGeoJSON : function () { - throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); - } - }; - - _self.__defineGetter__("id", function () { - return _id; - }); - - _self.__defineGetter__("providerName", function () { - return _providerName; - }); + tizen1_utils.validateArgumentType(onSuccess.onattach, "function", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + tizen1_utils.validateArgumentType(onSuccess.ondetach, "function", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); +} - if (prop) { - if (prop.name) { - _self.name = String(prop.name); - } - if (tizen1_utils.isValidArray(prop.categories)) { - _self.categories = []; - for (i in prop.categories) { - _self.categories.push(String(prop.categories[i])); - } - } - if (prop.address) { - if (typeof prop.address === "string") { - _self.address = String(prop.address); - } else if (Object.prototype.toString.call(prop.address) === "[object Object]") { - copy = prop.address.constructor(); - for (attr in prop.address) { - if (prop.address.hasOwnProperty(attr)) { - copy[attr] = prop.address[attr]; - } - } - _self.address = copy; - } +_self = function () { + var nfc, _exclusiveMode = false; + function getDefaultAdapter() { + if (!_security.getDefaultAdapter) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - if (tizen1_utils.isValidArray(prop.phoneNumbers)) { - _self.phoneNumbers = []; - for (i in prop.phoneNumbers) { - _self.phoneNumbers.push(String(prop.phoneNumbers[i])); - } + if (arguments.length > 0) { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); } - if (prop.geometry) { - _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt); + + if (!_data.nfcAdapter) { + throw new WebAPIError(errorcode.UNKNOWN_ERR); } - if (tizen1_utils.isValidArray(prop.urls)) { - _self.urls = []; - for (i in prop.urls) { - _self.urls.push(String(prop.urls[i])); - } + + return _data.nfcAdapter; + } + + /* API Description: + * If it gets priority and it is in foreground, system doesn't + * send app controls that are usually sent when detecting NFC Tag + * or receiving NDEF Message from the connected NFC peer-to-peer target + * + * Implementation detail: + * due to simulator only support single running instance and doesn't have + * other app controls which be called by design. we just put some system + * exclusive mode info on the 'System Summary' panel + */ + function setExclusiveMode(mode) { + if (!_security.setExclusiveMode) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - if (typeof prop.rating === "number") { - _self.rating = prop.rating; + + if (typeof mode !== "boolean") { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); } - if (Object.prototype.toString.call(prop.tags) === "[object Object]") { - copy = prop.tags.constructor(); - for (attr in prop.tags) { - if (prop.tags.hasOwnProperty(attr)) { - copy[attr] = prop.tags[attr]; - } + _exclusiveMode = mode; + jQuery("#NFCExclusiveModeValue").text(_exclusiveMode); + } + + function handleSubFeatures(subFeatures) { + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - _self.tags = copy; } } - return _self; -} + nfc = { + getDefaultAdapter: getDefaultAdapter, + setExclusiveMode: setExclusiveMode, + handleSubFeatures: handleSubFeatures + }; -module.exports = function (prop) { + nfc.__defineGetter__("NFC_RECORD_TNF_EMPTY", function () { + return 0; + }); - var _self = new lbs.LocationServiceProvider(prop); + nfc.__defineGetter__("NFC_RECORD_TNF_WELL_KNOWN", function () { + return 1; + }); - if (prop.metaData) { - _security = prop.metaData; - } + nfc.__defineGetter__("NFC_RECORD_TNF_MIME_MEDIA", function () { + return 2; + }); - _self.__defineGetter__("supportedFilterTypes", function () { - return []; + nfc.__defineGetter__("NFC_RECORD_TNF_URI", function () { + return 3; }); - _self.__defineGetter__("supportedPOIFilterAttributes", function () { - return []; + nfc.__defineGetter__("NFC_RECORD_TNF_EXTERNAL_RTD", function () { + return 4; }); - _self.__defineGetter__("supportedCategories", function () { - /* reference: http://wiki.openstreetmap.org/wiki/Map_Features#Amenity */ - return ["bar", "bbq", "biergarten", "cafe", "drinking_water", "fast_food", "food_court", "ice_cream", - "pub", "restaurant", "college", "kindergarten", "library", "school", "university", - "bicycle_parking", "bicycle_rental", "bus_station", "car_rental", "car_sharing", "car_wash", - "ev_charging", "ferry_terminal", "fuel", "grit_bin", "parking", "parking_entrance", - "parking_space", "taxi", "atm", "bank", "bureau_de_change", "baby_hatch", "clinic", - "dentist", "doctors", "hospital", "nursing_home", "pharmacy", "social_facility", "veterinary", - "arts_centre", "cinema", "community_centre", "fountain", "nightclub", "social_centre", - "stripclub", "studio", "swingerclub", "theatre", "bench", "brothel", "clock", "courthouse", - "crematorium", "embassy", "fire_station", "grave_yard", "hunting_stand", "marketplace", - "place_of_worship", "police", "post_box", "post_office", "prison", "public_building", - "recycling", "sauna", "shelter", "shower", "telephone", "toilets", "townhall", "vending_machine", - "waste_basket", "waste_disposal", "watering_place"]; + nfc.__defineGetter__("NFC_RECORD_TNF_UNKNOWN", function () { + return 5; }); - _self.__defineGetter__("capabilities", function () { - /* The set is empty, indicating that this provider supports only 'find' operations */ - return []; + nfc.__defineGetter__("NFC_RECORD_TNF_UNCHANGED", function () { + return 6; }); - _self.find = function (point, successCallback, errorCallback, options) { - /* This provider only supports searching by "GeoRectBounds" due to MapQuest XAPI limitation */ + return nfc; +}; - function _find() { - var searchStr, pois = [], isTypeOK = false, - id, providerName, name, categories = [], geometry; - if (Object.prototype.toString.call(point) === "[object Object]") { - if (point.southWest && point.northEast) { - if (typeof point.southWest.latitude === "number" && - typeof point.southWest.longitude === "number" && - typeof point.northEast.latitude === "number" && - typeof point.northEast.longitude === "number") { - isTypeOK = true; - } - } +NFCAdapter = function () { + var nfcAdapter, + interval, + powered = false, // Identify the device on or off + polling = false, // Identify the device is polled + seType = "NONE"; // Identify card emulation type + + event.trigger("nfc-power-changed", [powered]); + event.on("nfc-power-setting", function (status) { + _updatePowerStatus(status); + }); + event.on("nfc-attach-setting", function (type, isAttached) { + var isDetectTag; + isDetectTag = type === "Tag" ? true : false; + _updateIsNear(isDetectTag, isAttached); + }); + event.on("nfc-tag-send", function (status) { + if (status) { + tag = db.retrieveObject(_NFC_TAG); + if (tag.isSupportedNDEF) { + _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF, tag.ndefSize, null, true, tag.ndefs); + } else { + _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF, tag.ndefSize, null, true, tag.rawData); } - - if (!isTypeOK) { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + if (_data.listener.onTagDetected) { + _data.listener.onTagDetected.onattach(_data.nfcTag); } - - searchStr = "http://open.mapquestapi.com/xapi/api/0.6/node"; - if (options && tizen1_utils.isValidArray(options.categories) && - options.categories.length > 0 && typeof options.categories[0] === "string") { - /* xapi support single amenity only */ - searchStr += "[amenity=" + options.categories[0] + "]"; + } else { + tag = {}; + if (_data.listener.onTagDetected) { + _data.listener.onTagDetected.ondetach(); } - searchStr += "[bbox=" + point.southWest.longitude + "," + point.southWest.latitude + "," + - point.northEast.longitude + "," + point.northEast.latitude + "]"; + } + }); + event.on("nfc-peer-send", function (status) { + if (status) { + _data.nfcPeer = new NFCPeer(true); + if (_data.listener.onPeerDetected) { + _data.listener.onPeerDetected.onattach(_data.nfcPeer); + } + isPeerConnected = true; + } else { + if (_data.listener.onPeerDetected) { + _data.listener.onPeerDetected.ondetach(); + } + isPeerConnected = false; + } + }); + event.on("nfc-peer-sending-ndef", function () { + var _records = [], rec, _ndef, i; + if (isPeerConnected) { + peer = db.retrieveObject(_NFC_PEER); + for (i in peer.ndef.records) { + rec = peer.ndef.records[i]; + _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload, rec.id)); + } + _ndef = new NDEFMessage(_records); + if (_data.listener.onNDEFReceived) { + _data.listener.onNDEFReceived(_ndef); + } + } + }); - /* use Open MapQuest online xapi service. (http://open.mapquestapi.com/xapi/) */ - $.ajax({ - type: "GET", - url: searchStr, - dataType: "xml", - timeout: 15000, /* 15 secs timeout */ - success: function (xml) { - providerName = $(xml).find("osm").attr("generator"); - $(xml).find("node").each(function () { - var $item = $(this); - categories = []; - id = $item.attr("id"); - geometry = new POIGeometry(new SimpleCoordinates($item.attr("lat"), $item.attr("lon"))); - $item.find("tag").each(function () { - if ($(this).attr("k") === "name") { - name = $(this).attr("v"); - } else if ($(this).attr("k") === "amenity") { - categories.push($(this).attr("v")); - } - }); - pois.push(new POIPublic({id: id, providerName: providerName, name: name, - categories: categories, geometry: geometry})); - }); - successCallback(pois); - }, - error: function (obj, msg) { - if (errorCallback) { - if (msg === "timeout") { - setTimeout(function () { - errorCallback(new WebAPIError(errorcode.TIMEOUT_ERR)); - }, 1); - } else { - setTimeout(function () { - errorCallback(new WebAPIError(errorcode.NETWORK_ERR)); - }, 1); - } - } - } - }); + // private + function _updatePowerStatus(status) { + if (powered === status) { + return; + } + if (!status) { + _updateIsNear(_data.isDetectTag, false); + _data.listener.onTagDetected = null; + _data.listener.onPeerDetected = null; + _data.listener.onNDEFReceived = null; + _data.listener.onCardEmulationChanged = null; } + powered = status; + _updatePollingStatus(status); - if (!_security.all && !_security.find) { - throw new WebAPIError(errorcode.SECURITY_ERR); + event.trigger("nfc-power-changed", [powered]); + } + function _updatePollingStatus(status) { + if (!powered) + return; + if (polling === status) { + return; + } + polling = status; + event.trigger("nfc-polling-changed", [polling]); + if (polling) { + interval = setInterval(poll, _data.INTERVAL); + } else { + clearInterval(interval); + } + } + function _updateIsNear(isDetectTag, isAttached) { + _data.isDetectTag = isDetectTag; + _data.isNear = isAttached; + if (!_data.isNear) { + _data.connectedState = false; + event.trigger("nfc-connectedState-changed", [false]); + } + } + function poll() { + if (!_data.isNear) { + return; } + if (!_data.connectedState) { + _data.connectedState = true; + event.trigger("nfc-connectedState-changed", [true]); - tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); - }; + } + } - _self.update = function (poi, successCallback, errorCallback) { - if (!_security.all && !_security.update) { + // public + // Turns NFC adapter on or off. + function setPowered(state, successCallback, errorCallback) { + if (!_security.setPowered) { throw new WebAPIError(errorcode.SECURITY_ERR); } - throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); - }; + tizen1_utils.validateArgumentType(state, "boolean", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - _self.add = function (poi, successCallback, errorCallback) { - if (!_security.all && !_security.add) { + tizen1_utils.validateCallbackType(successCallback, errorCallback); + + _updatePowerStatus(state); + if (successCallback) { + successCallback(); + } + } +/* + function setCardEmulation(_seType, successCallback, errorCallback) { + var originalType; + if (!_security.all && !_security.setCardEmulation) { throw new WebAPIError(errorcode.SECURITY_ERR); } + tizen1_utils.validateCallbackType(successCallback, errorCallback); - throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); - }; + switch (_seType) { + case "NONE": + case "UICC": + break; + default: + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + } - _self.remove = function (poi, successCallback, errorCallback) { - if (!_security.all && !_security.remove) { + if (!powered) { + return; + } + + originalType = seType; + seType = _seType; + + if (_data.listener.onCardEmulationChanged && originalType !== seType) { + _data.listener.onCardEmulationChanged(seType); + } + if (successCallback) { + successCallback(); + } + } + function setCardEmulationChangeListener(changeCallback) { + if (!_security.all && !_security.setCardEmulationChangeListener) { throw new WebAPIError(errorcode.SECURITY_ERR); } + tizen1_utils.validateArgumentType(changeCallback, "function", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + if (!powered) { + return; + } + _data.listener.onCardEmulationChanged = changeCallback; + } - throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); - }; + function unsetCardEmulationChangeListener() { + if (!_security.all && !_security.unsetCardEmulationChangeListener) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + if (!powered || !_data.listener.onCardEmulationChanged) { + return; + } - return _self; -}; + _data.listener.onCardEmulationChanged = null; + } +*/ -}); -define('ripple/platform/tizen/2.0/power', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var event = require('ripple/event'), - utils = require('ripple/utils'), - constants = require('ripple/constants'), - deviceSettings = require('ripple/deviceSettings'), - errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - _POWER_RESOURCE = constants.POWER_RESOURCE, - _SCREEN_STATE = constants.POWER_RESOURCE.SCREEN.STATE, - ScreenState = {"previous" : null, "current" : null}, - _listeners = [], - _isScreenResourceOccupied = false, - _originalBrightness, - _isCPUAwake = false, - _isScreenOn = true, - _normalBrightness, - _minimal_screen_state = null, - _security = { - "http://tizen.org/privilege/power": ["request", "setScreenBrightness", "turnScreenOn", "turnScreenOff"], - all: true - }, - _self; + // Registers a callback function to invoke when NFC tag is detected. + function setTagListener(detectCallback, tagFilter) { + if (!_security.setTagListener) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } -/**initialize**/ -function initState() { - _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness"); - updateResourceState(); -} + _validateCallbackType(detectCallback); -function getResourceState(value) { - var state; - value = Number(value); - if (value <= _SCREEN_STATE.SCREEN_OFF.MAX) { - state = _SCREEN_STATE.SCREEN_OFF.NAME; - } else if (value < _SCREEN_STATE.SCREEN_DIM.MAX) { - state = _SCREEN_STATE.SCREEN_DIM.NAME; - } else if (value < _SCREEN_STATE.SCREEN_NORMAL.MAX) { - state = _SCREEN_STATE.SCREEN_NORMAL.NAME; - } else { - state = _SCREEN_STATE.SCREEN_BRIGHT.NAME; + if (tagFilter) { + tizen1_utils.validateArgumentType(tagFilter, "array", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } + //TODO: tagFilter support + if (!powered) { + return; + } + _data.listener.onTagDetected = detectCallback; } - return state; -} -function updateResourceState() { - var brightness, actualState; - brightness = deviceSettings.retrieve("DISPLAY.brightness"); - actualState = getResourceState(brightness); - ScreenState.previous = ScreenState.current; - ScreenState.current = actualState; -} + // Registers a callback function to be invoked when NFC peer-to-peer target is detected. + function setPeerListener(detectCallback) { + if (!_security.setPeerListener) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } -function callListeners(listeners, previousState, changedState) { - listeners.forEach(function (listener) { - setTimeout(function () { - listener(previousState, changedState); - }, 1); - }); -} + _validateCallbackType(detectCallback); -function triggerListenerCB(stateObj) { - if (stateObj.previous !== stateObj.current) { - callListeners(_listeners, stateObj.previous, stateObj.current); + if (!powered) { + return; + } + _data.listener.onPeerDetected = detectCallback; } -} -_self = function () { - function request(resource, state) { - if (!_security.all && !_security.request) { + // Unregisters the listener for detecting an NFC tag. + function unsetTagListener() { + if (!_security.unsetTagListener) { throw new WebAPIError(errorcode.SECURITY_ERR); } - if (typeof resource !== 'string' || typeof state !== 'string') { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } - //Check resource - if (!_POWER_RESOURCE.hasOwnProperty(resource)) { - throw new WebAPIError(errorcode.INVALID_VALUES_ERR); - } - //Check state - if (!_POWER_RESOURCE[resource].STATE.hasOwnProperty(state)) { - throw new WebAPIError(errorcode.INVALID_VALUES_ERR); + + if (!powered || !_data.listener.onTagDetected) { + return; } - // Exception check: SCREEN_OFF is a state cannot be requested - if (resource === "SCREEN" && state === "SCREEN_OFF") { - throw new WebAPIError(errorcode.INVALID_VALUES_ERR); + + _data.listener.onTagDetected = null; + } + + // Unregisters the listener for detecting an NFC peer-to-peer target. + function unsetPeerListener() { + if (!_security.unsetPeerListener) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - switch (resource) { - case "SCREEN" : - if ((_minimal_screen_state === null) || - (_minimal_screen_state === "SCREEN_DIM" && (state === "SCREEN_NORMAL" || state === "SCREEN_BRIGHT")) || - (_minimal_screen_state === "SCREEN_NORMAL" && state === "SCREEN_BRIGHT")) { - _minimal_screen_state = state; - } - break; - case "CPU" : - _isCPUAwake = true; - break; - default: - break; + + if (!powered || !_data.listener.onPeerDetected) { + return; } + + _data.listener.onPeerDetected = null; } - function release(resource) { - switch (resource) { - case "SCREEN" : - if (_isScreenResourceOccupied) { - _isScreenResourceOccupied = false; - deviceSettings.persist("DISPLAY.brightness", _originalBrightness); - event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]); - updateResourceState(); - triggerListenerCB(ScreenState); - } - _minimal_screen_state = null; - break; - case "CPU" : - _isCPUAwake = false; - break; - default: - if (typeof resource === "string") { - throw (new WebAPIError(errorcode.INVALID_VALUES_ERR)); - } else { - throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } + // Gets NDEF message cached when the tag is detected. + function getCachedMessage() { + if (!_security.getCachedMessage) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - } - function setScreenStateChangeListener(listener) { - tizen1_utils.validateArgumentType(listener, "function", - new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - _listeners.push(listener); + return _data.pairedNFC || new NDEFMessage([]); } - function unsetScreenStateChangeListener() { - _listeners = []; - } + nfcAdapter = { + setPowered : setPowered, + //setCardEmulation: setCardEmulation, + //setCardEmulationChangeListener: setCardEmulationChangeListener, + //unsetCardEmulationChangeListener: unsetCardEmulationChangeListener, + setTagListener : setTagListener, + setPeerListener : setPeerListener, + unsetTagListener : unsetTagListener, + unsetPeerListener : unsetPeerListener, + getCachedMessage : getCachedMessage + }; - function getScreenBrightness() { - var brightness = deviceSettings.retrieve("DISPLAY.brightness"); - return brightness; + nfcAdapter.__defineGetter__("powered", function () { + return powered; + }); + + nfcAdapter.__defineGetter__("seType", function () { + return seType; + }); + + return nfcAdapter; +}; + +NFCTag = function (type, isSupportedNDEF, ndefSize, properties, isConnected, ndefs) { + var nfcTag, i, j, + _ndefs, + rec, + _records, + _ndefs_index = 0; + + type = type || null; + isSupportedNDEF = isSupportedNDEF || false; + ndefSize = ndefSize || 1; + properties = null; + isConnected = isConnected || false; + + _ndefs = []; + for (i in ndefs) { + _records = []; + for (j in ndefs[i].records) { + rec = ndefs[i].records[j]; + _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload, rec.id)); + } + _ndefs.push(new NDEFMessage(_records)); } - function setScreenBrightness(brightness) { - if (!_security.all && !_security.setScreenBrightness) { + // Reads NDEF data. + function readNDEF(readCallback, errorCallback) { + if (!_security.readNDEF) { throw new WebAPIError(errorcode.SECURITY_ERR); } - if (typeof brightness !== 'number') { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } - if (brightness < 0 || brightness > 1) { - throw new WebAPIError(errorcode.INVALID_VALUES_ERR); - } - if (!_isScreenResourceOccupied) { - _originalBrightness = deviceSettings.retrieve("DISPLAY.brightness"); - _isScreenResourceOccupied = true; + function _readNDEF() { + if (!isConnected || !isSupportedNDEF) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); + } + return; + } + if (_ndefs_index >= ndefSize) { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); + } else { + _data.pairedNFC = _ndefs[_ndefs_index]; + readCallback(_ndefs[_ndefs_index]); + _ndefs_index++; + } } - deviceSettings.persist("DISPLAY.brightness", brightness); - event.trigger("DisplayBrightnessChangedByPower", [brightness]); - updateResourceState(); - triggerListenerCB(ScreenState); - } - function isScreenOn() { - return _isScreenOn; + tizen1_utils.validateTypeMismatch(readCallback, errorCallback, "nfc:readNDEF", _readNDEF); } - function restoreScreenBrightness() { - if (_isScreenResourceOccupied) { - _isScreenResourceOccupied = false; - deviceSettings.persist("DISPLAY.brightness", _originalBrightness); - event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]); - updateResourceState(); - triggerListenerCB(ScreenState); + // Writes NDEF data. + function writeNDEF(ndefMessage, successCallback, errorCallback) { + if (!_security.writeNDEF) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + + tizen1_utils.validateCallbackType(successCallback, errorCallback); + + tizen1_utils.validateArgumentType(ndefMessage, "object", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + + if (!isConnected || !isSupportedNDEF) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); + } + return; + } + db.saveObject(_NFC_OUTPUT_MESSAGE, ndefMessage); + event.trigger("nfc-output-msg", []); + if (successCallback) { + successCallback(); } } - function turnScreenOn() { - var brightness, value, flag = false; - if (!_security.all && !_security.turnScreenOn) { + // Access the raw format card. + function transceive(data, dataCallback, errorCallback) { + if (!_security.transceive) { throw new WebAPIError(errorcode.SECURITY_ERR); } - brightness = deviceSettings.retrieve("DISPLAY.brightness"); - switch (_minimal_screen_state) { - case "SCREEN_DIM": - if (brightness <= _SCREEN_STATE.SCREEN_OFF.VALUE) { - if (!_isScreenResourceOccupied) { - _originalBrightness = brightness; - _isScreenResourceOccupied = true; + function _transceive() { + if (!tizen1_utils.isValidArray(data)) + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + + if (!isConnected || isSupportedNDEF) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); } - value = _SCREEN_STATE.SCREEN_DIM.VALUE; - flag = true; + return; } - break; - case "SCREEN_NORMAL": - if (brightness < _SCREEN_STATE.SCREEN_NORMAL.MIN) { - if (!_isScreenResourceOccupied) { - _originalBrightness = brightness; - _isScreenResourceOccupied = true; - } - value = _normalBrightness; - flag = true; + db.saveObject(_NFC_OUTPUT_MESSAGE, data); + event.trigger("nfc-output-msg", []); + dataCallback(ndefs); + } + + tizen1_utils.validateTypeMismatch(dataCallback, errorCallback, "nfc:transceive", _transceive); + } + + // Formats the detected tag that can store NDEF messages. + /* + function formatNDEF(successCallback, errorCallback, key) { + + tizen1_utils.validateCallbackType(successCallback, errorCallback); + + if (key) { + tizen1_utils.validateArgumentType(key, "array", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } + + if (!isConnected || !isSupportedNDEF) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); } - break; - case "SCREEN_BRIGHT": - if (brightness < _SCREEN_STATE.SCREEN_BRIGHT.MIN) { - if (!_isScreenResourceOccupied) { - _originalBrightness = brightness; - _isScreenResourceOccupied = true; + return; + } + + successCallback(); + } + */ + + nfcTag = { + readNDEF : readNDEF, + writeNDEF : writeNDEF, + transceive : transceive, + //formatNDEF : formatNDEF + }; + + nfcTag.__defineGetter__("type", function () { + return type; + }); + + nfcTag.__defineGetter__("isSupportedNDEF", function () { + return isSupportedNDEF; + }); + + nfcTag.__defineGetter__("ndefSize", function () { + return ndefSize; + }); + + nfcTag.__defineGetter__("properties", function () { + return properties; + }); + + nfcTag.__defineGetter__("isConnected", function () { + return isConnected; + }); + + return nfcTag; +}; + +NFCPeer = function (isConnected) { + var nfcPeer; + + isConnected = isConnected || false; + + // Registers a callback function to be invoked when NDEF message is received from NFC peer-to-peer target connected. + function setReceiveNDEFListener(successCallback, errorCallback) { + if (!_security.setReceiveNDEFListener) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + function _setReceiveNDEFListener() { + if (!isConnected) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); } - value = _SCREEN_STATE.SCREEN_BRIGHT.VALUE; - flag = true; + return; } - break; - } - if (flag) { - deviceSettings.persist("DISPLAY.brightness", value); - event.trigger("DisplayBrightnessChangedByPower", [value]); - updateResourceState(); - triggerListenerCB(ScreenState); + _data.listener.onNDEFReceived = successCallback; } - _isScreenOn = true; + + tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "nfc:setReceiveNDEFListener", _setReceiveNDEFListener); } - function turnScreenOff() { - if (!_security.all && !_security.turnScreenOff) { + // Unregisters the listener for receiving NDEFMessage from NFC peer-to-peer target connected. + function unsetReceiveNDEFListener() { + if (!_security.unsetReceiveNDEFListener) { throw new WebAPIError(errorcode.SECURITY_ERR); } - _isScreenOn = false; + + _data.listener.onNDEFReceived = null; } - function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; + // Sends data to NFC peer-to-peer target. + function sendNDEF(ndefMessage, successCallback, errorCallback) { + if (!_security.sendNDEF) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + + tizen1_utils.validateCallbackType(successCallback, errorCallback); + + tizen1_utils.validateArgumentType(ndefMessage, "object", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + + if (!isConnected) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); + return; + } + + db.saveObject(_NFC_OUTPUT_MESSAGE, ndefMessage); + event.trigger("nfc-output-msg", []); + if (successCallback) { + successCallback(); } } - var power = { - request: request, - release: release, - setScreenStateChangeListener: setScreenStateChangeListener, - unsetScreenStateChangeListener: unsetScreenStateChangeListener, - getScreenBrightness: getScreenBrightness, - setScreenBrightness: setScreenBrightness, - isScreenOn: isScreenOn, - restoreScreenBrightness: restoreScreenBrightness, - turnScreenOn: turnScreenOn, - turnScreenOff: turnScreenOff, - handleSubFeatures : handleSubFeatures + nfcPeer = { + setReceiveNDEFListener : setReceiveNDEFListener, + unsetReceiveNDEFListener : unsetReceiveNDEFListener, + sendNDEF : sendNDEF }; - return power; + nfcPeer.__defineGetter__("isConnected", function () { + return isConnected; + }); + + return nfcPeer; }; -initState(); -event.on("CpuLoadChanged", function (value) { - var load; - if (_isCPUAwake && Number(value) === 0) { - load = _POWER_RESOURCE.CPU.STATE.CPU_AWAKE.DEFAULT_VALUE; - deviceSettings.persist("CPU.load", load); - event.trigger("CpuLoadChangedByPower", [load]); - } -}); -event.on("DisplayBrightnessChanged", function () { - _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness"); - updateResourceState(); - triggerListenerCB(ScreenState); -}); +function _initialize() { + _data.nfcAdapter = new NFCAdapter(); +} +_initialize(); module.exports = _self; + }); -define('ripple/platform/tizen/2.0/push', function (require, exports, module) { +define('ripple/platform/tizen/2.0/notification', function (require, exports, module) { /* - * Copyright 2013 Intel Corporation. + * Copyright 2012 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87398,210 +89692,542 @@ define('ripple/platform/tizen/2.0/push', function (require, exports, module) { * limitations under the License. */ -var event = require('ripple/event'), +var db = require('ripple/db'), + utils = require('ripple/utils'), + event = require('ripple/event'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), - t = require('ripple/platform/tizen/2.0/typedef'), - Notification = require('ripple/platform/tizen/2.0/notification'), - StatusNotification = require('ripple/platform/tizen/2.0/StatusNotification'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), - TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), - PushMessage, - _data = { - service: { -/* "ID_APPLICATION_0": { - * appId: null, - * registrationId: null, - * appControl: null, - * isRegistered: false, - * isConnected: false, - * onpushed: null - * } - */ - } - }, + _notificationStack, _security = { - "http://tizen.org/privilege/push": ["registerService", - "unregisterService", "connectService", "disconnectService", - "getRegistrationId"], - all: true + "http://tizen.org/privilege/notification": ["post", "update", "remove", "removeAll"] }, _self; -function _initialize() { - event.on("PushNotified", function (appId, pushMessage) { - var appService, notificationDict, statusNotification, notification; +function _validateNotification(notification) { + if (typeof notification !== "object") { + return false; + } - appService = _data.service[appId]; + if (typeof notification.id !== "string") { + return false; + } - if (!appService) - return; + if (typeof notification.type !== "string" || notification.type !== "STATUS") { + return false; + } - if (appService.isConnected) { - appService.onpushed(new PushMessage(pushMessage)); - } else { - notificationDict = { - content: pushMessage.appData, - appControl: appService.appControl, - appId: appId - }; - statusNotification = new StatusNotification("SIMPLE", - pushMessage.alertMessage, notificationDict); - notification = new Notification(); + if (typeof notification.title !== "string") { + return false; + } - notification.post(statusNotification); - } - }); -} + if (notification.content && typeof notification.content !== "string") { + return false; + } -function _getCurrentApplicationId() { - return "ID_APPLICATION_0"; + return true; } -_self = { - registerService: function (appControl, successCallback, errorCallback) { - var appId, appService; +_self = function () { + function post(notification) { + if (!_security.post) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + if (!_validateNotification(notification)) { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } - if (!_security.all && !_security.registerService) { - throw new WebAPIException(errorcode.SECURITY_ERR); + if (notification.statusType === "PROGRESS" && notification.progressValue && + (notification.progressValue < 1 || notification.progressValue > 100)) { + throw new WebAPIError(errorcode.INVALID_VALUES_ERR); } - if (!(new TypeCoerce(t.ApplicationControl)).match(appControl) || - !(new TypeCoerce(t.PushRegisterSuccessCallback)).match(successCallback) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + + if (!_notificationStack[notification.id]) { + Object.defineProperty(notification, "postedTime", {value: new Date().toString(), writable: false}); + _notificationStack[notification.id] = utils.copy(notification); + db.saveObject("posted-notifications", _notificationStack); + event.trigger("refreshNotificationUI", [], true); } + } - appId = _getCurrentApplicationId(); - appService = { - appId: appId, - registrationId: null, - appControl: appControl, - isRegistered: false - }; - _data.service[appId] = appService; + function update(notification) { + if (!_security.update) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + if (!_validateNotification(notification)) { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } - event.trigger("PushRequest", ["REGISTER", appService], true); + if (notification.statusType === "PROGRESS" && notification.progressValue && + (notification.progressValue < 1 || notification.progressValue > 100)) { + throw new WebAPIError(errorcode.INVALID_VALUES_ERR); + } - if (appService.registrationId !== null) { - appService.isRegistered = true; - successCallback(appService.registrationId); - } else if (errorCallback) { - window.setTimeout(function () { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - }, 1); + if (_notificationStack[notification.id]) { + _notificationStack[notification.id] = utils.copy(notification); + db.saveObject("posted-notifications", _notificationStack); + event.trigger("refreshNotificationUI", [], true); } - }, - unregisterService: function (successCallback, errorCallback) { - var appId, appService; + } - if (!_security.all && !_security.unregisterService) { - throw new WebAPIException(errorcode.SECURITY_ERR); + function remove(id) { + if (!_security.remove) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - if ((successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) || - (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + if (typeof id !== "string") { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); } - appId = _getCurrentApplicationId(); - appService = _data.service[appId]; - if (!appService || !appService.isRegistered) { - if (errorCallback) { - window.setTimeout(function () { - errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); - }, 1); + if (!_notificationStack[id]) { + throw (new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + + delete _notificationStack[id]; + db.saveObject("posted-notifications", _notificationStack); + event.trigger('refreshNotificationUI', [], true); + } + + function removeAll() { + if (!_security.removeAll) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + _notificationStack = {}; + db.saveObject("posted-notifications", _notificationStack); + event.trigger('refreshNotificationUI', [], true); + } + + function get(id) { + if (typeof id !== "string") { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } + + if (!_notificationStack[id]) { + throw (new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + + return utils.copy(_notificationStack[id]); + } + + function getAll() { + var notifications = []; + utils.forEach(_notificationStack, function (item) { + notifications.push(utils.copy(item)); + }); + return notifications; + } + + function handleSubFeatures(subFeatures) { + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - return; } + } - delete _data.service[appId]; - event.trigger("PushRequest", ["UNREGISTER", appId]); + var notification = { + post: post, + update: update, + remove: remove, + removeAll: removeAll, + get: get, + getAll: getAll, + handleSubFeatures: handleSubFeatures + }; + + return notification; +}; + +function _initilize() { + _notificationStack = db.retrieveObject("posted-notifications") || {}; + event.on("refreshNotificationStack", function () { + _notificationStack = db.retrieveObject("posted-notifications"); + }); +} + +_initilize(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/package', function (require, exports, module) { +/* + * Copyright 2013 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var db = require('ripple/db'), + event = require('ripple/event'), + utils = require('ripple/utils'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), + PackageInformation = require('ripple/platform/tizen/2.0/PackageInformation'), + t = require('ripple/platform/tizen/2.0/typedef'), + _security = { + "http://tizen.org/privilege/packagemanager.install": ["install", "uninstall"], + "http://tizen.org/privilege/package.info": ["getPackagesInfo", "getPackageInfo", + "setPackageInfoEventListener", "unsetPackageInfoEventListener"] + }, + DB_PACKAGE_KEY = "tizen-db-package", + _listeners = [], + _data = { + packageList: {}, + installedList: {} }, + INTERVAL = 1000, // INTERVAL = 1sec + INSTALL_AMOUNT = 3072, // installation speed amount = 3072 (KB/sec) + _self; - connectService: function (notificationCallback) { - var appId, appService; +function _get() { + _data = db.retrieveObject(DB_PACKAGE_KEY); + utils.forEach(_data.installedList, function (item) { + item.lastModified = new Date(item.lastModified); + }); +} + +function _save() { + db.saveObject(DB_PACKAGE_KEY, _data); +} + +function _exec(callback, name, id, arg1) { + switch (name) { + case "onprogress": + callback[name](id, arg1); + break; + case "oncomplete": + callback[name](id); + break; + default: + break; + } +} - if (!_security.all && !_security.connectService) { +_self = function () { + var _package; + //public + function install(path, progressCallback, errorCallback) { + var intervalId, installedSize = 0, packageSize, updateFlag = false, item, info, progress; + if (!_security.install) { throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!(new TypeCoerce(t.PushNotificationCallback)).match(notificationCallback)) { + if (!(new TypeCoerce(t.DOMString)).match(path) || + !(new TypeCoerce(t.PackageProgressCallback)).match(progressCallback) || + (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - - appId = _getCurrentApplicationId(); - appService = _data.service[appId]; - if (!appService || !appService.isRegistered) { - throw new WebAPIException(errorcode.UNKNOWN_ERR); + if (!_data.packageList[path]) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + return; + } + item = _data.packageList[path]; + //check package has been installed or not + if (_data.installedList[item.id]) { + updateFlag = true; } + packageSize = item.totalSize; + intervalId = setInterval(function () { + if (installedSize >= packageSize) { + //install complete + _data.installedList[item.id] = new PackageInformation( + item.id, item.name, item.iconPath, item.version, + item.totalSize, item.dataSize, new Date(), + item.author, item.description, item.appIds + ); + event.trigger("install-apps", [item.appIds]); + _save(); + _exec(progressCallback, "oncomplete", item.id); + clearInterval(intervalId); + item = _data.installedList[item.id]; + utils.forEach(_listeners, function (listener) { + info = new PackageInformation( + item.id, item.name, item.iconPath, item.version, + item.totalSize, item.dataSize, item.lastModified, + item.author, item.description, item.appIds); + if (!updateFlag) { + listener.oninstalled(info); + } else { + listener.onupdated(info); + } + }); + event.trigger("installedList-updated"); + } else { + installedSize += INSTALL_AMOUNT; + if (installedSize > packageSize) { + progress = 100; + } else { + progress = Math.floor(installedSize * 100 / packageSize); + } + _exec(progressCallback, "onprogress", item.id, progress); + } - appService.isConnected = true; - appService.onpushed = notificationCallback; - event.trigger("PushRequest", ["CONNECT", appId]); - }, + }, INTERVAL); + } - disconnectService: function () { - var appId, appService; + function uninstall(id, progressCallback, errorCallback) { + var intervalId, removedSize = 0, packageSize, item, progress; + if (!_security.uninstall) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + if (!(new TypeCoerce(t.PackageId)).match(id) || + !(new TypeCoerce(t.PackageProgressCallback)).match(progressCallback) || + (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (!_data.installedList[id]) { + if (errorCallback) { + errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR)); + } + return; + } + item = _data.installedList[id]; + packageSize = item.totalSize; + intervalId = setInterval(function () { + if (removedSize >= packageSize) { + //remove complete + utils.forEach(_data.packageList, function (_package) { + if (_package.id === id) { + event.trigger("remove-apps", [_package.appIds]); + } + }); + delete _data.installedList[item.id]; + _save(); + _exec(progressCallback, "oncomplete", item.id); + clearInterval(intervalId); + item = _data.installedList[item.id]; + utils.forEach(_listeners, function (listener) { + listener.onuninstalled(id); + }); + event.trigger("installedList-updated"); + } else { + removedSize += INSTALL_AMOUNT * 10; + if (removedSize > packageSize) { + progress = 100; + } else { + progress = Math.floor(removedSize * 100 / packageSize); + } + _exec(progressCallback, "onprogress", item.id, progress); + } + }, INTERVAL); + } - if (!_security.all && !_security.disconnectService) { + function getPackagesInfo(successCallback, errorCallback) { + var packageArray = []; + if (!_security.getPackagesInfo) { throw new WebAPIException(errorcode.SECURITY_ERR); } + if (!(new TypeCoerce(t.PackageInformationArraySuccessCallback)).match(successCallback) || + (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + utils.forEach(_data.installedList, function (item) { + var i; + i = new PackageInformation( + item.id, item.name, item.iconPath, item.version, + item.totalSize, item.dataSize, item.lastModified, + item.author, item.description, item.appIds + ); + packageArray.push(i); + }); + successCallback(packageArray); + } - appId = _getCurrentApplicationId(); - appService = _data.service[appId]; - if (!appService || !appService.isRegistered) { - throw new WebAPIException(errorcode.UNKNOWN_ERR); + function getPackageInfo(id) { + var p, item; + if (!_security.getPackageInfo) { + throw new WebAPIException(errorcode.SECURITY_ERR); } - if (!appService.isConnected) { - return; + + //assgin the defaul package ID + if (arguments.length === 0) { + id = "api1pack00"; } - appService.onpushed = null; - appService.isConnected = false; - event.trigger("PushRequest", ["DISCONNECT", appId]); - }, + if (!(new TypeCoerce(t.PackageId)).match(id)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (!_data.installedList[id]) { + throw new WebAPIException(errorcode.NOT_FOUND_ERR); + } + item = _data.installedList[id]; + p = new PackageInformation( + item.id, item.name, item.iconPath, item.version, + item.totalSize, item.dataSize, item.lastModified, + item.author, item.description, item.appIds + ); + return p; + } - getRegistrationId: function () { - var appService; + function setPackageInfoEventListener(eventCallback) { + if (!_security.setPackageInfoEventListener) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + if (!(new TypeCoerce(t.PackageInfomationEventCallback)).match(eventCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + _listeners.push(eventCallback); + } - if (!_security.all && !_security.getRegistrationId) { + function unsetPackageInfoEventListener() { + if (!_security.unsetPackageInfoEventListener) { throw new WebAPIException(errorcode.SECURITY_ERR); } + _listeners = []; + } - appService = _data.service[_getCurrentApplicationId()]; - if (!appService || !appService.isRegistered) { - return null; + function handleSubFeatures(subFeatures) { + var i, subFeature; + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; + } } + } - return appService.registrationId; + function updatePackage(path, updateFlag) { + var item, p, info; + if (!_data.packageList[path]) { + return; + } + _get(); + p = _data.packageList[path]; + item = _data.installedList[p.id]; + utils.forEach(_listeners, function (listener) { + info = new PackageInformation( + item.id, item.name, item.iconPath, item.version, + item.totalSize, item.dataSize, item.lastModified, + item.author, item.description, item.appIds); + if (!updateFlag) { + listener.oninstalled(info); + } else { + listener.onupdated(info); + } + }); } + + event.on("install-packge", function (path) { + updatePackage(path, false); + }); + event.on("update-package", function (path) { + updatePackage(path, true); + }); + + event.on("uninstall-package", function (id) { + _get(); + utils.forEach(_listeners, function (listener) { + listener.onuninstalled(id); + }); + }); + + _package = { + install: install, + uninstall: uninstall, + getPackagesInfo: getPackagesInfo, + getPackageInfo: getPackageInfo, + setPackageInfoEventListener: setPackageInfoEventListener, + unsetPackageInfoEventListener: unsetPackageInfoEventListener, + handleSubFeatures: handleSubFeatures + }; + + return _package; }; +function _initialize() { + _get(); +} + _initialize(); -PushMessage = function (pushMessageInitDict) { - var appData, alertMessage, date; +module.exports = _self; - this.__defineGetter__("appData", function () { - return appData; - }); - this.__defineGetter__("alertMessage", function () { - return alertMessage; - }); +}); +define('ripple/platform/tizen/2.0/pendingObject', function (require, exports, module) { +/* + * Copyright 2011 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - this.__defineGetter__("date", function () { - return date; - }); +module.exports = function (pendingObj) { + var cancelFlag = true; + this.setCancelFlag = function (flag) { + cancelFlag = flag; + }; + this.getCancelFlag = function () { + return cancelFlag; + }; + this.userCancel = null; + this.pendingID = null; +}; - appData = pushMessageInitDict.appData || ""; - alertMessage = pushMessageInitDict.alertMessage || ""; - date = pushMessageInitDict.date || new Date(); +}); +define('ripple/platform/tizen/2.0/pendingoperation', function (require, exports, module) { +/* + * Copyright 2011 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = function (pendingObj) { + var pending = true; + this.cancel = function () { + if (pending === true) { + if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) { + pending = false; + // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout + clearTimeout(pendingObj.pendingID); + return false; + } + if (typeof (pendingObj.userCancel) === "function") { + pendingObj.userCancel(); + } + clearTimeout(pendingObj.pendingID); + pending = false; + return true; + } else { + return false; + } + }; }; -module.exports = _self; }); -define('ripple/platform/tizen/2.0/route', function (require, exports, module) { +define('ripple/platform/tizen/2.0/poi', function (require, exports, module) { /* * Copyright 2012 Intel Corporation. * @@ -87618,39 +90244,53 @@ define('ripple/platform/tizen/2.0/route', function (require, exports, module) { * limitations under the License. */ -var errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), - ProviderNominatim = require('ripple/platform/tizen/2.0/routeBackend_navigation'), // navigation route service - _getProviders, +var OpenMapQuestProvider = require('ripple/platform/tizen/2.0/poiBackend_openmapquest'), // opne.MapQuest.xapi service _providers, + _security = { + "http://tizen.org/api/poi": [], + "http://tizen.org/api/poi.read": ["find"], + "http://tizen.org/api/poi.write": ["add", "remove", "update"], + all: true + }, _self; function _initialize() { - _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})]; + _providers = [new OpenMapQuestProvider({name : "MapQuest", connectivity : "ONLINE", metaData : _security})]; } -_initialize(); +_self = function () { + var poi; -_self = { - getDefaultProvider : function () { - if (arguments.length !== 0) { - throw (new WebAPIError(errorcode.INVALID_VALUES_ERR)); - } - return _providers[0]; - }, - getProviders : function () { - if (arguments.length !== 0) { - throw (new WebAPIError(errorcode.INVALID_VALUES_ERR)); + poi = { + getDefaultProvider : function () { + return _providers[0]; + }, + getProviders : function () { + return _providers; + }, + handleSubFeatures: function (subFeatures) { + var i, subFeature; + for (subFeature in subFeatures) { + if (_security[subFeature].length === 0) { + _security.all = true; + break; + } + _security.all = false; + for (i = 0; i < _security[subFeature].length; i++) { + _security[_security[subFeature][i]] = true; + } + } + _initialize(); } - return _providers; - } + }; + + return poi; }; module.exports = _self; }); -define('ripple/platform/tizen/2.0/routeBackend_local', function (require, exports, module) { +define('ripple/platform/tizen/2.0/poiBackend_openmapquest', function (require, exports, module) { /* * Copyright 2012 Intel Corporation. * @@ -87667,532 +90307,535 @@ define('ripple/platform/tizen/2.0/routeBackend_local', function (require, export * limitations under the License. */ -var db = require('ripple/db'), - utils = require('ripple/utils'), +var lbs = require('ripple/platform/tizen/2.0/lbs_utils'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - lbs = require('ripple/platform/tizen/2.0/lbs'), - LocationServiceProvider = {}, - RouteWaypoint, - RouteDistance, - RouteDuration, - RouteStep, - RouteSegment, - RouteRequestOptions, - RouteResultSummary, - RouteResult, - _data = { - DB_ROUTE_LOCATION_KEY: "tizen1-db-route", - DB_ROUTE_COLLEAGE_KEY: "tizen2-db-route", - routeProvider: {}, - routes: [], - RouteDistanceUnit: ["M", "KM", "MI", "FT"], - providers: [], - path: [] - }, - _self; - -// The RouteWaypoint object -RouteWaypoint = function () { - return { - position: { - latitude: 0, - longitude: 0 - }, - isStopover: true - }; -}; + POIGeometry = require('ripple/platform/tizen/2.0/POIGeometry'), + SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), + _security; -// The RouteDistance object -RouteDistance = function () { - return { - text: "", - value: 0, - unit: "KM" +function POIPublic(prop) { + /* This is created for public use */ + var _self, i, copy, attr, _id = null, _providerName = null; + if (prop.id) { + _id = prop.id; + } + if (prop.providerName) { + _providerName = prop.providerName; + } + _self = { + name : null, + categories : [], + address : null, + phoneNumbers : [], + geometry : null, + urls : [], + rating : null, + tags : null, + toGeoJSON : function () { + throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); + } }; -}; -// The RouteDuration object -RouteDuration = function () { - return { - text: "", - value: 0 // The duration in a seconds - }; -}; + _self.__defineGetter__("id", function () { + return _id; + }); -// The RouteStep object -RouteStep = function () { - var _self = { - mode: "", // The way of the travel, for example: car, bike, foot - instruction: "", // The instruction of this step - points: [] // The points of this step - }; + _self.__defineGetter__("providerName", function () { + return _providerName; + }); - _self.origin = new SimpleCoordinates(0, 0); - _self.destination = new SimpleCoordinates(0, 0); - _self.distance = new RouteDistance(); - _self.duration = new RouteDuration(); + if (prop) { + if (prop.name) { + _self.name = String(prop.name); + } + if (tizen1_utils.isValidArray(prop.categories)) { + _self.categories = []; + for (i in prop.categories) { + _self.categories.push(String(prop.categories[i])); + } + } + if (prop.address) { + if (typeof prop.address === "string") { + _self.address = String(prop.address); + } else if (Object.prototype.toString.call(prop.address) === "[object Object]") { + copy = prop.address.constructor(); + for (attr in prop.address) { + if (prop.address.hasOwnProperty(attr)) { + copy[attr] = prop.address[attr]; + } + } + _self.address = copy; + } + } + if (tizen1_utils.isValidArray(prop.phoneNumbers)) { + _self.phoneNumbers = []; + for (i in prop.phoneNumbers) { + _self.phoneNumbers.push(String(prop.phoneNumbers[i])); + } + } + if (prop.geometry) { + _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt); + } + if (tizen1_utils.isValidArray(prop.urls)) { + _self.urls = []; + for (i in prop.urls) { + _self.urls.push(String(prop.urls[i])); + } + } + if (typeof prop.rating === "number") { + _self.rating = prop.rating; + } + if (Object.prototype.toString.call(prop.tags) === "[object Object]") { + copy = prop.tags.constructor(); + for (attr in prop.tags) { + if (prop.tags.hasOwnProperty(attr)) { + copy[attr] = prop.tags[attr]; + } + } + _self.tags = copy; + } + } return _self; -}; +} -// The RouteSegment object -RouteSegment = function () { - var _self = { - steps: [] - }; +module.exports = function (prop) { - _self.origin = new SimpleCoordinates(0, 0); - _self.destination = new SimpleCoordinates(0, 0); - _self.distance = new RouteDistance(); - _self.duration = new RouteDuration(); + var _self = new lbs.LocationServiceProvider(prop); - return _self; -}; + if (prop.metaData) { + _security = prop.metaData; + } -// The RouteRequestOptions object -RouteRequestOptions = function () { - return { - mode: "", // CAR, BIKE - unit: "KM", - routeGoal: "SHORTEST", - constraints: ["HIGHWAY", "TOLL", "UNPAVED"], - wayPoints: [], - maxResults: 1 - }; -}; + _self.__defineGetter__("supportedFilterTypes", function () { + return []; + }); -// The RouteResultSummary object -RouteResultSummary = function () { - var _self = {}; + _self.__defineGetter__("supportedPOIFilterAttributes", function () { + return []; + }); - _self.origin = new SimpleCoordinates(0, 0); - _self.destination = new SimpleCoordinates(0, 0); - _self.totalDistance = new RouteDistance(); - _self.totalDuration = new RouteDuration(); + _self.__defineGetter__("supportedCategories", function () { + /* reference: http://wiki.openstreetmap.org/wiki/Map_Features#Amenity */ + return ["bar", "bbq", "biergarten", "cafe", "drinking_water", "fast_food", "food_court", "ice_cream", + "pub", "restaurant", "college", "kindergarten", "library", "school", "university", + "bicycle_parking", "bicycle_rental", "bus_station", "car_rental", "car_sharing", "car_wash", + "ev_charging", "ferry_terminal", "fuel", "grit_bin", "parking", "parking_entrance", + "parking_space", "taxi", "atm", "bank", "bureau_de_change", "baby_hatch", "clinic", + "dentist", "doctors", "hospital", "nursing_home", "pharmacy", "social_facility", "veterinary", + "arts_centre", "cinema", "community_centre", "fountain", "nightclub", "social_centre", + "stripclub", "studio", "swingerclub", "theatre", "bench", "brothel", "clock", "courthouse", + "crematorium", "embassy", "fire_station", "grave_yard", "hunting_stand", "marketplace", + "place_of_worship", "police", "post_box", "post_office", "prison", "public_building", + "recycling", "sauna", "shelter", "shower", "telephone", "toilets", "townhall", "vending_machine", + "waste_basket", "waste_disposal", "watering_place"]; + }); - return _self; -}; + _self.__defineGetter__("capabilities", function () { + /* The set is empty, indicating that this provider supports only 'find' operations */ + return []; + }); -// The RouteResult object -RouteResult = function () { - var _self = { - segments: [] - }; + _self.find = function (point, successCallback, errorCallback, options) { + /* This provider only supports searching by "GeoRectBounds" due to MapQuest XAPI limitation */ - _self.summary = new RouteResultSummary(); + function _find() { + var searchStr, pois = [], isTypeOK = false, + id, providerName, name, categories = [], geometry; - return _self; -}; + if (Object.prototype.toString.call(point) === "[object Object]") { + if (point.southWest && point.northEast) { + if (typeof point.southWest.latitude === "number" && + typeof point.southWest.longitude === "number" && + typeof point.northEast.latitude === "number" && + typeof point.northEast.longitude === "number") { + isTypeOK = true; + } + } + } -// Floyd arithmetic in Mathematics, solving the optimal way -function floyd(e, n, startIndex, endIndex) { - var MAX = Infinity, - a = new Array(n), i, j, k, p = new Array(n), - paths, pathWay = []; + if (!isTypeOK) { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } - for (i = 1; i < n + 1; i++) { - a[i] = new Array(n); - } - for (i = 1; i < n + 1; i++) { - p[i] = new Array(n); - } - for (i = 1; i < n + 1; i++) { - for (j = 1; j < n + 1; j++) { - if (i === j || e[i][j] === "MIN") { - a[i][j] = 0; - } else if (e[i][j] !== 0 && e[i][j] !== "MIN") { - a[i][j] = e[i][j]; - } else { - a[i][j] = MAX; + searchStr = "http://open.mapquestapi.com/xapi/api/0.6/node"; + if (options && tizen1_utils.isValidArray(options.categories) && + options.categories.length > 0 && typeof options.categories[0] === "string") { + /* xapi support single amenity only */ + searchStr += "[amenity=" + options.categories[0] + "]"; } - p[i][j] = 0; - } - } - for (i = 1; i < n + 1; i++) { - a[i][i] = 0; - } - for (k = 1; k < n + 1; k++) { - for (i = 1; i < n + 1; i++) { - for (j = 1; j < n + 1; j++) { - if (parseInt(a[i][k], 10) + parseInt(a[k][j], 10) < a[i][j]) { - a[i][j] = parseInt(a[i][k], 10) + parseInt(a[k][j], 10); - p[i][j] = k; + searchStr += "[bbox=" + point.southWest.longitude + "," + point.southWest.latitude + "," + + point.northEast.longitude + "," + point.northEast.latitude + "]"; + + /* use Open MapQuest online xapi service. (http://open.mapquestapi.com/xapi/) */ + $.ajax({ + type: "GET", + url: searchStr, + dataType: "xml", + timeout: 15000, /* 15 secs timeout */ + success: function (xml) { + providerName = $(xml).find("osm").attr("generator"); + $(xml).find("node").each(function () { + var $item = $(this); + categories = []; + id = $item.attr("id"); + geometry = new POIGeometry(new SimpleCoordinates($item.attr("lat"), $item.attr("lon"))); + $item.find("tag").each(function () { + if ($(this).attr("k") === "name") { + name = $(this).attr("v"); + } else if ($(this).attr("k") === "amenity") { + categories.push($(this).attr("v")); + } + }); + pois.push(new POIPublic({id: id, providerName: providerName, name: name, + categories: categories, geometry: geometry})); + }); + successCallback(pois); + }, + error: function (obj, msg) { + if (errorCallback) { + if (msg === "timeout") { + setTimeout(function () { + errorCallback(new WebAPIError(errorcode.TIMEOUT_ERR)); + }, 1); + } else { + setTimeout(function () { + errorCallback(new WebAPIError(errorcode.NETWORK_ERR)); + }, 1); + } + } } - } + }); } - } - _data.path = []; - paths = findPath(startIndex, endIndex, p); - pathWay = []; - pathWay.push(startIndex); - for (i = 0; i < paths.length; i++) { - pathWay.push(paths[i]); - } - pathWay.push(endIndex); - - return pathWay; -} - -// Find the best way in the locations -function findPath(i, j, p) { - var k = p[i][j]; - if (k === 0 || i === j) { - return _data.path; - } - findPath(i, k, p); - _data.path.push(k); + if (!_security.all && !_security.find) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } - return findPath(k, j, p); -} + tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); + }; -// Find the index in the locations by string -function findIndexByStr(str, locations) { - for (var i in locations) { - if (locations[i].name === str) { - return parseInt(i, 10) + 1; + _self.update = function (poi, successCallback, errorCallback) { + if (!_security.all && !_security.update) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - } - return -1; -} -// Find the index in the colleages by name1 and name2 -function findValueByStr(start, end, locations, colleages) { - for (var i in colleages) { - if (colleages[i].name1 === locations[start - 1].name && colleages[i].name2 === locations[end - 1].name) { - return parseInt(i, 10); - } else if (colleages[i].name2 === locations[start - 1].name && colleages[i].name1 === locations[end - 1].name) { - return parseInt(i, 10); - } - } - return -1; -} + throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); + }; -// Find the index in the locations by latitude and longitude -function searchIndexBycoodinates(latitude, longitude, locations) { - if (latitude !== null && longitude !== null) { - for (var i in locations) { - if (locations[i].latitude === latitude && locations[i].longitude === longitude) { - return parseInt(i, 10) + 1; - } + _self.add = function (poi, successCallback, errorCallback) { + if (!_security.all && !_security.add) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - } - return -1; -} -// Get the relation among the locations -function getRelation(n, colleages, locations, goal) { - var i, j, start, end, relation = new Array(n + 1); - for (i = 1; i < n + 2; i++) { - relation[i] = new Array(n + 1); - } - for (i = 1; i < n + 1; i++) { - for (j = 1; j < n + 1; j++) { - relation[i][j] = 0; - } - } - for (i in colleages) { - start = findIndexByStr(colleages[i].name1, locations); - end = findIndexByStr(colleages[i].name2, locations); - if (start !== -1 && end !== -1 && start !== end) { - switch (goal) { - case "distance": - relation[start][end] = colleages[i].distance; - relation[end][start] = colleages[i].distance; - break; + throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); + }; - case "duration": - relation[start][end] = colleages[i].duration; - relation[end][start] = colleages[i].duration; - break; + _self.remove = function (poi, successCallback, errorCallback) { + if (!_security.all && !_security.remove) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } - case "simple": - relation[start][end] = 1; - relation[end][start] = 1; - break; + throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR); + }; - case "scenic": - if (colleages[i].addition.scenic === "SCENIC") { - relation[start][end] = 1; - relation[start][end] = 1; - } else if (colleages[i].addition.scenic === "") { - relation[start][end] = "MIN"; - relation[start][end] = "MIN"; - } - break; + return _self; +}; - case "cheap": - if (colleages[i].addition.toll === "TOLL") { - relation[start][end] = 1; - relation[end][start] = 1; - } else if (colleages[i].addition.toll === "") { - relation[start][end] = "MIN"; - relation[start][end] = "MIN"; - } - break; +}); +define('ripple/platform/tizen/2.0/power', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var event = require('ripple/event'), + constants = require('ripple/constants'), + deviceSettings = require('ripple/deviceSettings'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), + _POWER_RESOURCE = constants.POWER_RESOURCE, + _SCREEN_STATE = constants.POWER_RESOURCE.SCREEN.STATE, + ScreenState = {"previous" : null, "current" : null}, + _listeners = [], + _isScreenResourceOccupied = false, + _originalBrightness, + _isCPUAwake = false, + _isScreenOn = true, + _normalBrightness, + _minimal_screen_state = null, + _security = { + "http://tizen.org/privilege/power": ["request", "setScreenBrightness", "turnScreenOn", "turnScreenOff"] + }, + _self; - case "safe": - if (colleages[i].addition.hazardous === "HAZARDOUS") { - relation[start][end] = 1; - relation[end][start] = 1; - } else if (colleages[i].addition.hazardous === "") { - relation[start][end] = "MIN"; - relation[end][start] = "MIN"; - } - break; +/**initialize**/ +function initState() { + _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness"); + updateResourceState(); +} - default: - return null; - } - } +function getResourceState(value) { + var state; + value = Number(value); + if (value <= _SCREEN_STATE.SCREEN_OFF.MAX) { + state = _SCREEN_STATE.SCREEN_OFF.NAME; + } else if (value < _SCREEN_STATE.SCREEN_DIM.MAX) { + state = _SCREEN_STATE.SCREEN_DIM.NAME; + } else if (value < _SCREEN_STATE.SCREEN_NORMAL.MAX) { + state = _SCREEN_STATE.SCREEN_NORMAL.NAME; + } else { + state = _SCREEN_STATE.SCREEN_BRIGHT.NAME; } + return state; +} - return relation; +function updateResourceState() { + var brightness, actualState; + brightness = deviceSettings.retrieve("DISPLAY.brightness"); + actualState = getResourceState(brightness); + ScreenState.previous = ScreenState.current; + ScreenState.current = actualState; } -// Get the distance relationship among the locations -function distanceRelation(n, colleages, locations) { - return getRelation(n, colleages, locations, "distance"); +function callListeners(listeners, previousState, changedState) { + listeners.forEach(function (listener) { + setTimeout(function () { + listener(previousState, changedState); + }, 1); + }); } -// Get the duration relationship among the locations -function durationRelation(n, colleages, locations) { - return getRelation(n, colleages, locations, "duration"); +function triggerListenerCB(stateObj) { + if (stateObj.previous !== stateObj.current) { + callListeners(_listeners, stateObj.previous, stateObj.current); + } } -// Get the simple relationship among the locations -function simpleRelation(n, colleages, locations) { - return getRelation(n, colleages, locations, "simple"); -} - -// Get the cheap relationship among the locations -function cheapRelation(n, colleages, locations) { - return getRelation(n, colleages, locations, "cheap"); -} - -// Get the safe relationship among the locations -function safeRelation(n, colleages, locations) { - return getRelation(n, colleages, locations, "safe"); -} - -// Get the scenic relationship among the locations -function scenicRelation(n, colleages, locations) { - return getRelation(n, colleages, locations, "scenic"); -} - -// Get the shortest way by origin, destination, locations and colleages -function optimalWay(origin, destination, locations, colleages, relation) { - var n = locations.length, i, steps = [], step, relations, routeLocations, - originIndex, destinationIndex, startIndex, endIndex, colleageIndex, - originLatitude, originLongitude, destinationLatitude, destinationLongitude, - startLatitude, startLongitude, endLatitude, endLongitude, - originLocation, destinationLocation, segment, result; - - originLatitude = origin.latitude; - originLongitude = origin.longitude; - originIndex = searchIndexBycoodinates(originLatitude, originLongitude, locations); - - destinationLatitude = destination.latitude; - destinationLongitude = destination.longitude; - destinationIndex = searchIndexBycoodinates(destinationLatitude, destinationLongitude, locations); - - relations = relation(n, colleages, locations); - - if (originIndex !== -1 && destinationIndex !== -1) { - routeLocations = floyd(relations, n, parseInt(originIndex, 10), parseInt(destinationIndex, 10)); - - for (i = 0; i < routeLocations.length - 1; i++) { - colleageIndex = findValueByStr(routeLocations[i], routeLocations[i + 1], locations, colleages); - - if (colleageIndex !== -1) { - step = new RouteStep(); - startIndex = parseInt(routeLocations[i], 10) - 1; - endIndex = parseInt(routeLocations[i + 1], 10) - 1; - - startLatitude = locations[startIndex].latitude; - startLongitude = locations[startIndex].longitude; - originLocation = new SimpleCoordinates(startLatitude, startLongitude); - - endLatitude = locations[endIndex].latitude; - endLongitude = locations[endIndex].longitude; - destinationLocation = new SimpleCoordinates(endLatitude, endLongitude); - - step.origin = originLocation; - step.destination = destinationLocation; - step.distance = colleages[colleageIndex].distance; - step.duration = colleages[colleageIndex].duration; - step.mode = colleages[colleageIndex].mode; - step.addition = colleages[colleageIndex].addition; - - steps.push(step); - } else if (colleageIndex === -1) { - return null; +_self = function () { + function request(resource, state) { + if (!_security.request) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + if (typeof resource !== 'string' || typeof state !== 'string') { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + } + //Check resource + if (!_POWER_RESOURCE.hasOwnProperty(resource)) { + throw new WebAPIError(errorcode.INVALID_VALUES_ERR); + } + //Check state + if (!_POWER_RESOURCE[resource].STATE.hasOwnProperty(state)) { + throw new WebAPIError(errorcode.INVALID_VALUES_ERR); + } + // Exception check: SCREEN_OFF is a state cannot be requested + if (resource === "SCREEN" && state === "SCREEN_OFF") { + throw new WebAPIError(errorcode.INVALID_VALUES_ERR); + } + switch (resource) { + case "SCREEN" : + if ((_minimal_screen_state === null) || + (_minimal_screen_state === "SCREEN_DIM" && (state === "SCREEN_NORMAL" || state === "SCREEN_BRIGHT")) || + (_minimal_screen_state === "SCREEN_NORMAL" && state === "SCREEN_BRIGHT")) { + _minimal_screen_state = state; } + break; + case "CPU" : + _isCPUAwake = true; + break; + default: + break; } - - segment = new RouteSegment(); - segment.steps = steps; - result = new RouteResult(); - result.segments[0] = segment; - - return result; } - return null; -} - -// Get the shortest way by origin, destination, locations and colleages -function shortestWay(origin, destination, locations, colleages) { - return optimalWay(origin, destination, locations, colleages, distanceRelation); -} - -// Get the fastest way by origin, destination, locations and colleages -function fastestWay(origin, destination, locations, colleages) { - return optimalWay(origin, destination, locations, colleages, durationRelation); -} - -// Get the simplest way by origin, destination, locations and colleages -function simplestWay(origin, destination, locations, colleages) { - return optimalWay(origin, destination, locations, colleages, simpleRelation); -} - -// Get the most scenic way by origin, destination, locations and colleages -function mostScenicWay(origin, destination, locations, colleages) { - return optimalWay(origin, destination, locations, colleages, scenicRelation); -} - -// Get the cheapest way by origin, destination, locations and colleages -function cheapestWay(origin, destination, locations, colleages) { - return optimalWay(origin, destination, locations, colleages, cheapRelation); -} - -// Get the safest way by origin, destination, locations and colleages -function safestWay(origin, destination, locations, colleages) { - return optimalWay(origin, destination, locations, colleages, safeRelation); -} -// Uniquelize the array -function uniquelize(array) { - var temp = {}, result = [], i; - for (i = array.length; i--;) { - temp[array[i]] = array[i]; - } - for (i in temp) { - result.push(temp[i]); + function release(resource) { + switch (resource) { + case "SCREEN" : + if (_isScreenResourceOccupied) { + _isScreenResourceOccupied = false; + deviceSettings.persist("DISPLAY.brightness", _originalBrightness); + event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]); + updateResourceState(); + triggerListenerCB(ScreenState); + } + _minimal_screen_state = null; + break; + case "CPU" : + _isCPUAwake = false; + break; + default: + if (typeof resource === "string") { + throw (new WebAPIError(errorcode.INVALID_VALUES_ERR)); + } else { + throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + } + } } - return result; -} - -// Is it intersect between the Array a and b -function intersect(a, b) { - var i, j; - a = uniquelize(a); - if (a.length === 0 && b.length === 0) { - return true; + function setScreenStateChangeListener(listener) { + tizen1_utils.validateArgumentType(listener, "function", + new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); + _listeners.push(listener); } - for (i in a) { - for (j in b) { - if (a[i] === b[j]) - return true; - } + + function unsetScreenStateChangeListener() { + _listeners = []; } - return false; -} -function getConstrains(result) { - var steps = result.segments[0].steps, constrains = []; + function getScreenBrightness() { + var brightness = deviceSettings.retrieve("DISPLAY.brightness"); + return brightness; + } - utils.forEach(steps, function (item, index) { - if (item.addition.highway === "HIGHWAY") { - constrains.push("HIGHWAY"); - } - if (item.addition.toll === "TOLL") { - constrains.push("TOLL"); + function setScreenBrightness(brightness) { + if (!_security.setScreenBrightness) { + throw new WebAPIError(errorcode.SECURITY_ERR); } - if (item.addition.bridge === "BRIDGE") { - constrains.push("BRIDGE"); + if (typeof brightness !== 'number') { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); } - if (item.addition.hazardous === "HAZARDOUS") { - constrains.push("HAZARDOUS"); + if (brightness < 0 || brightness > 1) { + throw new WebAPIError(errorcode.INVALID_VALUES_ERR); } - if (item.addition.scenic === "SCENIC") { - constrains.push("SCENIC"); + if (!_isScreenResourceOccupied) { + _originalBrightness = deviceSettings.retrieve("DISPLAY.brightness"); + _isScreenResourceOccupied = true; } - }); - if (constrains.length > 0) { - return uniquelize(constrains); + deviceSettings.persist("DISPLAY.brightness", brightness); + event.trigger("DisplayBrightnessChangedByPower", [brightness]); + updateResourceState(); + triggerListenerCB(ScreenState); } - return constrains; -} - -module.exports = function (prop) { - var _self = new lbs.LocationServiceProvider(prop); - _self.find = function (origin, destination, successCallback, errorCallback, options) { - function _find() { - var locations, colleages, i, result = {}, emptyResult = [], modes = [], resultModes = [], constrains = [], resultconstrains = []; - - locations = db.retrieveObject(_data.DB_ROUTE_LOCATION_KEY); - colleages = db.retrieveObject(_data.DB_ROUTE_COLLEAGE_KEY); - - modes = options.modes; - constrains = options.constrains; - if (locations.length > 0 && colleages.length > 0) { - switch (options.routeGoal) { - case "SHORTEST": - result = shortestWay(origin, destination, locations, colleages); - break; - case "FASTEST": - result = fastestWay(origin, destination, locations, colleages); - break; + function isScreenOn() { + return _isScreenOn; + } - case "SIMPLEST": - result = simplestWay(origin, destination, locations, colleages); - break; + function restoreScreenBrightness() { + if (_isScreenResourceOccupied) { + _isScreenResourceOccupied = false; + deviceSettings.persist("DISPLAY.brightness", _originalBrightness); + event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]); + updateResourceState(); + triggerListenerCB(ScreenState); + } + } - case "MOST_SCENIC": - result = mostScenicWay(origin, destination, locations, colleages); - break; + function turnScreenOn() { + var brightness, value, flag = false; + if (!_security.turnScreenOn) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + brightness = deviceSettings.retrieve("DISPLAY.brightness"); + switch (_minimal_screen_state) { + case "SCREEN_DIM": + if (brightness <= _SCREEN_STATE.SCREEN_OFF.VALUE) { + if (!_isScreenResourceOccupied) { + _originalBrightness = brightness; + _isScreenResourceOccupied = true; + } + value = _SCREEN_STATE.SCREEN_DIM.VALUE; + flag = true; + } + break; + case "SCREEN_NORMAL": + if (brightness < _SCREEN_STATE.SCREEN_NORMAL.MIN) { + if (!_isScreenResourceOccupied) { + _originalBrightness = brightness; + _isScreenResourceOccupied = true; + } + value = _normalBrightness; + flag = true; + } + break; + case "SCREEN_BRIGHT": + if (brightness < _SCREEN_STATE.SCREEN_BRIGHT.MIN) { + if (!_isScreenResourceOccupied) { + _originalBrightness = brightness; + _isScreenResourceOccupied = true; + } + value = _SCREEN_STATE.SCREEN_BRIGHT.VALUE; + flag = true; + } + break; + } + if (flag) { + deviceSettings.persist("DISPLAY.brightness", value); + event.trigger("DisplayBrightnessChangedByPower", [value]); + updateResourceState(); + triggerListenerCB(ScreenState); + } + _isScreenOn = true; + } - case "CHEAPEST": - result = cheapestWay(origin, destination, locations, colleages); - break; + function turnScreenOff() { + if (!_security.turnScreenOff) { + throw new WebAPIError(errorcode.SECURITY_ERR); + } + _isScreenOn = false; + } - case "SAFEST": - result = safestWay(origin, destination, locations, colleages); - break; + function handleSubFeatures(subFeatures) { + var i, subFeature; - default: - result = shortestWay(origin, destination, locations, colleages); - break; - } - if (result !== null) { - for (i in result.segments[0].steps) { - resultModes.push(result.segments[0].steps[i].mode); - } - resultconstrains = getConstrains(result); - if (intersect(resultModes, modes) && intersect(resultconstrains, constrains)) { - successCallback(result); - } else { - successCallback(null); - } - } - } else { - successCallback(emptyResult); + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } } - tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); + } + + var power = { + request: request, + release: release, + setScreenStateChangeListener: setScreenStateChangeListener, + unsetScreenStateChangeListener: unsetScreenStateChangeListener, + getScreenBrightness: getScreenBrightness, + setScreenBrightness: setScreenBrightness, + isScreenOn: isScreenOn, + restoreScreenBrightness: restoreScreenBrightness, + turnScreenOn: turnScreenOn, + turnScreenOff: turnScreenOff, + handleSubFeatures : handleSubFeatures }; - return _self; + + return power; }; +initState(); +event.on("CpuLoadChanged", function (value) { + var load; + if (_isCPUAwake && Number(value) === 0) { + load = _POWER_RESOURCE.CPU.STATE.CPU_AWAKE.DEFAULT_VALUE; + deviceSettings.persist("CPU.load", load); + event.trigger("CpuLoadChangedByPower", [load]); + } +}); +event.on("DisplayBrightnessChanged", function () { + _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness"); + updateResourceState(); + triggerListenerCB(ScreenState); +}); + +module.exports = _self; + }); -define('ripple/platform/tizen/2.0/routeBackend_navigation', function (require, exports, module) { +define('ripple/platform/tizen/2.0/push', function (require, exports, module) { /* - * Copyright 2012 Intel Corporation. + * Copyright 2013 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88207,379 +90850,227 @@ define('ripple/platform/tizen/2.0/routeBackend_navigation', function (require, e * limitations under the License. */ -var utils = require('ripple/utils'), - db = require('ripple/db'), - tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), - lbs_utils = require('ripple/platform/tizen/2.0/lbs_utils'), +var event = require('ripple/event'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), + t = require('ripple/platform/tizen/2.0/typedef'), + Notification = require('ripple/platform/tizen/2.0/notification'), + StatusNotification = require('ripple/platform/tizen/2.0/StatusNotification'), WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), - SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), - RouteWaypoint, - RouteDistance, - RouteDuration, - RouteStep, - RouteSegment, - RouteRequestOptions, - RouteResultSummary, - RouteResult, - LocationServiceProvider = {}, + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), + PushMessage, _data = { - positionDistance: {}, - positionDuration: {}, - routeProvider: {}, - routes: [], - RouteDistanceUnit: ["M", "KM", "MI", "FT"], - providers: [], - path: [] - }, + service: { +/* "ID_APPLICATION_0": { + * appId: null, + * registrationId: null, + * appControl: null, + * isRegistered: false, + * isConnected: false, + * onpushed: null + * } + */ + } + }, + _security = { + "http://tizen.org/privilege/push": ["registerService", + "unregisterService", "connectService", "disconnectService", + "getRegistrationId"] + }, _self; -// The RouteWaypoint object -RouteWaypoint = function () { - return { - position: { - latitude: 0, - longitude: 0 - }, - isStopover: true - }; -}; +function _initialize() { + event.on("PushNotified", function (appId, pushMessage) { + var appService, notificationDict, statusNotification, notification; -// The RouteDistance object -RouteDistance = function () { - return { - text : "Distance", - value : "0", - unit : "KM " - }; -}; + appService = _data.service[appId]; -// The RouteDuration object -RouteDuration = function () { - return { - text : "Duration", - value : "0" // The duration in a seconds - }; -}; + if (!appService) + return; -// The RouteStep object -RouteStep = function () { - var _self = { - mode: "", // The way of the travel, for example: car, bike, foot - instruction: "", // The instruction of this step - points: [] // The points of this step - }; + if (appService.isConnected) { + appService.onpushed(new PushMessage(pushMessage)); + } else { + notificationDict = { + content: pushMessage.appData, + appControl: appService.appControl, + appId: appId + }; + statusNotification = new StatusNotification("SIMPLE", + pushMessage.alertMessage, notificationDict); + notification = new Notification(); - _self.origin = new SimpleCoordinates(0, 0); - _self.destination = new SimpleCoordinates(0, 0); - _self.distance = new RouteDistance(); - _self.duration = new RouteDuration(); + notification.post(statusNotification); + } + }); +} - return _self; -}; -// The RouteSegment object -RouteSegment = function () { - var _self = { - steps: [] - }; +function _getCurrentApplicationId() { + return "ID_APPLICATION_0"; +} - _self.origin = new SimpleCoordinates(0, 0); - _self.destination = new SimpleCoordinates(0, 0); - _self.distance = new RouteDistance(); - _self.duration = new RouteDuration(); +_self = function () { + var push; - return _self; -}; + function registerService(appControl, successCallback, errorCallback) { + var appId, appService; -// The RouteRequestOptions object -RouteRequestOptions = function () { - return { - mode: "", // CAR, BIKE - unit: "KM", - routeGoal: "SHORTEST", - constraints: ["HIGHWAY", "TOLL", "UNPAVED"], - wayPoints: [], - maxResults: 1 - }; -}; - -// The RouteResultSummary object -RouteResultSummary = function () { - var _self = {}; - - _self.origin = new SimpleCoordinates(0, 0); - _self.destination = new SimpleCoordinates(0, 0); - _self.totalDistance = new RouteDistance(); - _self.totalDuration = new RouteDuration(); - - return _self; -}; + if (!_security.registerService) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + if (!(new TypeCoerce(t.ApplicationControl)).match(appControl) || + !(new TypeCoerce(t.PushRegisterSuccessCallback)).match(successCallback) || + (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } -// The RouteResult object -RouteResult = function () { - var _self, jsonStr, jsonObj; - jsonObj = { - "type" : "Point", - "coordinates" : [] + appId = _getCurrentApplicationId(); + appService = { + appId: appId, + registrationId: null, + appControl: appControl, + isRegistered: false }; - jsonStr = JSON.stringify(jsonObj); - _self = { - segments : [], - toGeoJSON : function () { - return jsonStr; - } - }; - _self.summary = new RouteResultSummary(); - return _self; -}; - -function calcDegree(distance) { - return distance * Math.PI / 180.0; -} - -//calcute the distance -function calculateDistance(lat1, lat2, lon1, lon2) { - var R = 6371, dLat, dLon, a, c, distance; // km - dLat = calcDegree(parseFloat(lat2) - parseFloat(lat1)); - dLon = calcDegree(parseFloat(lon2) - parseFloat(lon1)); - - lat1 = calcDegree(lat1); - lat2 = calcDegree(lat2); + _data.service[appId] = appService; - a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); - c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - distance = R * c; - return distance; -} + event.trigger("PushRequest", ["REGISTER", appService], true); -function calculateDuration(mode, distance) { - var duration, v; - switch (mode) { - case "motorcar" : - v = 50; - duration = distance / v; - break; - case "bicycle" : - v = 20; - duration = distance / v; - break; - case "foot" : - v = 5; - duration = distance / v; - break; - default: - duration = 0; + if (appService.registrationId !== null) { + appService.isRegistered = true; + successCallback(appService.registrationId); + } else if (errorCallback) { + window.setTimeout(function () { + errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR)); + }, 1); + } } - return duration; -} -function optimalWay(points, mode) { - var steps = [], startLatitude, startLongitude, originLocation, endLatitude, endLongitude, - destinationLocation, step, distance, segment, result, i, routeDistance, routeDuration; - for (i = 0;i < points.length - 1;i++) { - startLatitude = points[i].lat; - startLongitude = points[i].lon; - originLocation = new SimpleCoordinates(startLatitude, startLongitude); - endLatitude = points[i + 1].lat; - endLongitude = points[i + 1].lon; - destinationLocation = new SimpleCoordinates(endLatitude, endLongitude); - step = new RouteStep(); - step.origin = originLocation; - step.destination = destinationLocation; - distance = calculateDistance(startLatitude, endLatitude, startLongitude, endLongitude); - routeDistance = new RouteDistance(); - routeDistance.value = distance; - routeDistance.unit = "km"; - step.distance = routeDistance; - routeDuration = new RouteDuration(); - routeDuration.value = calculateDuration(mode, distance); - step.duration = routeDuration; - steps.push(step); - } - return steps; -} + function unregisterService(successCallback, errorCallback) { + var appId, appService; -function existInSupports(str, array) { - for (var i in array) { - if (str === array[i]) { - return true; + if (!_security.unregisterService) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + if ((successCallback && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) || + (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback))) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + + appId = _getCurrentApplicationId(); + delete _data.service[appId]; + event.trigger("PushRequest", ["UNREGISTER", appId]); + if (successCallback) { + window.setTimeout(function () { + successCallback(); + }, 1); } } - return false; -} -function navigation(searchStr, flat, flon, tlat, tlon, v, fast) { - var positions = []; + function connectService(notificationCallback) { + var appId, appService; - _data.positionDistance = {}; - _data.positionDuration = {}; - jQuery.ajax({ - type : "get", - async : false, - url : searchStr, - data : { - flat : flat, - flon : flon, - tlat : tlat, - tlon : tlon, - v : v, - fast : fast, - layer : 'mapnik', - format : "geojson" - }, - contentType : "application/json; charset=utf-8", - dataType : "json", - cache : false, - success : function (data) { - $.each(data.coordinates, function (i, item) { - var point = {}; - point.lon = item[0]; - point.lat = item[1]; - positions.push(point); - }); - $.each(data.properties, function (i, item) { - if (typeof item === "number") { - _data.positionDistance = new RouteDistance(); - _data.positionDistance.value = item; - _data.positionDistance.unit = "km"; - _data.positionDuration = new RouteDuration(); - _data.positionDuration.value = calculateDuration(v, item); - } - }); - }, - error : function (errorCB) { - if (errorCB) { - setTimeout(function () { - errorCB(new WebAPIError(errorcode.NETWORK_ERR)); - }, 1); - } + if (!_security.connectService) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } + if (!(new TypeCoerce(t.PushNotificationCallback)).match(notificationCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - }); - return positions; -} - -function filterWaypoints(routeWaypoints) { - var mathWaypoints = [], i; - for (i in routeWaypoints) { - if (routeWaypoints[i].position.latitude !== "" && - routeWaypoints[i].position.latitude !== undefined && - routeWaypoints[i].position.latitude !== null && - routeWaypoints[i].position.longitude !== null && - routeWaypoints[i].position.longitude !== "" && - routeWaypoints[i].position.longitude !== undefined) { - mathWaypoints.push(routeWaypoints[i]); + appId = _getCurrentApplicationId(); + appService = _data.service[appId]; + if (!appService || !appService.isRegistered) { + throw new WebAPIException(errorcode.UNKNOWN_ERR); } - } - return mathWaypoints; -} -module.exports = function (prop) { - var _self = new lbs_utils.LocationServiceProvider(prop); + appService.isConnected = true; + appService.onpushed = notificationCallback; + event.trigger("PushRequest", ["CONNECT", appId]); + } - _self.supportedGoals = ["SHORTEST", "FASTEST", "MOST_SCENIC", "SIMPLEST", "CHEAPEST", "SAFEST" ]; - _self.supportedModes = ["motorcar", "bicycle", "foot"]; - _self.supportedConstraints = ["HIGHWAY", "TOLL", "UNPAVED", "BORDER", "GRAVEL_PAVING", "TUNNEL", "BRIDGE", "LEFT_TURN", "CARPOOL", "HAZARDOUS_CARGO" ]; - _self.supportsWayPoints = true; - _self.find = function (origin, destination, successCallback, errorCallback, options) { - function _find() { - var flat, flon, tlat, tlon, v, fast, layer, mapnik, format, searchStr, mode, result, - points = [], - routeWaypoints = [], - segmentPositions = [], - positions = [], - segments = [], - totalDistances = 0, totalDurations = 0, - k, key, segment, startPosition, endPosition, - summary, distance, duration; + function disconnectService() { + var appId, appService; - v = options.mode; - //init - if (!existInSupports(v, _self.supportedModes)) { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } - if (!existInSupports(options.routeGoal, _self.supportedGoals)) { - throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); - } - switch (options.routeGoal) { - case "SHORTEST": - fast = 0; - break; + if (!_security.disconnectService) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } - case "FASTEST": - fast = 1; - break; + appId = _getCurrentApplicationId(); + appService = _data.service[appId]; + if (!appService || !appService.isRegistered) { + throw new WebAPIException(errorcode.UNKNOWN_ERR); + } + if (!appService.isConnected) { + return; + } - case "SIMPLEST": - break; + appService.onpushed = null; + appService.isConnected = false; + event.trigger("PushRequest", ["DISCONNECT", appId]); + } - case "MOST_SCENIC": - break; + function getRegistrationId() { + var appService; - case "CHEAPEST": - break; + if (!_security.getRegistrationId) { + throw new WebAPIException(errorcode.SECURITY_ERR); + } - case "SAFEST": - break; + appService = _data.service[_getCurrentApplicationId()]; + if (!appService || !appService.isRegistered) { + return null; + } - default: - fast = 0; - } - searchStr = "http://www.yournavigation.org/api/dev/gosmore.php"; - routeWaypoints = options.wayPoints; - routeWaypoints = filterWaypoints(routeWaypoints); - segmentPositions.push(origin); + return appService.registrationId; + } - if (routeWaypoints.length > 0) { - for (k in routeWaypoints) { - segmentPositions.push(routeWaypoints[k].position); - } - } - segmentPositions.push(destination); + function handleSubFeatures(subFeatures) { + var i, subFeature; - for (key = 0; key < segmentPositions.length - 1; key++) { - segment = new RouteSegment(); - startPosition = segmentPositions[key]; - endPosition = segmentPositions[key + 1]; - segment.origin = startPosition; - segment.destination = endPosition; - flat = startPosition.latitude; - flon = startPosition.longitude; - tlat = endPosition.latitude; - tlon = endPosition.longitude; - positions = navigation(searchStr, flat, flon, tlat, tlon, v, fast); - segment.steps = optimalWay(positions, v); - segment.distance = _data.positionDistance; - totalDistances += _data.positionDistance.value; - segment.duration = _data.positionDuration; - totalDurations += _data.positionDuration.value; - segments.push(segment); + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - result = new RouteResult(); - summary = new RouteResultSummary(); - summary.origin = segmentPositions[0]; - summary.destination = segmentPositions[segmentPositions.length - 1]; - distance = new RouteDistance(); - distance.value = totalDistances; - distance.unit = "km"; - summary.totalDistance = distance; - duration = new RouteDuration(); - duration.value = totalDurations; - summary.totalDuration = duration; - result.segments = segments; - result.summary = summary; - successCallback(result); } + } - tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); + push = { + registerService: registerService, + unregisterService: unregisterService, + connectService: connectService, + disconnectService: disconnectService, + getRegistrationId: getRegistrationId, + handleSubFeatures: handleSubFeatures }; - return _self; + return push; +}; + +_initialize(); + +PushMessage = function (pushMessageInitDict) { + var appData, alertMessage, date; + + this.__defineGetter__("appData", function () { + return appData; + }); + + this.__defineGetter__("alertMessage", function () { + return alertMessage; + }); + + this.__defineGetter__("date", function () { + return date; + }); + + appData = pushMessageInitDict.appData || ""; + alertMessage = pushMessageInitDict.alertMessage || ""; + date = pushMessageInitDict.date || new Date(); }; +module.exports = _self; + }); -define('ripple/platform/tizen/2.0/sensors', function (require, exports, module) { +define('ripple/platform/tizen/2.0/route', function (require, exports, module) { /* * Copyright 2012 Intel Corporation. * @@ -88596,104 +91087,39 @@ define('ripple/platform/tizen/2.0/sensors', function (require, exports, module) * limitations under the License. */ -var utils = require('ripple/utils'), - sensors = require('ripple/platform/tizen/2.0/spec/sensor'), - _sensors = ["Accelerometer", "MagneticField", "Rotation", "Orientation"], - _permission = true, - _isWriteable = false, +var errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), + ProviderNominatim = require('ripple/platform/tizen/2.0/routeBackend_navigation'), // navigation route service + _getProviders, + _providers, _self; -function SensorError(code, msg) { - this.__defineGetter__("message", function () { - return msg; - }); - this.__defineGetter__("code", function () { - return code; - }); - - this.PERMISSION_DENIED = -100; +function _initialize() { + _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})]; } -function SensorRequest() { - var _self = { - result: [], - error: null, - readyState: "processing" - }; - - this.__defineGetter__("result", function () { - return _self.result; - }); - this.__defineSetter__("result", function (resultData) { - if (_isWriteable) { - _self.result = utils.copy(resultData); - _isWriteable = false; - return; - } - }); +_initialize(); - this.__defineGetter__("error", function () { - return _self.error; - }); - this.__defineSetter__("error", function (errorData) { - if (_isWriteable) { - _self.error = utils.copy(errorData); - _isWriteable = false; - return; +_self = { + getDefaultProvider : function () { + if (arguments.length !== 0) { + throw (new WebAPIError(errorcode.INVALID_VALUES_ERR)); } - }); - - this.__defineGetter__("readyState", function () { - return _self.readyState; - }); - this.__defineSetter__("readyState", function (readyStateData) { - if (_isWriteable) { - _self.readyState = readyStateData; - _isWriteable = false; - return; + return _providers[0]; + }, + getProviders : function () { + if (arguments.length !== 0) { + throw (new WebAPIError(errorcode.INVALID_VALUES_ERR)); } - }); -} - -_self = { - findSensors: function (type) { - var sensorRequest = new SensorRequest(), index, sensorName = ""; - - setTimeout(function () { - if (_permission) { - for (index = 0; index < _sensors.length; index++) { - sensorName = _sensors[index]; - if (type === null || type === undefined || type === sensorName) { - _isWriteable = true; - sensorRequest.result.push(sensors[sensorName]); - } - } - - _isWriteable = true; - sensorRequest.readyState = "done"; - - if (sensorRequest.onsuccess) { - sensorRequest.onsuccess(); - } - } - else { - // error event on the request with error code PERMISSION_DENIED must be fired. - sensorRequest.error = new SensorError(-100, "permission denied!"); - if (sensorRequest.onerror) { - sensorRequest.onerror(); - } - } - }, 1); - - return sensorRequest; + return _providers; } }; module.exports = _self; - }); -define('ripple/platform/tizen/2.0/spec/btdevices', function (require, exports, module) { +define('ripple/platform/tizen/2.0/routeBackend_local', function (require, exports, module) { /* * Copyright 2012 Intel Corporation. * @@ -88710,79 +91136,532 @@ define('ripple/platform/tizen/2.0/spec/btdevices', function (require, exports, m * limitations under the License. */ -module.exports = { - "22:33:44:12:34:56": { - "name": "Tizen Phone", - "address": "22:33:44:12:34:56", - "deviceClass": { - "major": 0x02, - "majorName": "PHONE", - "minor": 0x03, - "minorName": "PHONE_SMARTPHONE", - "services": [0x0080], - "servicesName": ["OBJECT_TRANSFER"] - }, - "isTrusted": false, - "services": { - "5bce9431-6c75-32ab-afe0-2ec108a30860" : { - "name": "Data Exchange", - "uuid": "5bce9431-6c75-32ab-afe0-2ec108a30860", - "protocol": "RFCOMM" - }, - "3537d485-0c1e-445a-a066-43fafcfb61d1" : { - "name": "Data Transfer", - "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1", - "protocol": "RFCOMM" - } - } +var db = require('ripple/db'), + utils = require('ripple/utils'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), + tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), + lbs = require('ripple/platform/tizen/2.0/lbs'), + LocationServiceProvider = {}, + RouteWaypoint, + RouteDistance, + RouteDuration, + RouteStep, + RouteSegment, + RouteRequestOptions, + RouteResultSummary, + RouteResult, + _data = { + DB_ROUTE_LOCATION_KEY: "tizen1-db-route", + DB_ROUTE_COLLEAGE_KEY: "tizen2-db-route", + routeProvider: {}, + routes: [], + RouteDistanceUnit: ["M", "KM", "MI", "FT"], + providers: [], + path: [] }, - "22:33:44:12:34:88": { - "name": "Keyboard", - "address": "22:33:44:12:34:88", - "deviceClass": { - "major": 0x05, - "majorName": "PERIPHERAL", - "minor": 0x10, - "minorName": "PERIPHERAL_KEYBOARD", - "services": [0x0080], - "servicesName": ["OBJECT_TRANSFER"] + _self; + +// The RouteWaypoint object +RouteWaypoint = function () { + return { + position: { + latitude: 0, + longitude: 0 }, - "isTrusted": true, - "services": { - "3537d485-0c1e-445a-a066-43fafcfb61d1" : { - "name": "Data Exchange", - "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1", - "protocol": "RFCOMM" + isStopover: true + }; +}; + +// The RouteDistance object +RouteDistance = function () { + return { + text: "", + value: 0, + unit: "KM" + }; +}; + +// The RouteDuration object +RouteDuration = function () { + return { + text: "", + value: 0 // The duration in a seconds + }; +}; + +// The RouteStep object +RouteStep = function () { + var _self = { + mode: "", // The way of the travel, for example: car, bike, foot + instruction: "", // The instruction of this step + points: [] // The points of this step + }; + + _self.origin = new SimpleCoordinates(0, 0); + _self.destination = new SimpleCoordinates(0, 0); + _self.distance = new RouteDistance(); + _self.duration = new RouteDuration(); + + return _self; +}; + +// The RouteSegment object +RouteSegment = function () { + var _self = { + steps: [] + }; + + _self.origin = new SimpleCoordinates(0, 0); + _self.destination = new SimpleCoordinates(0, 0); + _self.distance = new RouteDistance(); + _self.duration = new RouteDuration(); + + return _self; +}; + +// The RouteRequestOptions object +RouteRequestOptions = function () { + return { + mode: "", // CAR, BIKE + unit: "KM", + routeGoal: "SHORTEST", + constraints: ["HIGHWAY", "TOLL", "UNPAVED"], + wayPoints: [], + maxResults: 1 + }; +}; + +// The RouteResultSummary object +RouteResultSummary = function () { + var _self = {}; + + _self.origin = new SimpleCoordinates(0, 0); + _self.destination = new SimpleCoordinates(0, 0); + _self.totalDistance = new RouteDistance(); + _self.totalDuration = new RouteDuration(); + + return _self; +}; + +// The RouteResult object +RouteResult = function () { + var _self = { + segments: [] + }; + + _self.summary = new RouteResultSummary(); + + return _self; +}; + +// Floyd arithmetic in Mathematics, solving the optimal way +function floyd(e, n, startIndex, endIndex) { + var MAX = Infinity, + a = new Array(n), i, j, k, p = new Array(n), + paths, pathWay = []; + + for (i = 1; i < n + 1; i++) { + a[i] = new Array(n); + } + for (i = 1; i < n + 1; i++) { + p[i] = new Array(n); + } + for (i = 1; i < n + 1; i++) { + for (j = 1; j < n + 1; j++) { + if (i === j || e[i][j] === "MIN") { + a[i][j] = 0; + } else if (e[i][j] !== 0 && e[i][j] !== "MIN") { + a[i][j] = e[i][j]; + } else { + a[i][j] = MAX; } + p[i][j] = 0; } - }, - "22:33:44:88:34:58": { - "name": "Tizen Laptop", - "address": "22:33:44:88:34:58", - "deviceClass": { - "major": 0x01, - "majorName": "COMPUTER", - "minor": 0x03, - "minorName": "COMPUTER_LAPTOP", - "services": [0x0080], - "servicesName": ["OBJECT_TRANSFER"] - }, - "isTrusted": true, - "services": { - "3537d485-0c1e-445a-a066-43fafcfb61d1" : { - "name": "Data Exchange", - "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1", - "protocol": "RFCOMM" + } + for (i = 1; i < n + 1; i++) { + a[i][i] = 0; + } + for (k = 1; k < n + 1; k++) { + for (i = 1; i < n + 1; i++) { + for (j = 1; j < n + 1; j++) { + if (parseInt(a[i][k], 10) + parseInt(a[k][j], 10) < a[i][j]) { + a[i][j] = parseInt(a[i][k], 10) + parseInt(a[k][j], 10); + p[i][j] = k; + } + } + } + } + _data.path = []; + paths = findPath(startIndex, endIndex, p); + pathWay = []; + pathWay.push(startIndex); + for (i = 0; i < paths.length; i++) { + pathWay.push(paths[i]); + } + pathWay.push(endIndex); + + return pathWay; +} + +// Find the best way in the locations +function findPath(i, j, p) { + var k = p[i][j]; + + if (k === 0 || i === j) { + return _data.path; + } + findPath(i, k, p); + _data.path.push(k); + + return findPath(k, j, p); +} + +// Find the index in the locations by string +function findIndexByStr(str, locations) { + for (var i in locations) { + if (locations[i].name === str) { + return parseInt(i, 10) + 1; + } + } + return -1; +} + +// Find the index in the colleages by name1 and name2 +function findValueByStr(start, end, locations, colleages) { + for (var i in colleages) { + if (colleages[i].name1 === locations[start - 1].name && colleages[i].name2 === locations[end - 1].name) { + return parseInt(i, 10); + } else if (colleages[i].name2 === locations[start - 1].name && colleages[i].name1 === locations[end - 1].name) { + return parseInt(i, 10); + } + } + return -1; +} + +// Find the index in the locations by latitude and longitude +function searchIndexBycoodinates(latitude, longitude, locations) { + if (latitude !== null && longitude !== null) { + for (var i in locations) { + if (locations[i].latitude === latitude && locations[i].longitude === longitude) { + return parseInt(i, 10) + 1; + } + } + } + return -1; +} + +// Get the relation among the locations +function getRelation(n, colleages, locations, goal) { + var i, j, start, end, relation = new Array(n + 1); + for (i = 1; i < n + 2; i++) { + relation[i] = new Array(n + 1); + } + for (i = 1; i < n + 1; i++) { + for (j = 1; j < n + 1; j++) { + relation[i][j] = 0; + } + } + for (i in colleages) { + start = findIndexByStr(colleages[i].name1, locations); + end = findIndexByStr(colleages[i].name2, locations); + if (start !== -1 && end !== -1 && start !== end) { + switch (goal) { + case "distance": + relation[start][end] = colleages[i].distance; + relation[end][start] = colleages[i].distance; + break; + + case "duration": + relation[start][end] = colleages[i].duration; + relation[end][start] = colleages[i].duration; + break; + + case "simple": + relation[start][end] = 1; + relation[end][start] = 1; + break; + + case "scenic": + if (colleages[i].addition.scenic === "SCENIC") { + relation[start][end] = 1; + relation[start][end] = 1; + } else if (colleages[i].addition.scenic === "") { + relation[start][end] = "MIN"; + relation[start][end] = "MIN"; + } + break; + + case "cheap": + if (colleages[i].addition.toll === "TOLL") { + relation[start][end] = 1; + relation[end][start] = 1; + } else if (colleages[i].addition.toll === "") { + relation[start][end] = "MIN"; + relation[start][end] = "MIN"; + } + break; + + case "safe": + if (colleages[i].addition.hazardous === "HAZARDOUS") { + relation[start][end] = 1; + relation[end][start] = 1; + } else if (colleages[i].addition.hazardous === "") { + relation[start][end] = "MIN"; + relation[end][start] = "MIN"; + } + break; + + default: + return null; + } + } + } + + return relation; +} + +// Get the distance relationship among the locations +function distanceRelation(n, colleages, locations) { + return getRelation(n, colleages, locations, "distance"); +} + +// Get the duration relationship among the locations +function durationRelation(n, colleages, locations) { + return getRelation(n, colleages, locations, "duration"); +} + +// Get the simple relationship among the locations +function simpleRelation(n, colleages, locations) { + return getRelation(n, colleages, locations, "simple"); +} + +// Get the cheap relationship among the locations +function cheapRelation(n, colleages, locations) { + return getRelation(n, colleages, locations, "cheap"); +} + +// Get the safe relationship among the locations +function safeRelation(n, colleages, locations) { + return getRelation(n, colleages, locations, "safe"); +} + +// Get the scenic relationship among the locations +function scenicRelation(n, colleages, locations) { + return getRelation(n, colleages, locations, "scenic"); +} + +// Get the shortest way by origin, destination, locations and colleages +function optimalWay(origin, destination, locations, colleages, relation) { + var n = locations.length, i, steps = [], step, relations, routeLocations, + originIndex, destinationIndex, startIndex, endIndex, colleageIndex, + originLatitude, originLongitude, destinationLatitude, destinationLongitude, + startLatitude, startLongitude, endLatitude, endLongitude, + originLocation, destinationLocation, segment, result; + + originLatitude = origin.latitude; + originLongitude = origin.longitude; + originIndex = searchIndexBycoodinates(originLatitude, originLongitude, locations); + + destinationLatitude = destination.latitude; + destinationLongitude = destination.longitude; + destinationIndex = searchIndexBycoodinates(destinationLatitude, destinationLongitude, locations); + + relations = relation(n, colleages, locations); + + if (originIndex !== -1 && destinationIndex !== -1) { + routeLocations = floyd(relations, n, parseInt(originIndex, 10), parseInt(destinationIndex, 10)); + + for (i = 0; i < routeLocations.length - 1; i++) { + colleageIndex = findValueByStr(routeLocations[i], routeLocations[i + 1], locations, colleages); + + if (colleageIndex !== -1) { + step = new RouteStep(); + startIndex = parseInt(routeLocations[i], 10) - 1; + endIndex = parseInt(routeLocations[i + 1], 10) - 1; + + startLatitude = locations[startIndex].latitude; + startLongitude = locations[startIndex].longitude; + originLocation = new SimpleCoordinates(startLatitude, startLongitude); + + endLatitude = locations[endIndex].latitude; + endLongitude = locations[endIndex].longitude; + destinationLocation = new SimpleCoordinates(endLatitude, endLongitude); + + step.origin = originLocation; + step.destination = destinationLocation; + step.distance = colleages[colleageIndex].distance; + step.duration = colleages[colleageIndex].duration; + step.mode = colleages[colleageIndex].mode; + step.addition = colleages[colleageIndex].addition; + + steps.push(step); + } else if (colleageIndex === -1) { + return null; } } + + segment = new RouteSegment(); + segment.steps = steps; + result = new RouteResult(); + result.segments[0] = segment; + + return result; + } + return null; +} + +// Get the shortest way by origin, destination, locations and colleages +function shortestWay(origin, destination, locations, colleages) { + return optimalWay(origin, destination, locations, colleages, distanceRelation); +} + +// Get the fastest way by origin, destination, locations and colleages +function fastestWay(origin, destination, locations, colleages) { + return optimalWay(origin, destination, locations, colleages, durationRelation); +} + +// Get the simplest way by origin, destination, locations and colleages +function simplestWay(origin, destination, locations, colleages) { + return optimalWay(origin, destination, locations, colleages, simpleRelation); +} + +// Get the most scenic way by origin, destination, locations and colleages +function mostScenicWay(origin, destination, locations, colleages) { + return optimalWay(origin, destination, locations, colleages, scenicRelation); +} + +// Get the cheapest way by origin, destination, locations and colleages +function cheapestWay(origin, destination, locations, colleages) { + return optimalWay(origin, destination, locations, colleages, cheapRelation); +} + +// Get the safest way by origin, destination, locations and colleages +function safestWay(origin, destination, locations, colleages) { + return optimalWay(origin, destination, locations, colleages, safeRelation); +} + +// Uniquelize the array +function uniquelize(array) { + var temp = {}, result = [], i; + for (i = array.length; i--;) { + temp[array[i]] = array[i]; + } + for (i in temp) { + result.push(temp[i]); + } + return result; +} + +// Is it intersect between the Array a and b +function intersect(a, b) { + var i, j; + + a = uniquelize(a); + if (a.length === 0 && b.length === 0) { + return true; + } + for (i in a) { + for (j in b) { + if (a[i] === b[j]) + return true; + } + } + return false; +} + +function getConstrains(result) { + var steps = result.segments[0].steps, constrains = []; + + utils.forEach(steps, function (item, index) { + if (item.addition.highway === "HIGHWAY") { + constrains.push("HIGHWAY"); + } + if (item.addition.toll === "TOLL") { + constrains.push("TOLL"); + } + if (item.addition.bridge === "BRIDGE") { + constrains.push("BRIDGE"); + } + if (item.addition.hazardous === "HAZARDOUS") { + constrains.push("HAZARDOUS"); + } + if (item.addition.scenic === "SCENIC") { + constrains.push("SCENIC"); + } + }); + if (constrains.length > 0) { + return uniquelize(constrains); } + return constrains; +} + +module.exports = function (prop) { + var _self = new lbs.LocationServiceProvider(prop); + _self.find = function (origin, destination, successCallback, errorCallback, options) { + function _find() { + var locations, colleages, i, result = {}, emptyResult = [], modes = [], resultModes = [], constrains = [], resultconstrains = []; + + locations = db.retrieveObject(_data.DB_ROUTE_LOCATION_KEY); + colleages = db.retrieveObject(_data.DB_ROUTE_COLLEAGE_KEY); + + modes = options.modes; + constrains = options.constrains; + if (locations.length > 0 && colleages.length > 0) { + switch (options.routeGoal) { + case "SHORTEST": + result = shortestWay(origin, destination, locations, colleages); + break; + + case "FASTEST": + result = fastestWay(origin, destination, locations, colleages); + break; + + case "SIMPLEST": + result = simplestWay(origin, destination, locations, colleages); + break; + + case "MOST_SCENIC": + result = mostScenicWay(origin, destination, locations, colleages); + break; + + case "CHEAPEST": + result = cheapestWay(origin, destination, locations, colleages); + break; + + case "SAFEST": + result = safestWay(origin, destination, locations, colleages); + break; + + default: + result = shortestWay(origin, destination, locations, colleages); + break; + } + if (result !== null) { + for (i in result.segments[0].steps) { + resultModes.push(result.segments[0].steps[i].mode); + } + resultconstrains = getConstrains(result); + if (intersect(resultModes, modes) && intersect(resultconstrains, constrains)) { + successCallback(result); + } else { + successCallback(null); + } + } + } else { + successCallback(emptyResult); + } + } + tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); + }; + return _self; }; }); -define('ripple/platform/tizen/2.0/spec/config', function (require, exports, module) { +define('ripple/platform/tizen/2.0/routeBackend_navigation', function (require, exports, module) { /* - * Copyright 2011 Research In Motion Limited. - * Copyright 2011 Intel Corporation. + * Copyright 2012 Intel Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88796,1647 +91675,10651 @@ define('ripple/platform/tizen/2.0/spec/config', function (require, exports, modu * See the License for the specific language governing permissions and * limitations under the License. */ -var utils = require('ripple/utils'), - db = require('ripple/db'), - constants = require('ripple/constants'); -module.exports = { - fileName: "config.xml", - validateVersion: function (configValidationObject) { - var valid = true; - // no xmlns:JIL in wac 2.0 spec +var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), + lbs_utils = require('ripple/platform/tizen/2.0/lbs_utils'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), + SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'), + RouteWaypoint, + RouteDistance, + RouteDuration, + RouteStep, + RouteSegment, + RouteRequestOptions, + RouteResultSummary, + RouteResult, + _data = { + positionDistance: {}, + positionDuration: {}, + routeProvider: {}, + routes: [], + RouteDistanceUnit: ["M", "KM", "MI", "FT"], + providers: [], + path: [] + }, + _self; + +// The RouteWaypoint object +RouteWaypoint = function () { + return { + position: { + latitude: 0, + longitude: 0 + }, + isStopover: true + }; +}; + +// The RouteDistance object +RouteDistance = function () { + return { + text : "Distance", + value : "0", + unit : "KM " + }; +}; + +// The RouteDuration object +RouteDuration = function () { + return { + text : "Duration", + value : "0" // The duration in a seconds + }; +}; + +// The RouteStep object +RouteStep = function () { + var _self = { + mode: "", // The way of the travel, for example: car, bike, foot + instruction: "", // The instruction of this step + points: [] // The points of this step + }; + + _self.origin = new SimpleCoordinates(0, 0); + _self.destination = new SimpleCoordinates(0, 0); + _self.distance = new RouteDistance(); + _self.duration = new RouteDuration(); + + return _self; +}; +// The RouteSegment object +RouteSegment = function () { + var _self = { + steps: [] + }; + + _self.origin = new SimpleCoordinates(0, 0); + _self.destination = new SimpleCoordinates(0, 0); + _self.distance = new RouteDistance(); + _self.duration = new RouteDuration(); + + return _self; +}; + +// The RouteRequestOptions object +RouteRequestOptions = function () { + return { + mode: "", // CAR, BIKE + unit: "KM", + routeGoal: "SHORTEST", + constraints: ["HIGHWAY", "TOLL", "UNPAVED"], + wayPoints: [], + maxResults: 1 + }; +}; + +// The RouteResultSummary object +RouteResultSummary = function () { + var _self = {}; + + _self.origin = new SimpleCoordinates(0, 0); + _self.destination = new SimpleCoordinates(0, 0); + _self.totalDistance = new RouteDistance(); + _self.totalDuration = new RouteDuration(); + + return _self; +}; + +// The RouteResult object +RouteResult = function () { + var _self, jsonStr, jsonObj; + jsonObj = { + "type" : "Point", + "coordinates" : [] + }; + jsonStr = JSON.stringify(jsonObj); + _self = { + segments : [], + toGeoJSON : function () { + return jsonStr; + } + }; + _self.summary = new RouteResultSummary(); + return _self; +}; + +function calcDegree(distance) { + return distance * Math.PI / 180.0; +} + +//calcute the distance +function calculateDistance(lat1, lat2, lon1, lon2) { + var R = 6371, dLat, dLon, a, c, distance; // km + dLat = calcDegree(parseFloat(lat2) - parseFloat(lat1)); + dLon = calcDegree(parseFloat(lon2) - parseFloat(lon1)); + + lat1 = calcDegree(lat1); + lat2 = calcDegree(lat2); + + a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); + c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + distance = R * c; + return distance; +} + +function calculateDuration(mode, distance) { + var duration, v; + switch (mode) { + case "motorcar" : + v = 50; + duration = distance / v; + break; + case "bicycle" : + v = 20; + duration = distance / v; + break; + case "foot" : + v = 5; + duration = distance / v; + break; + default: + duration = 0; + } + return duration; +} + +function optimalWay(points, mode) { + var steps = [], startLatitude, startLongitude, originLocation, endLatitude, endLongitude, + destinationLocation, step, distance, i, routeDistance, routeDuration; + for (i = 0;i < points.length - 1;i++) { + startLatitude = points[i].lat; + startLongitude = points[i].lon; + originLocation = new SimpleCoordinates(startLatitude, startLongitude); + endLatitude = points[i + 1].lat; + endLongitude = points[i + 1].lon; + destinationLocation = new SimpleCoordinates(endLatitude, endLongitude); + step = new RouteStep(); + step.origin = originLocation; + step.destination = destinationLocation; + distance = calculateDistance(startLatitude, endLatitude, startLongitude, endLongitude); + routeDistance = new RouteDistance(); + routeDistance.value = distance; + routeDistance.unit = "km"; + step.distance = routeDistance; + routeDuration = new RouteDuration(); + routeDuration.value = calculateDuration(mode, distance); + step.duration = routeDuration; + steps.push(step); + } + return steps; +} + +function existInSupports(str, array) { + for (var i in array) { + if (str === array[i]) { + return true; + } + } + return false; +} + +function navigation(searchStr, flat, flon, tlat, tlon, v, fast) { + var positions = []; + + _data.positionDistance = {}; + _data.positionDuration = {}; + jQuery.ajax({ + type : "get", + async : false, + url : searchStr, + data : { + flat : flat, + flon : flon, + tlat : tlat, + tlon : tlon, + v : v, + fast : fast, + layer : 'mapnik', + format : "geojson" + }, + contentType : "application/json; charset=utf-8", + dataType : "json", + cache : false, + success : function (data) { + $.each(data.coordinates, function (i, item) { + var point = {}; + point.lon = item[0]; + point.lat = item[1]; + positions.push(point); + }); + $.each(data.properties, function (i, item) { + if (typeof item === "number") { + _data.positionDistance = new RouteDistance(); + _data.positionDistance.value = item; + _data.positionDistance.unit = "km"; + _data.positionDuration = new RouteDuration(); + _data.positionDuration.value = calculateDuration(v, item); + } + }); + }, + error : function (errorCB) { + if (errorCB) { + setTimeout(function () { + errorCB(new WebAPIError(errorcode.NETWORK_ERR)); + }, 1); + } + } + }); + return positions; +} + + +function filterWaypoints(routeWaypoints) { + var mathWaypoints = [], i; + for (i in routeWaypoints) { + if (routeWaypoints[i].position.latitude !== "" && + routeWaypoints[i].position.latitude !== undefined && + routeWaypoints[i].position.latitude !== null && + routeWaypoints[i].position.longitude !== null && + routeWaypoints[i].position.longitude !== "" && + routeWaypoints[i].position.longitude !== undefined) { + mathWaypoints.push(routeWaypoints[i]); + } + } + return mathWaypoints; +} + +module.exports = function (prop) { + var _self = new lbs_utils.LocationServiceProvider(prop); + + _self.supportedGoals = ["SHORTEST", "FASTEST", "MOST_SCENIC", "SIMPLEST", "CHEAPEST", "SAFEST" ]; + _self.supportedModes = ["motorcar", "bicycle", "foot"]; + _self.supportedConstraints = ["HIGHWAY", "TOLL", "UNPAVED", "BORDER", "GRAVEL_PAVING", "TUNNEL", "BRIDGE", "LEFT_TURN", "CARPOOL", "HAZARDOUS_CARGO" ]; + _self.supportsWayPoints = true; + _self.find = function (origin, destination, successCallback, errorCallback, options) { + function _find() { + var flat, flon, tlat, tlon, v, fast, searchStr, result, + routeWaypoints = [], + segmentPositions = [], + positions = [], + segments = [], + totalDistances = 0, totalDurations = 0, + k, key, segment, startPosition, endPosition, + summary, distance, duration; + + v = options.mode; + //init + if (!existInSupports(v, _self.supportedModes)) { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + } + if (!existInSupports(options.routeGoal, _self.supportedGoals)) { + throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR); + } + switch (options.routeGoal) { + case "SHORTEST": + fast = 0; + break; + + case "FASTEST": + fast = 1; + break; + + case "SIMPLEST": + break; + + case "MOST_SCENIC": + break; + + case "CHEAPEST": + break; + + case "SAFEST": + break; + + default: + fast = 0; + } + searchStr = "http://www.yournavigation.org/api/dev/gosmore.php"; + routeWaypoints = options.wayPoints; + routeWaypoints = filterWaypoints(routeWaypoints); + segmentPositions.push(origin); + + if (routeWaypoints.length > 0) { + for (k in routeWaypoints) { + segmentPositions.push(routeWaypoints[k].position); + } + } + segmentPositions.push(destination); + + for (key = 0; key < segmentPositions.length - 1; key++) { + segment = new RouteSegment(); + startPosition = segmentPositions[key]; + endPosition = segmentPositions[key + 1]; + segment.origin = startPosition; + segment.destination = endPosition; + flat = startPosition.latitude; + flon = startPosition.longitude; + tlat = endPosition.latitude; + tlon = endPosition.longitude; + positions = navigation(searchStr, flat, flon, tlat, tlon, v, fast); + segment.steps = optimalWay(positions, v); + segment.distance = _data.positionDistance; + totalDistances += _data.positionDistance.value; + segment.duration = _data.positionDuration; + totalDurations += _data.positionDuration.value; + segments.push(segment); + } + result = new RouteResult(); + summary = new RouteResultSummary(); + summary.origin = segmentPositions[0]; + summary.destination = segmentPositions[segmentPositions.length - 1]; + distance = new RouteDistance(); + distance.value = totalDistances; + distance.unit = "km"; + summary.totalDistance = distance; + duration = new RouteDuration(); + duration.value = totalDurations; + summary.totalDuration = duration; + result.segments = segments; + result.summary = summary; + successCallback(result); + } + + tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find); + }; + + return _self; +}; + +}); +define('ripple/platform/tizen/2.0/sensors', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var utils = require('ripple/utils'), + sensors = require('ripple/platform/tizen/2.0/spec/sensor'), + _sensors = ["Accelerometer", "MagneticField", "Rotation", "Orientation"], + _permission = true, + _isWriteable = false, + _self; + +function SensorError(code, msg) { + this.__defineGetter__("message", function () { + return msg; + }); + this.__defineGetter__("code", function () { + return code; + }); + + this.PERMISSION_DENIED = -100; +} + +function SensorRequest() { + var _self = { + result: [], + error: null, + readyState: "processing" + }; + + this.__defineGetter__("result", function () { + return _self.result; + }); + this.__defineSetter__("result", function (resultData) { + if (_isWriteable) { + _self.result = utils.copy(resultData); + _isWriteable = false; + return; + } + }); + + this.__defineGetter__("error", function () { + return _self.error; + }); + this.__defineSetter__("error", function (errorData) { + if (_isWriteable) { + _self.error = utils.copy(errorData); + _isWriteable = false; + return; + } + }); + + this.__defineGetter__("readyState", function () { + return _self.readyState; + }); + this.__defineSetter__("readyState", function (readyStateData) { + if (_isWriteable) { + _self.readyState = readyStateData; + _isWriteable = false; + return; + } + }); +} + +_self = { + findSensors: function (type) { + var sensorRequest = new SensorRequest(), index, sensorName = ""; + + setTimeout(function () { + if (_permission) { + for (index = 0; index < _sensors.length; index++) { + sensorName = _sensors[index]; + if (type === null || type === undefined || type === sensorName) { + _isWriteable = true; + sensorRequest.result.push(sensors[sensorName]); + } + } + + _isWriteable = true; + sensorRequest.readyState = "done"; + + if (sensorRequest.onsuccess) { + sensorRequest.onsuccess(); + } + } + else { + // error event on the request with error code PERMISSION_DENIED must be fired. + sensorRequest.error = new SensorError(-100, "permission denied!"); + if (sensorRequest.onerror) { + sensorRequest.onerror(); + } + } + }, 1); + + return sensorRequest; + } +}; + +module.exports = _self; + + +}); +define('ripple/platform/tizen/2.0/spec/btdevices', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + "22:33:44:12:34:56": { + "name": "Tizen Phone", + "address": "22:33:44:12:34:56", + "deviceClass": { + "major": 0x02, + "majorName": "PHONE", + "minor": 0x03, + "minorName": "PHONE_SMARTPHONE", + "services": [0x0080], + "servicesName": ["OBJECT_TRANSFER"] + }, + "isTrusted": false, + "services": { + "5bce9431-6c75-32ab-afe0-2ec108a30860" : { + "name": "Data Exchange", + "uuid": "5bce9431-6c75-32ab-afe0-2ec108a30860", + "protocol": "RFCOMM" + }, + "3537d485-0c1e-445a-a066-43fafcfb61d1" : { + "name": "Data Transfer", + "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1", + "protocol": "RFCOMM" + } + } + }, + "22:33:44:12:34:88": { + "name": "Keyboard", + "address": "22:33:44:12:34:88", + "deviceClass": { + "major": 0x05, + "majorName": "PERIPHERAL", + "minor": 0x10, + "minorName": "PERIPHERAL_KEYBOARD", + "services": [0x0080], + "servicesName": ["OBJECT_TRANSFER"] + }, + "isTrusted": true, + "services": { + "3537d485-0c1e-445a-a066-43fafcfb61d1" : { + "name": "Data Exchange", + "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1", + "protocol": "RFCOMM" + } + } + }, + "22:33:44:88:34:58": { + "name": "Tizen Laptop", + "address": "22:33:44:88:34:58", + "deviceClass": { + "major": 0x01, + "majorName": "COMPUTER", + "minor": 0x03, + "minorName": "COMPUTER_LAPTOP", + "services": [0x0080], + "servicesName": ["OBJECT_TRANSFER"] + }, + "isTrusted": true, + "services": { + "3537d485-0c1e-445a-a066-43fafcfb61d1" : { + "name": "Data Exchange", + "uuid": "3537d485-0c1e-445a-a066-43fafcfb61d1", + "protocol": "RFCOMM" + } + } + } +}; + +}); +define('ripple/platform/tizen/2.0/spec/config', function (require, exports, module) { +/* + * Copyright 2011 Research In Motion Limited. + * Copyright 2011 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var utils = require('ripple/utils'), + db = require('ripple/db'), + constants = require('ripple/constants'); + +module.exports = { + fileName: "config.xml", + validateVersion: function (configValidationObject) { + var valid = true; + // no xmlns:JIL in wac 2.0 spec valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid; - return valid; - }, - extractInfo: function (configValidationObject) { - if (!configValidationObject) { - return null; + return valid; + }, + extractInfo: function (configValidationObject) { + if (!configValidationObject) { + return null; + } + + var widgetInfo = {}, + configFeatures, + configPreferences, + preferenceName, + platform; + + widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || ""; + widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value; + widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value; + widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value; + + widgetInfo.features = {}; + + if (configValidationObject.widget.children.setting.hasOwnProperty('validationResult') === true && + configValidationObject.widget.children.setting.validationResult[0].valid === true) { + db.save("layout", configValidationObject.widget.children.setting.validationResult[0].attributes["screen-orientation"].value); + } + + configFeatures = configValidationObject.widget.children.feature.validationResult; + utils.forEach(configFeatures, function (f) { + if (f.valid === true) { + var feature = {id: f.attributes.name.value, + required: f.attributes.required.valid}; + widgetInfo.features[feature.id] = feature; + } + }); + + widgetInfo.preferences = {}; + + configPreferences = configValidationObject.widget.children.preference.validationResult; + + platform = require('ripple/platform'); + utils.forEach(configPreferences, function (preference) { + preferenceName = preference.attributes.name.value; + if (preferenceName) { + widgetInfo.preferences[preferenceName] = { + "key": preferenceName, + "value": preference.attributes.value.value || "", + "readonly": preference.attributes.readonly.value === "true" + }; + + db.save(preferenceName, + widgetInfo.preferences[preferenceName].value, + platform.getPersistencePrefix(widgetInfo.id)); + } + }); + + return widgetInfo; + }, + schema: { + rootElement: "widget", + widget: { + nodeName: "widget", + required: true, + occurrence: 1, + helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in the configuration document and may have the following child elments: name,description,icon,author,license,content,feature and preference.The \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir", + attributes: { + xmlns: { + attributeName: "xmlns", + required: true, + type: "list", + listValues: ["http://www.w3.org/ns/widgets"] + }, + "xmlns:tizen": { + attributeName: "xmlns:tizen", + required: false, + type: "list", + listValues: ["http://tizen.org/ns/widgets"] + }, + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language" + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + id: { + attributeName: "id", + required: false, + type: "string" + }, + version: { + attributeName: "version", + required: false, + type: "string" + }, + height: { + attributeName: "height", + required: false, + type: "integer" + }, + width: { + attributeName: "width", + required: false, + type: "integer" + }, + viewmodes: { + attributeName: "viewmodes", + required: false, + type: "list", + listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"] + }, + defaultlocale: { + attributeName: "defaultlocale", + required: false, + type: "iso-language" + }, + }, + children: { + name: { + nodeName: "name", + required: false, + occurrence: 0, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + unique: true + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + "short": { + attributeName: "short", + required: false, + type: "string" + } + }, + children: { + span: { + nodeName: "span", + required: false, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + unique: true + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + } + } + } + } + }, + description: { + nodeName: "description", + required: false, + occurrence: 0, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + unique: true + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + } + }, + children: { + span: { + nodeName: "span", + required: false, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + unique: true + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + } + } + } + } + }, + author: { + nodeName: "author", + required: false, + occurrence: 0, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + href: { + attributeName: "href", + required: false, + type: "regex", + regex: constants.REGEX.URL + }, + email: { + attributeName: "email", + required: false, + type: "regex", + regex: constants.REGEX.EMAIL + } + }, + children: { + span: { + nodeName: "span", + required: false, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + unique: true + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + } + } + } + } + }, + license: { + nodeName: "license", + required: false, + occurrence: 0, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + href: { + attributeName: "href", + type: "regex", + required: false, + regex: constants.REGEX.URL + } + }, + children: { + span: { + nodeName: "span", + required: false, + type: "string", + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + unique: true + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + } + } + } + } + }, + icon: { + nodeName: "icon", + required: false, + occurrence: 0, + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + src: { + attributeName: "src", + required: true, + type: "string" + }, + width: { + attributeName: "width", + required: false, + type: "integer" + }, + height: { + attributeName: "height", + required: false, + type: "integer" + } + } + }, + content: { + nodeName: "content", + required: false, + occurrence: 1, + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + unique: true + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + src: { + attributeName: "src", + required: true, + type: "string" + }, + encoding: { + attributeName: "encoding", + required: false, + type: "string" + }, + type: { + attributeName: "type", + required: false, + type: "string" + } + } + }, + setting: { + nodeName: "tizen:setting", + required: false, + occurrence: 0, + attributes: { + 'screen-orientation': { + attributeName: "screen-orientation", + required: false, + type: "list", + listValues: ['portrait', 'landscape'] + }, + 'context-menu': { + attributeName: "context-menu", + required: false, + type: "list", + listValues: ['enable', 'disable'] + }, + 'background-support': { + attributeName: "background-support", + required: false, + type: "list", + listValues: ['enable', 'disable'] + }, + 'encryption': { + attributeName: "encryption", + required: true, + type: "list", + listValues: ['enable', 'disable'] + }, + 'install-location': { + attributeName: "install-location", + required: false, + type: "list", + listValues: ['auto', 'internal-only', 'perfer-external'] + } + } + }, + application: { + nodeName: "tizen:application", + required: true, + occurrence: 1, + attributes: { + id: { + attributeName: "id", + required: true, + type: "string" + }, + required_version: { + attributeName: "required_version", + required: true, + type: "string" + }, + package: { + attributeName: "package", + required: false, + type: "string" + } + } + }, + "tizen:content": { + nodeName: "tizen:content", + required: true, + occurrence: 1, + attributes: { + src: { + attributeName: "src", + required: true, + type: "string" + } + } + }, + control: { + nodeName: "tizen:app-control", + required: false, + occurrence: 0, + children: { + src: { + nodeName: "tizen:src", + required: true, + occurence: 0, + attributes: { + name: { + attributeName: "name", + required: false, + type: "string" + } + } + }, + operation: { + nodeName: "tizen:operation", + required: true, + occurence: 0, + attributes: { + name: { + attributeName: "name", + required: false, + type: "string" + } + } + }, + uri: { + nodeName: "tizen:uri", + required: false, + occurence: 0, + attributes: { + name: { + attributeName: "name", + required: false, + type: "string" + } + } + }, + mime: { + nodeName: "tizen:mime", + required: false, + occurence: 0, + attributes: { + name: { + attributeName: "name", + required: false, + type: "string" + } + } + } + } + }, + "app-widget": { + nodeName: "tizen:app-widget", + required: false, + occurrence: 0, + attributes: { + id: { + attributeName: "id", + required: true, + type: "string" + }, + primary: { + attributeName: "primary", + required: true, + type: "list", + listValues: ['true', 'false'] + }, + "auto-launch": { + attributeName: "auto-launch", + required: false, + type: "list", + listValues: ['true', 'false'] + }, + "update-period": { + attributeName: "update-period", + required: false, + type: "integer" + } + }, + children: { + "box-label": { + nodeName: "tizen:box-label", + required: true, + occurence: 1 + }, + "box-icon": { + nodeName: "tizen:box-icon", + required: true, + occurence: 1, + attributes: { + src: { + attributeName: "src", + required: true, + type: "string" + } + } + }, + "box-content": { + nodeName: "tizen:box-content", + required: true, + occurence: 1, + attributes: { + src: { + attributeName: "src", + required: true, + type: "string" + }, + "mouse-event": { + attributeName: "mouse-event", + required: false, + type: "string" + }, + "touch-event": { + attributeName: "touch-event", + required: false, + type: "string" + } + }, + children: { + "box-size": { + nodeName: "tizen:box-size", + required: false, + occurence: 1, + attributes: { + "preview": { + attributeName: "preview", + required: false, + type: "string" + } + } + }, + pd: { + nodeName: "tizen:pd", + required: false, + occurence: 1, + attributes: { + "src": { + attributeName: "src", + required: true, + type: "string" + }, + "width": { + attributeName: "width", + required: true, + type: "integer" + }, + "height": { + attributeName: "height", + required: true, + type: "integer" + } + } + } + } + } + } + }, + account: { + nodeName: "tizen:account", + required: false, + occurrence: 0, + attributes: { + "multiple-account-support": { + attributeName: "multiple-account-support", + required: true, + type: "list", + listValues: ['true', 'false'] + } + }, + children: { + icon: { + nodeName: "tizen:icon", + required: false, + occurence: 1, + attributes: { + section: { + attributeName: "section", + required: true, + type: "string" + } + } + }, + "display-name": { + nodeName: "tizen:display-name", + required: false, + occurence: 1, + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "string" + } + } + }, + capability: { + nodeName: "capability", + required: false, + occurence: 1 + } + } + }, + feature: { + nodeName: "tizen:privilege", + required: false, + occurrence: 0, + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + name: { + attributeName: "name", + required: true, + type: "list", + listValues: ["http://www.w3.org/TR/battery-status/", + "http://www.w3.org/TR/geolocation-API/", + "http://www.w3.org/TR/touch-events/", + "http://www.w3.org/TR/vibration/", + "http://tizen.org/privilege/tizen", + "http://tizen.org/privilege/alarm", + "http://tizen.org/privilege/application.launch", + "http://tizen.org/privilege/appmanager.kill", "http://tizen.org/privilege/appmanager.certificate", + "http://tizen.org/privilege/bluetoothmanager", "http://tizen.org/privilege/bluetooth.admin", + "http://tizen.org/privilege/bluetooth.gap", "http://tizen.org/privilege/bluetooth.spp", + "http://tizen.org/privilege/bookmark.read", "http://tizen.org/privilege/bookmark.write", + "http://tizen.org/privilege/calendar.read", "http://tizen.org/privilege/calendar.write", + "http://tizen.org/privilege/callhistory.read", "http://tizen.org/privilege/callhistory.write", + "http://tizen.org/privilege/contact.read", "http://tizen.org/privilege/contact.write", + "http://tizen.org/privilege/content.read", "http://tizen.org/privilege/content.write", + "http://tizen.org/privilege/datacontrol.consumer", + "http://tizen.org/privilege/datasync", + "http://tizen.org/privilege/download", + "http://tizen.org/privilege/filesystem.read", "http://tizen.org/privilege/filesystem.write", + "http://tizen.org/privilege/messaging.read", "http://tizen.org/privilege/messaging.write", + "http://tizen.org/privilege/networkbearerselection", + "http://tizen.org/privilege/nfc.common", "http://tizen.org/privilege/nfc.admin", + "http://tizen.org/privilege/nfc.tag", "http://tizen.org/privilege/nfc.p2p", + "http://tizen.org/privilege/notification", + "http://tizen.org/privilege/packagemanager.install", "http://tizen.org/privilege/package.info", + "http://tizen.org/privilege/power", + "http://tizen.org/privilege/push", + "http://tizen.org/privilege/setting", + "http://tizen.org/privilege/system", "http://tizen.org/privilege/systemmanager", + "http://tizen.org/privilege/time"] + }, + required: { + attributeName: "required", + type: "boolean", + required: false + } + }, + children: { + param: { + nodeName: "param", + required: false, + occurrence: 0, + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + name: { + attributeName: "name", + required: true, + type: "string", + }, + value: { + attributeName: "value", + required: true, + type: "string", + } + } + } + } + }, + preference: { + nodeName: "preference", + required: false, + occurrence: 0, + attributes: { + "xml:lang": { + attributeName: "xml:lang", + required: false, + type: "iso-language", + }, + dir: { + attributeName: "dir", + required: false, + type: "list", + listValues: ["ltr", "rtl", "lro", "rlo"] + }, + name: { + attributeName: "name", + required: true, + type: "string" + }, + value: { + type: "string", + required: false, + attributeName: "value" + }, + readonly: { + attributeName: "readonly", + type: "boolean", + required: false + } + } + } + } + } + } +}; + +}); +define('ripple/platform/tizen/2.0/spec/device', function (require, exports, module) { +/* + * Copyright 2011 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var event = require('ripple/event'), + utils = require('ripple/utils'), + StorageTypeTable = { + "UNKNOWN": "UNKNOWN", + "INTERNAL": "INTERNAL", + "MMC": "MMC", + "USB_HOST": "USB_HOST" + }, + NetworkTypeTable = { + "NONE": "NONE", + "2G": "2G", + "2.5G": "2.5G", + "3G": "3G", + "4G": "4G", + "WIFI": "WIFI", + "ETHERNET": "ETHERNET", + "UNKNOWN": "UNKNOWN" + }, + LocaleTable = { + "eng_USA": "eng_USA", + "eng_CAN": "eng_CAN", + "deu_DEU": "deu_DEU", + "jpn_JPN": "jpn_JPN", + "zho_CHN": "zho_CHN", + "UNKNOWN": "UNKNOWN" + }, + SimStateTable = { + "ABSENT": "ABSENT", + "INITIALIZING": "INITIALIZING", + "READY": "READY", + "PIN_REQUIRED": "PIN_REQUIRED", + "PUK_REQUIRED":"PUK_REQUIRED", + "NETWORK_LOCKED": "NETWORK_LOCKED", + "SIM_LOCKED": "SIM_LOCKED", + "UNKNOWN": "UNKNOWN" + }; + +function deviceStatusEventTrigger(setting) { + event.trigger("DeviceStatusChanged", [setting]); +} + +module.exports = { + "Config": { + "vibratingMode": { + "name": "Vibrator", + "control": { + "type": "checkbox", + "value": true + }, + "callback": function (setting) { + event.trigger("VibratingModeChanged", [setting]); + } + }, + "lockScreen": { + "name": "Lock Screen", + "control": { + "type": "checkbox", + "value": false + }, + "callback": function (setting) { + event.trigger("LockScreenChanged", [setting]); + } + } + }, + "DEVICE_ORIENTATION": { + "status": { + "name": "Status", + "control": { + "type": "label", + "innertext": "PORTRAIT_PRIMARY", + "value": "PORTRAIT_PRIMARY" + }, + "event": "LayoutChanged" + } + }, + "CPU": { + "load": { + "name": "Load", + "control": { + "type": "number", + "value": 0.1 + }, + "event": "CpuLoadChanged", + "callback": function (setting) { + if (setting > 1) setting = 1; + if (setting < 0) setting = 0; + event.trigger("CpuLoadChanged", [setting]); + } + } + }, + "STORAGE": { + "type": { + "name": "Type", + "control": { + "type": "select", + "value": StorageTypeTable["INTERNAL"] + }, + "options": (function () { + var optionList = {}; + utils.forEach(StorageTypeTable, function (key, value) { + optionList[key] = StorageTypeTable[value]; + }); + + return optionList; + }()) + }, + "capacity": { + "name": "Capacity", + "control": { + "type": "label", + "value": 16000000000 + }, + }, + "availableCapacity": { + "name": "AvailableCapacity", + "control": { + "type": "number", + "value": 12000000000 + }, + "callback": function (setting) { + event.trigger("AvailCapacityChanged", [setting]); + } + }, + "isRemovable": { + "name": "IsRemovable", + "control": { + "type": "checkbox", + "value": true + } + } + }, + "BUILD": { + "model": { + "name": "Model", + "control": { + "type": "label", + "innertext": "tizen-2.2 build", + "value": "tizen-2.2 build" + } + }, + "manufacturer": { + "name": "Manufacturer", + "control": { + "type": "label", + "innertext": "Tizen", + "value": "Tizen" + } + } + }, + "LOCALE": { + "language": { + "name": "Language", + "control": { + "type": "select", + "value": LocaleTable["eng_USA"] + }, + "options": (function () { + var optionList = {}; + utils.forEach(LocaleTable, function (key, value) { + optionList[key] = LocaleTable[value]; + }); + + return optionList; + }()) + }, + "country": { + "name": "Country", + "control": { + "type": "select", + "value": LocaleTable["eng_USA"] + }, + "options": (function () { + var optionList = {}; + utils.forEach(LocaleTable, function (key, value) { + optionList[key] = LocaleTable[value]; + }); + + return optionList; + }()) + } + }, + "DISPLAY": { + "resolutionWidth": { + "name": "Resolution Width", + "control": { + "type": "label", + "value": 0 + } + }, + "resolutionHeight": { + "name": "Resolution Height", + "control": { + "type": "label", + "value": 0 + } + }, + "dotsPerInchWidth": { + "name": "DPI-X", + "control": { + "type": "label", + "value": 0 + } + }, + "dotsPerInchHeight": { + "name": "DPI-Y", + "control": { + "type": "label", + "value": 0 + } + }, + "physicalWidth": { + "name": "Physical Width", + "control": { + "type": "label", + "value": 0 + } + }, + "physicalHeight": { + "name": "Physical Height", + "control": { + "type": "label", + "value": 0 + } + }, + "brightness": { + "name": "Brightness", + "control": { + "type": "number", + "value": 1 + }, + "event": "DisplayBrightnessChanged", + "callback": function (setting) { + if (setting > 1) setting = 1; + if (setting < 0) setting = 0; + event.trigger("DisplayBrightnessChanged", [setting]); + } + } + }, + "NETWORK": { + "networkType": { + "name": "Network Type", + "control" : { + "type": "select", + "value": NetworkTypeTable["NONE"] + }, + "options": (function () { + var optionList = {}; + utils.forEach(NetworkTypeTable, function (key, value) { + optionList[key] = NetworkTypeTable[value]; + }); + + return optionList; + }()) + } + }, + "WIFI_NETWORK": { + "status": { + "name": "Status", + "control": { + "type": "checkbox", + "value": false + }, + "event": "WiFiNetworkStatusChanged", + "callback": function (setting) { + event.trigger("WiFiNetworkStatusChanged", [setting]); + } + }, + "ssid": { + "name": "SSID", + "control": { + "type": "text", + "value": "Tizen WiFi" + } + }, + "ipAddress": { + "name": "IP Address", + "control": { + "type": "text", + "value": "192.168.0.1" + } + }, + "ipv6Address": { + "name": "IPv6 Address", + "control": { + "type": "text", + "value": "2001:db8:85a3:0:0:0:70:7334" + } + }, + "signalStrength": { + "name": "Signal Strength", + "control": { + "type": "select", + "value": 0 + }, + "options": (function () { + var i, + optionList = {}; + + for (i = 0; i <= 10; i++) { + optionList[i] = i; + } + + return optionList; + }()) + } + }, + "CELLULAR_NETWORK": { + "status": { + "name": "Status", + "control": { + "type": "checkbox", + "value": true + }, + "event": "CellularNetworkStatusChanged", + "callback": function (setting) { + event.trigger("CellularNetworkStatusChanged", [setting]); + } + }, + "apn": { + "name": "APN", + "control": { + "type": "text", + "value": "Tizen" + } + }, + "ipAddress": { + "name": "IP Address", + "control": { + "type": "text", + "value": "10.0.2.16" + } + }, + "ipv6Address": { + "name": "IPv6 Address", + "control": { + "type": "text", + "value": "2001:db8:85a3:0:0:0:70:7334" + } + }, + "mcc": { + "name": "MCC", + "control": { + "type": "number", + "value": 460 + } + }, + "mnc": { + "name": "MNC", + "control": { + "type": "number", + "value": 0 + } + }, + "cellId": { + "name": "Cell ID", + "control": { + "type": "number", + "value": 0 + } + }, + "lac": { + "name": "LAC", + "control": { + "type": "number", + "value": 0 + } + }, + "isRoaming": { + "name": "Roaming", + "control": { + "type": "checkbox", + "value": true + } + }, + "isFlightMode": { + "name": "Flight Mode", + "control": { + "type": "checkbox", + "value": false + }, + "callback": function (setting) { + event.trigger("FlightModeChanged", [setting]); + } + }, + "imei": { + "name": "IMEI", + "control": { + "type": "text", + "value": "012417005203000" + } + } + }, + "SIM": { + "state": { + "name": "State", + "control": { + "type": "select", + "value": SimStateTable["READY"] + }, + "options": (function () { + var optionList = {}; + utils.forEach(SimStateTable, function (key, value) { + optionList[key] = SimStateTable[value]; + }); + + return optionList; + }()) + }, + "operatorName": { + "name": "Operator Name", + "control": { + "type": "text", + "value": "Tizen" + } + }, + "msisdn": { + "name": "MSISDN", + "control": { + "type": "text", + "value": "088123456789" + } + }, + "iccid": { + "name": "ICCID", + "control": { + "type": "text", + "value": "123000MFSSYYGXXXXXXP" + } + }, + "mcc": { + "name": "MCC", + "control": { + "type": "number", + "value": 460 + } + }, + "mnc": { + "name": "MNC", + "control": { + "type": "number", + "value": 0 + } + }, + "msin": { + "name": "MSIN", + "control": { + "type": "text", + "value": "H1 H2 H3 S 12345" + } + }, + "spn": { + "name": "SPN", + "control": { + "type": "text", + "value": "TizenSPN" + } + } + }, + "PERIPHERAL": { + "isVideoOutputOn": { + "name": "Video Output", + "control": { + "type": "checkbox", + "value": false + } + } + } +}; + + +}); +define('ripple/platform/tizen/2.0/spec/sensor', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var event = require('ripple/event'); + +function sensorStatusEventTrigger(setting) { + event.trigger("SensorStatusChanged", [setting]); +} + +module.exports = { + "Accelerometer": { + "resolution": 0.039239998906850815, + "minDelay": 20, + "range": 20.051639556884766, + "name": "Accelerometer", + "type": "Accelerometer" + }, + "MagneticField": { + "x": { + "name": "X", + "control": { + "type": "range", + "value": 100.0000000000000000, + "min": 0.0000000000000000, + "max": 200.0000000000000000, + "step": 0.0000000000000001 + }, + "callback": function (setting) { + event.trigger("MagneticField-xChanged", [setting]); + } + }, + + "y": { + "name": "Y", + "control": { + "type": "range", + "value": 100.0000000000000000, + "min": 0.0000000000000000, + "max": 200.0000000000000000, + "step": 0.0000000000000001 + }, + "callback": function (setting) { + event.trigger("MagneticField-yChanged", [setting]); + } + }, + + "z": { + "name": "Z", + "control": { + "type": "range", + "value": 100.0000000000000000, + "min": 0.0000000000000000, + "max": 200.0000000000000000, + "step": 0.0000000000000001 + }, + "callback": function (setting) { + event.trigger("MagneticField-zChanged", [setting]); + } + }, + + "resolution": 1, + "minDelay": 20, + "range": 359, + "name": "MagneticField", + "type": "MagneticField" + }, + "Rotation": { + "resolution": 1, + "minDelay": 20, + "range": 359, + "name": "Rotation", + "type": "Rotation" + }, + "Orientation": { + "resolution": 1, + "minDelay": 20, + "range": 359, + "name": "Orientation", + "type": "Orientation" + } +}; + +}); +define('ripple/platform/tizen/2.0/spec/ui', function (require, exports, module) { +/* + * Copyright 2011 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = { + plugins: [ + "sensors", + "communication", + "geoView", + "widgetConfig", + "deviceSettings", + "application", + "network", + "power", + "download", + "package" + ] +}; + +}); +define('ripple/platform/tizen/2.0/spec', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + + id: "tizen", + version: "2.2", + name: "TIZEN", + + persistencePrefix: "tizen1-", + + config: require('ripple/platform/tizen/2.0/spec/config'), + ui: require('ripple/platform/tizen/2.0/spec/ui'), + device: require('ripple/platform/tizen/2.0/spec/device'), + sensor: require('ripple/platform/tizen/2.0/spec/sensor'), + DeviceMotionEvent: require('ripple/platform/tizen/2.0/DeviceMotionEvent'), + DeviceOrientationEvent: require('ripple/platform/tizen/2.0/DeviceOrientationEvent'), + + objects: { + Coordinates: { + path: "w3c/1.0/Coordinates" + }, + Position: { + path: "w3c/1.0/Position" + }, + PositionError: { + path: "w3c/1.0/PositionError" + }, + SensorConnection: { + path: "w3c/1.0/SensorConnection" + }, + navigator: { + path: "tizen/2.0/navigator", + children: { + geolocation: { + path: "wac/2.0/geolocation" + }, + battery: { + path: "tizen/2.0/battery" + } + } + }, + tizen: { + feature: "http://tizen.org/privilege/tizen", + children: { + AlarmAbsolute: { + path: "tizen/2.0/AlarmAbsolute" + }, + AlarmRelative: { + path: "tizen/2.0/AlarmRelative" + }, + ApplicationControl: { + path: "tizen/2.0/ApplicationControl" + }, + ApplicationControlData: { + path: "tizen/2.0/ApplicationControlData" + }, + AttributeFilter: { + path: "tizen/2.0/AttributeFilter" + }, + AttributeRangeFilter: { + path: "tizen/2.0/AttributeRangeFilter" + }, + BookmarkFolder: { + path: "tizen/2.0/BookmarkFolder" + }, + BookmarkItem: { + path: "tizen/2.0/BookmarkItem" + }, + CalendarAlarm: { + path: "tizen/2.0/CalendarAlarm" + }, + CalendarAttendee: { + path: "tizen/2.0/CalendarAttendee" + }, + CalendarEvent: { + path: "tizen/2.0/CalendarEvent" + }, + CalendarEventId: { + path: "tizen/2.0/CalendarEventId" + }, + CalendarRecurrenceRule: { + path: "tizen/2.0/CalendarRecurrenceRule" + }, + CalendarTask: { + path: "tizen/2.0/CalendarTask" + }, + CompositeFilter: { + path: "tizen/2.0/CompositeFilter" + }, + Contact: { + path: "tizen/2.0/ContactBase" + }, + ContactAddress: { + path: "tizen/2.0/ContactAddress" + }, + ContactAnniversary: { + path: "tizen/2.0/ContactAnniversary" + }, + ContactEmailAddress: { + path: "tizen/2.0/ContactEmailAddress" + }, + ContactGroup: { + path: "tizen/2.0/ContactGroup" + }, + ContactName: { + path: "tizen/2.0/ContactName" + }, + ContactOrganization: { + path: "tizen/2.0/ContactOrganization" + }, + ContactPhoneNumber: { + path: "tizen/2.0/ContactPhoneNumber" + }, + ContactRef: { + path: "tizen/2.0/ContactRef" + }, + ContactWebSite: { + path: "tizen/2.0/ContactWebSite" + }, + DownloadRequest: { + path: "tizen/2.0/DownloadRequest" + }, + Message: { + path: "tizen/2.0/Message" + }, + NDEFMessage: { + path: "tizen/2.0/NDEFMessage" + }, + NDEFRecord: { + path: "tizen/2.0/NDEFRecord" + }, + NDEFRecordMedia: { + path: "tizen/2.0/NDEFRecordMedia" + }, + NDEFRecordText: { + path: "tizen/2.0/NDEFRecordText" + }, + NDEFRecordURI: { + path: "tizen/2.0/NDEFRecordURI" + }, + NotificationDetailInfo: { + path: "tizen/2.0/NotificationDetailInfo" + }, + SimpleCoordinates: { + path: "tizen/2.0/SimpleCoordinates" + }, + SortMode: { + path: "tizen/2.0/SortMode" + }, + StatusNotification: { + path: "tizen/2.0/StatusNotification" + }, + SyncInfo: { + path: "tizen/2.0/SyncInfo" + }, + SyncServiceInfo: { + path: "tizen/2.0/SyncServiceInfo" + }, + SyncProfileInfo: { + path: "tizen/2.0/SyncProfileInfo" + }, + TZDate: { + path: "tizen/2.0/TZDate" + }, + TimeDuration: { + path: "tizen/2.0/TimeDuration" + }, + alarm: { + path: "tizen/2.0/alarm", + feature: "http://tizen.org/privilege/alarm", + handleSubfeatures: true + }, + application: { + path: "tizen/2.0/application", + feature: "http://tizen.org/privilege/application.launch|http://tizen.org/privilege/appmanager.kill|http://tizen.org/privilege/appmanager.certificate", + handleSubfeatures: true + }, + bluetooth: { + path: "tizen/2.0/bluetooth", + feature: "http://tizen.org/privilege/bluetoothmanager|http://tizen.org/privilege/bluetooth.admin|http://tizen.org/privilege/bluetooth.gap|http://tizen.org/privilege/bluetooth.spp", + handleSubfeatures: true + }, + bookmark: { + path: "tizen/2.0/bookmark", + feature: "http://tizen.org/privilege/bookmark.read|http://tizen.org/privilege/bookmark.write", + handleSubfeatures: true + }, + callhistory: { + path: "tizen/2.0/callHistory", + feature: "http://tizen.org/privilege/callhistory|http://tizen.org/privilege/callhistory.read|http://tizen.org/privilege/callhistory.write", + handleSubfeatures: true + }, + calendar: { + path: "tizen/2.0/calendar", + feature: "http://tizen.org/privilege/calendar.read|http://tizen.org/privilege/calendar.write", + handleSubfeatures: true + }, + contact: { + path: "tizen/2.0/contact", + feature: "http://tizen.org/privilege/contact.read|http://tizen.org/privilege/contact.write", + handleSubfeatures: true + }, + content: { + path: "tizen/2.0/content", + feature: "http://tizen.org/privilege/content.read|http://tizen.org/privilege/content.write", + handleSubfeatures: true + }, + datacontrol: { + path: "tizen/2.0/datacontrol", + feature: "http://tizen.org/privilege/datacontrol.consumer", + handleSubfeatures: true + }, + datasync: { + path: "tizen/2.0/datasync", + feature: "http://tizen.org/privilege/datasync", + handleSubfeatures: true + }, + download: { + path: "tizen/2.0/download", + feature: "http://tizen.org/privilege/download", + handleSubfeatures: true + }, + filesystem: { + path: "tizen/2.0/filesystem", + feature: "http://tizen.org/privilege/filesystem.read|http://tizen.org/privilege/filesystem.write" + }, + messaging: { + path: "tizen/2.0/messaging", + feature: "http://tizen.org/privilege/messaging.send|http://tizen.org/privilege/messaging.read|http://tizen.org/privilege/messaging.write", + handleSubfeatures: true + }, + networkbearerselection: { + path: "tizen/2.0/networkbearerselection", + feature: "http://tizen.org/privilege/networkbearerselection", + handleSubfeatures: true + }, + nfc: { + path: "tizen/2.0/nfc", + feature: "http://tizen.org/privilege/nfc.common|http://tizen.org/privilege/nfc.admin|http://tizen.org/privilege/nfc.tag|http://tizen.org/privilege/nfc.p2p", + handleSubfeatures: true + }, + notification: { + path: "tizen/2.0/notification", + feature: "http://tizen.org/privilege/notification", + handleSubfeatures: true + }, + package: { + path: "tizen/2.0/package", + feature: "http://tizen.org/privilege/packagemanager.install|http://tizen.org/privilege/package.info", + handleSubfeatures: true + }, + power: { + path: "tizen/2.0/power", + feature: "http://tizen.org/privilege/power", + handleSubfeatures: true + }, + push: { + path: "tizen/2.0/push", + feature: "http://tizen.org/privilege/push", + handleSubfeatures: true + }, + systeminfo: { + path: "tizen/2.0/systeminfo", + feature: "http://tizen.org/privilege/system|http://tizen.org/privilege/systemmanager", + handleSubfeatures: true + }, + systemsetting: { + path: "tizen/2.0/systemsetting", + feature: "http://tizen.org/privilege/setting", + handleSubfeatures: true + }, + time: { + path: "tizen/2.0/time", + feature: "http://tizen.org/privilege/time", + handleSubfeatures: true + } + } + } + } +}; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/adapter', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.adapter +// auth: griffin +// date: 2012/10/22 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'); + + +var _self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + exports.Adapter = common.Base.extend({ + + // //------------------------------------------------------------------------- + // constructor: function(context, options, devInfo) { + + //------------------------------------------------------------------------- + normUri: function(uri) { + return common.normpath(uri); + }, + + //------------------------------------------------------------------------- + getStores: function() { + return _.values(this._stores); + }, + + //------------------------------------------------------------------------- + getStore: function(uri) { + return this._stores[this.normUri(uri)]; + }, + + //------------------------------------------------------------------------- + addStore: function(store, cb) { + var self = this; + if ( store instanceof storemod.Store ) + { + store.uri = self.normUri(store.uri); + store._a = self; + } + else + store = new storemod.Store(this, store); + store._updateModel(function(err) { + if ( err ) + return cb(err); + self._stores[store.uri] = store; + + // TODO: remove this sensitivity... + if ( ! self.isLocal ) + return cb(); + + self._save(self._c._txn(), function(err) { + if ( err ) + return cb(err); + cb(null, store); + }); + }); + }, + + //------------------------------------------------------------------------- + removeStore: function(uri, cb) { + var self = this; + if ( ! self.isLocal ) + // todo: implement + return cb(new common.LogicalError( + 'cannot remove remote store "' + uri + '": remote peer responsibility')); + if ( ! self._stores[uri] ) + return cb(new common.InternalError( + 'cannot remove store "' + uri + '": no such store')); + delete self._stores[uri]; + var model = self._getModel(); + model.stores = _.filter(model.stores, function(store) { + return store.uri != uri; + }); + _.each(model.peers, function(peer) { + peer.routes = _.filter(peer.routes, function(route) { + return route.localUri != uri; + }); + _.each(peer.stores, function(store) { + if ( store.binding && store.binding.uri == uri ) + store.binding = null; + }); + }); + return cb(); + }, + + //------------------------------------------------------------------------- + _isMapper: function() { + // indicates whether or not this adapter is capable of mapping + // items. in the standard SyncML peer model, only the server + // ever does mapping, but in the dream-land of syncml-js, all + // peers can be mappers, or even better, implements an extension + // "is-uuid/adopted" that does not require mapping. so, since + // that is just a dream-land for now, this will try to identify + // if this adapter represents a server... + // todo: enhance syncml-js so that it is not needed!... + if ( ! this.isLocal ) + return this.url && this.url.length > 0; + return this.devInfo && this.devInfo.devType == constant.DEVTYPE_SERVER; + }, + + //------------------------------------------------------------------------- + describe: function(stream, cb) { + var self = this; + if ( self.url ) + stream.writeln('URL: ' + self.url); + stream.writeln('Device ID: ' + self.devID); + var s1 = stream.indented(); + var s2 = s1.indented(); + + var describe_stores = function(cb) { + var stores = self.getStores(); + if ( stores.length <= 0 ) + { + stream.writeln('Data stores: (none)'); + return cb(); + } + stream.writeln('Data stores:'); + common.cascade(stores, function(store, cb) { + s1.writeln(( store.displayName || store.uri ) + ':'); + store.describe(s2, cb); + }, cb); + }; + + var describe_peers = function(cb) { + if ( ! self.getPeers ) + return cb(); + var peers = self.getPeers(); + if ( peers.length <= 0 ) + { + stream.writeln('Known peers: (none)'); + return cb(); + } + stream.writeln('Known peers:'); + common.cascade(peers, function(peer, cb) { + s1.writeln(( peer.displayName || peer.url ) + ':'); + peer.describe(s2, cb); + }, cb); + } + + describe_stores(function(err) { + if ( err ) + return cb(err); + describe_peers(cb); + }); + } + + }); + + return exports; + + })(); + + module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/agent', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.agent +// auth: griffin +// date: 2012/10/22 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'); + +var _self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + exports.Agent = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(options) { + options = _.defaults(options, { + hierarchicalSync: false + }); + this.hierarchicalSync = options.hierarchicalSync; + }, + + //------------------------------------------------------------------------- + dumpItem: function(item, stream, contentType, version, cb) { + return this.dumpsItem( + item, contentType, version, + function(err, data, new_contentType, new_version) { + if ( err ) { + return cb(err); + } + stream.write(data, function(err) { + if ( err ) { + return cb(err); + } + cb(null, new_contentType, new_version); + }); + }); + }, + + //------------------------------------------------------------------------- + loadItem: function(stream, contentType, version, cb) { + var self = this; + stream.read(function(err, data) { + if ( err ) { + cb(err); + } + self.loadsItem(data, contentType, version, cb); + }); + }, + + //------------------------------------------------------------------------- + deleteAllItems: function(cb) { + var self = this; + self.getAllItems(function(err, items) { + if ( err ) { + return cb(err); + } + common.cascade(items, function(e, cb) { + self.deleteItem(e, cb); + }, cb); + }); + }, + + // TODO: add documentation about all expected methods... + + getAllItems: function(cb) { + // cb(null, LIST) + return cb(new common.NotImplementedError()); + }, + + dumpsItem: function(item, contentType, version, cb) { + // cb(null, DATA [, NEW-CONTENTTYPE [, NEW-VERSION]]) + return cb(new common.NotImplementedError()); + }, + + loadsItem: function(data, contentType, version, cb) { + // cb(null, ITEM) + return cb(new common.NotImplementedError()); + }, + + addItem: function(item, cb) { + // cb(null, ITEM) + return cb(new common.NotImplementedError()); + }, + + getItem: function(itemID, cb) { + // cb(null, ITEM) + return cb(new common.NotImplementedError()); + }, + + replaceItem: function(item, reportChanges, cb) { + // cb(null [, CSPEC]) + return cb(new common.NotImplementedError()); + }, + + deleteItem: function(itemID, cb) { + // cb(null) + return cb(new common.NotImplementedError()); + }, + + getContentTypes: function() { + throw new common.NotImplementedError(); + }, + + matchItem: function(item, cb) { + this.getAllItems(function(err, list) { + if ( err ) { + return cb(err); + } + var match = _.find(list, function(cur) { + return cur.compare && cur.compare(item) == 0; + }); + return cb(null, match); + }); + } + + // TODO: mergeItems() + + }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/base64', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +//----------------------------------------------------------------------------- + +var _self = (function() { + + // shamelessly scrubbed from: + // http://www.webtoolkit.info/javascript-base64.html + + /** + * + * Base64 encode / decode + * http://www.webtoolkit.info/ + * + **/ + + var Base64 = { + + // private property + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + + // public method for encoding + encode : function (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + + input = Base64._utf8_encode(input); + + while (i < input.length) { + + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); + + } + + return output; + }, + + // public method for decoding + decode : function (input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + } + + output = Base64._utf8_decode(output); + + return output; + + }, + + // private method for UTF-8 encoding + _utf8_encode : function (string) { + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + }, + + // private method for UTF-8 decoding + _utf8_decode : function (utftext) { + var string = ""; + var i = 0; + var c = c1 = c2 = 0; + + while ( i < utftext.length ) { + + c = utftext.charCodeAt(i); + + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + + } + + return string; + } + + }; + + return Base64; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/codec', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// auth: metagriffin +// date: 2012/10/13 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + _self; + +_self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + exports.Codec = common.Base.extend({ + + encode: function(xtree, cb) { + throw new common.NotImplementedError(); + }, + + decode: function(contentType, data, cb) { + throw new common.NotImplementedError(); + }, + }, { + + factory: function(codec) { + // todo: should this be converted to callback-based?... + if ( codec == constant.CODEC_XML ) + return new exports.XmlCodec() + // TODO + // if ( codec == constant.CODEC_WBXML ) + // return exports.WbxmlCodec() + throw new common.UnknownCodec('unknown or unimplemented codec "' + codec + '"') + }, + + autoEncode: function(xtree, codecName, cb) { + exports.Codec.factory(codecName).encode(xtree, cb); + }, + + autoDecode: function(contentType, data, cb) { + if ( contentType.indexOf(constant.TYPE_SYNCML + '+') != 0 ) + return cb('unknown or unimplemented content type "' + contentType + '"'); + var ct = contentType.slice((constant.TYPE_SYNCML + '+').length).split(';')[0]; + exports.Codec.factory(ct).decode(contentType, data, function(err, tree) { + if ( err ) + return cb(err); + return cb(null, tree, ct); + }); + }, + }); + + //--------------------------------------------------------------------------- + exports.XmlCodec = exports.Codec.extend({ + + name: constant.CODEC_XML, + + encode: function(xtree, cb) { + // todo: really enforce this charset... + var ctype = constant.TYPE_SYNCML + '+' + this.name + '; charset=UTF-8'; + var ret = ET.tostring(xtree); + if ( ret.charAt(0) == '<' && ret.charAt(1) == '?' ) + { + var idx = ret.indexOf('?>'); + if ( idx >= 0 ) + ret = ret.substr(0, idx + 2).replace(/'/g, '"') + ret.substr(idx + 2); + } + cb(null, ctype, ret); + }, + + decode: function(contentType, data, cb) { + var expCT = constant.TYPE_SYNCML + '+' + this.name; + if ( contentType.indexOf(expCT) != 0 ) + cb(new common.ProtocolError( + 'received unexpected content-type "' + contentType + '" (expected "' + + expCT + '")')); + try + { + return cb(null, ET.parse(data).getroot()); + } + catch(e) + { + return cb(new common.ProtocolError('could not parse XML: ' + e, e)); + } + } + + }); + + //--------------------------------------------------------------------------- + // TODO: implement wbxml... + // exports.WbXmlCodec = exports.Codec.extend({ + // encode: function(xtree, cb) { + // }, + // decode: function(contentType, data, cb) { + // } + // }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/common', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// auth: metagriffin +// date: 2012/10/13 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + _self; + +_self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + // object inheritance helper routines shamelessly scrubbed from backbone.js + + // The self-propagating extend function that Backbone classes use. + var extend = exports.extend = function (protoProps, classProps) { + var child = inherits(this, protoProps, classProps); + child.extend = this.extend; + return child; + }; + + // Shared empty constructor function to aid in prototype-chain creation. + var ctor = function(){}; + + // Helper function to correctly set up the prototype chain, for subclasses. + // Similar to `goog.inherits`, but uses a hash of prototype properties and + // class properties to be extended. + var inherits = function(parent, protoProps, staticProps) { + var child; + + // The constructor function for the new subclass is either defined by you + // (the "constructor" property in your `extend` definition), or defaulted + // by us to simply call the parent's constructor. + if (protoProps && protoProps.hasOwnProperty('constructor')) { + child = protoProps.constructor; + } else { + child = function(){ parent.apply(this, arguments); }; + } + + // Inherit class (static) properties from parent. + _.extend(child, parent); + + // Set the prototype chain to inherit from `parent`, without calling + // `parent`'s constructor function. + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + + // Add prototype properties (instance properties) to the subclass, + // if supplied. + if (protoProps) _.extend(child.prototype, protoProps); + + // Add static properties to the constructor function, if supplied. + if (staticProps) _.extend(child, staticProps); + + // Correctly set child's `prototype.constructor`. + child.prototype.constructor = child; + + // Set a convenience property in case the parent's prototype is needed later. + child.__super__ = parent.prototype; + + return child; + }; + + //----------------------------------------------------------------------------- + exports.Base = function() {}; + exports.Base.extend = extend; + + //----------------------------------------------------------------------------- + var SyncmlError = exports.Base.extend({ + constructor: function(msg, exception, attrs) { + this.message = this.name; + if ( msg != undefined ) + this.message += ': ' + msg; + this.exception = exception; + if ( attrs ) + _.extend(this, attrs); + }, + toString: function() { + return this.message; + } + }); + + //--------------------------------------------------------------------------- + exports.Stream = exports.Base.extend({ + + writeln: function(data) { + if ( data == undefined ) + return; + return this.write(data + '\n'); + }, + + indented: function(indent) { + return new exports.IndentStream(this, indent || this._indent); + } + + }); + + _.extend(exports, { + + //--------------------------------------------------------------------------- + // exceptions + SyncmlError: SyncmlError.extend({name: 'SyncmlError'}), + TypeError: SyncmlError.extend({name: 'TypeError'}), + NotImplementedError: SyncmlError.extend({name: 'NotImplementedError'}), + ProtocolError: SyncmlError.extend({name: 'ProtocolError'}), + InternalError: SyncmlError.extend({name: 'InternalError'}), + ConflictError: SyncmlError.extend({name: 'ConflictError'}), + FeatureNotSupported: SyncmlError.extend({name: 'FeatureNotSupported'}), + LogicalError: SyncmlError.extend({name: 'LogicalError'}), + CredentialsRequired: SyncmlError.extend({name: 'CredentialsRequired'}), + InvalidCredentials: SyncmlError.extend({name: 'InvalidCredentials'}), + InvalidContext: SyncmlError.extend({name: 'InvalidContext'}), + InvalidAdapter: SyncmlError.extend({name: 'InvalidAdapter'}), + InvalidStore: SyncmlError.extend({name: 'InvalidStore'}), + InvalidContentType: SyncmlError.extend({name: 'InvalidContentType'}), + InvalidAgent: SyncmlError.extend({name: 'InvalidAgent'}), + InvalidContent: SyncmlError.extend({name: 'InvalidContent'}), + InvalidItem: SyncmlError.extend({name: 'InvalidItem'}), + UnknownCodec: SyncmlError.extend({name: 'UnknownCodec'}), + NoSuchRoute: SyncmlError.extend({name: 'NoSuchRoute'}), + UnknownAuthType: SyncmlError.extend({name: 'UnknownAuthType'}), + UnknownFormatType: SyncmlError.extend({name: 'UnknownFormatType'}), + + //--------------------------------------------------------------------------- + // UUID generation + makeID: function() { + // shamelessly scrubbed from: + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 + // (adjusted to remove the dashes) + // todo: see some of those links on how to make this more "robust"... + return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); + }, + + //------------------------------------------------------------------------- + synctype2alert: function(type) { + return constant.SyncTypeToAlert[type]; + }, + + //------------------------------------------------------------------------- + alert2synctype: function(alert) { + for ( var key in constant.SyncTypeToAlert ) + { + if ( constant.SyncTypeToAlert[key] == alert ) + return exports.int(key); + } + return null; + }, + + //------------------------------------------------------------------------- + mode2string: function(code) { + switch ( code ) + { + case constant.ALERT_TWO_WAY: return 'two-way'; + case constant.ALERT_SLOW_SYNC: return 'slow-sync'; + case constant.ALERT_ONE_WAY_FROM_CLIENT: return 'one-way-from-client'; + case constant.ALERT_REFRESH_FROM_CLIENT: return 'refresh-from-client'; + case constant.ALERT_ONE_WAY_FROM_SERVER: return 'one-way-from-server'; + case constant.ALERT_REFRESH_FROM_SERVER: return 'refresh-from-server'; + case constant.ALERT_TWO_WAY_BY_SERVER: return 'two-way-by-server'; + case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: return 'one-way-from-client-by-server'; + case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: return 'refresh-from-client-by-server'; + case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: return 'one-way-from-server-by-server'; + case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: return 'refresh-from-server-by-server'; + default: return 'UNKNOWN'; + } + }, + + //------------------------------------------------------------------------- + state2string: function(state) { + switch ( state ) + { + case constant.ITEM_OK: return 'ok'; + case constant.ITEM_ADDED: return 'added'; + case constant.ITEM_MODIFIED: return 'modified'; + case constant.ITEM_DELETED: return 'deleted'; + case constant.ITEM_SOFTDELETED: return 'soft-deleted'; + default: return 'UNKNOWN'; + } + }, + + //------------------------------------------------------------------------- + oneWay: function(mode) { + switch ( mode ) + { + case constant.ALERT_TWO_WAY: + case constant.ALERT_SLOW_SYNC: + return false; + case constant.ALERT_ONE_WAY_FROM_CLIENT: + case constant.ALERT_REFRESH_FROM_CLIENT: + case constant.ALERT_ONE_WAY_FROM_SERVER: + case constant.ALERT_REFRESH_FROM_SERVER: + return true; + // case constant.ALERT_TWO_WAY_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: + default: + throw new exports.InternalError('invalid mode "' + mode + '"'); + } + }, + + //------------------------------------------------------------------------- + oneWayIn: function(session, mode) { + switch ( mode ) + { + case constant.ALERT_TWO_WAY: + case constant.ALERT_SLOW_SYNC: + return false; + case constant.ALERT_ONE_WAY_FROM_CLIENT: + case constant.ALERT_REFRESH_FROM_CLIENT: + return !! session.isServer; + case constant.ALERT_ONE_WAY_FROM_SERVER: + case constant.ALERT_REFRESH_FROM_SERVER: + return ! session.isServer; + // case constant.ALERT_TWO_WAY_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: + default: + throw new exports.InternalError('invalid mode "' + mode + '"'); + } + }, + + //------------------------------------------------------------------------- + oneWayOut: function(session, mode) { + switch ( mode ) + { + case constant.ALERT_TWO_WAY: + case constant.ALERT_SLOW_SYNC: + return false; + case constant.ALERT_ONE_WAY_FROM_CLIENT: + case constant.ALERT_REFRESH_FROM_CLIENT: + return ! session.isServer; + case constant.ALERT_ONE_WAY_FROM_SERVER: + case constant.ALERT_REFRESH_FROM_SERVER: + return !! session.isServer; + // case constant.ALERT_TWO_WAY_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: + default: + throw new exports.InternalError('invalid mode "' + mode + '"'); + } + }, + + //------------------------------------------------------------------------- + cascade: function(list, iterator, cb) { + if ( ! cb && iterator ) + { + cb = iterator; + iterator = null; + } + if ( ! list ) + return cb(); + var cur = 0; + var next = function() { + if ( cur >= list.length ) + return cb(); + var curcb = function(err) { + if ( err ) + return cb(err); + cur += 1; + var args = []; + for ( var idx=1 ; idx b ) + return 1; + return 0; + }, + + //------------------------------------------------------------------------- + // partially emulates python's string.split() method + splitn: function(str, sep, limit) { + var ret = str.split(sep); + if ( ret.length <= ( limit + 1 ) ) + return ret; + var tmp = ret.slice(0, limit); + tmp.push(ret.slice(limit).join(sep)); + return tmp; + }, + + //------------------------------------------------------------------------- + prettyJson: function(obj, indent) { + indent = indent || ''; + var ret = ''; + if ( _.isArray(obj) ) + { + if ( obj.length <= 0 ) + return '[]'; + ret = '[\n' + indent; + _.each(obj, function(el, idx) { + ret += ' ' + exports.prettyJson(el, indent + ' '); + if ( idx + 1 < obj.length ) + ret += ','; + ret += '\n' + indent; + }); + return ret + ']'; + } + if ( _.isObject(obj) ) + { + var keys = _.keys(obj); + if ( keys.length <= 0 ) + return '{}'; + keys.sort(); + ret = '{\n' + indent; + _.each(keys, function(key, idx) { + ret += ' ' + exports.prettyJson(key) + + ': ' + exports.prettyJson(obj[key], indent + ' '); + if ( idx + 1 < keys.length ) + ret += ','; + ret += '\n' + indent; + }); + return ret + ( indent.length <= 0 ? '}\n' : '}' ); + } + return JSON.stringify(obj); + }, + + //------------------------------------------------------------------------- + urlEncode: function(dat) { + return ( dat == undefined ? dat : encodeURIComponent(dat) ); + }, + + //------------------------------------------------------------------------- + /* + rmfr: function(path, cb) { + fs.stat(path, function(err, stats) { + if ( err && err.code == 'ENOENT' ) + return cb(); + if ( err ) + return cb(err); + if ( ! stats.isDirectory() ) + return fs.unlink(path, cb); + fs.readdir(path, function(err, files) { + exports.cascade(files, function(file, cb) { + var curpath = pathmod.join(path, file); + return exports.rmfr(curpath, cb); + }, function(err) { + if ( err ) + return cb(err); + fs.rmdir(path, cb); + }); + }); + }); + }, + */ + //------------------------------------------------------------------------- + /* + makedirs: function(path, cb) { + // node sucks. i can't believe it doesn't provide a fs.makedirs(). wtf. + // clean up the path + path = pathmod.normalize(path.split(/[\\\/]/).join('/')); + var paths = path.split('/'); + paths = _.map(paths, function(p, idx) { + return paths.slice(0, idx + 1).join('/'); + }); + if ( path.charAt(0) == '/' ) + paths.shift(); + exports.cascade(paths, function(path, cb) { + fs.stat(path, function(err, stats) { + if ( err && err.code == 'ENOENT' ) + return fs.mkdir(path, cb); + if ( err ) + return cb(err); + if ( stats.isDirectory() ) + return cb(); + // this probably won't work, but let's get the error anyhow... + return fs.mkdir(path, cb); + }); + }, cb); + }, + */ + + //------------------------------------------------------------------------- + StringStream: exports.Stream.extend({ + + constructor: function(initData) { + this._data = initData || ''; + }, + + write: function(data) { + if ( data == undefined ) + return; + this._data += data; + }, + + getData: function() { + return this._data; + } + + }), + + //------------------------------------------------------------------------- + IndentStream: exports.Stream.extend({ + + //----------------------------------------------------------------------- + constructor: function(stream, indent, options) { + options = options || {}; + this._stream = stream; + this._indent = indent || ' '; + this._cleared = true; + this._stayBlank = !! options.stayBlank; + }, + + //----------------------------------------------------------------------- + write: function(data) { + var self = this; + if ( data == undefined ) + return; + // if ( ! data || ! data.length || data.length <= 0 ) + // return; + var lines = data.split('\n'); + if ( self._cleared ) + self._stream.write(self._indent); + self._cleared = false; + for ( var idx=0 ; idx= lines.length ) + self._cleared = true; + else + { + if ( idx != 0 && ! self._stayBlank ) + self._stream.write(self._indent); + } + } + else + { + if ( idx != 0 || self._cleared ) + self._stream.write(self._indent); + self._stream.write(line); + } + if ( idx + 1 < lines.length ) + self._stream.write('\n'); + } + } + + }) + + }); + + return exports; +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/constant', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// desc: SyncML constants +// auth: metagriffin +// date: 2012/10/13 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var _self = { + // SyncML versions + SYNCML_VERSION_1_0 : 'SyncML/1.0', + SYNCML_VERSION_1_1 : 'SyncML/1.1', + SYNCML_VERSION_1_2 : 'SyncML/1.2', + SYNCML_DTD_VERSION_1_0 : '1.0', + SYNCML_DTD_VERSION_1_1 : '1.1', + SYNCML_DTD_VERSION_1_2 : '1.2', + + // SyncML alert/sync codes + ALERT_DISPLAY : 100, + ALERT_TWO_WAY : 200, + ALERT_SLOW_SYNC : 201, + ALERT_ONE_WAY_FROM_CLIENT : 202, + ALERT_REFRESH_FROM_CLIENT : 203, + ALERT_ONE_WAY_FROM_SERVER : 204, + ALERT_REFRESH_FROM_SERVER : 205, + ALERT_TWO_WAY_BY_SERVER : 206, + ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER : 207, + ALERT_REFRESH_FROM_CLIENT_BY_SERVER : 208, + ALERT_ONE_WAY_FROM_SERVER_BY_SERVER : 209, + ALERT_REFRESH_FROM_SERVER_BY_SERVER : 210, + // alert codes 211-220 are reserved for future use + + // SyncML SyncCap SyncTypes + SYNCTYPE_AUTO : null, + SYNCTYPE_TWO_WAY : 1, + SYNCTYPE_SLOW_SYNC : 2, + SYNCTYPE_ONE_WAY_FROM_CLIENT : 3, + SYNCTYPE_REFRESH_FROM_CLIENT : 4, + SYNCTYPE_ONE_WAY_FROM_SERVER : 5, + SYNCTYPE_REFRESH_FROM_SERVER : 6, + SYNCTYPE_SERVER_ALERTED : 7, + + // Special syncml-js SyncTypes + SYNCTYPE_DISCOVER : 'discover', + + // SyncML synctype-to-alertcode mapping + // taking advantage of the fact that 1..7 maps to 200..206 + // (more or less... "7" is a bit "nebulous"...) + SyncTypeToAlert: _.object(_.map(_.range(7), function(i) { + return [ i + 1, i + 200 ]; + })), + + // Conflict handling policies + POLICY_ERROR : 1, + POLICY_CLIENT_WINS : 2, + POLICY_SERVER_WINS : 3, + + // SyncML XML namespaces + NAMESPACE_SYNCML_1_0 : 'syncml:syncml1.0', + NAMESPACE_SYNCML_1_1 : 'syncml:syncml1.1', + NAMESPACE_SYNCML_1_2 : 'syncml:syncml1.2', + NAMESPACE_METINF : 'syncml:metinf', + NAMESPACE_DEVINF : 'syncml:devinf', + NAMESPACE_AUTH_BASIC : 'syncml:auth-basic', + NAMESPACE_AUTH_MD5 : 'syncml:auth-md5', + NAMESPACE_FILTER_CGI : 'syncml:filtertype-cgi', + + // Commonly used content-types + TYPE_TEXT_PLAIN : 'text/plain', + TYPE_VCARD_V21 : 'text/x-vcard', + TYPE_VCARD_V30 : 'text/vcard', + TYPE_VCALENDAR : 'text/x-vcalendar', + TYPE_ICALENDAR : 'text/calendar', + TYPE_MESSAGE : 'text/message', + TYPE_SYNCML : 'application/vnd.syncml', + TYPE_SYNCML_DEVICE_INFO : 'application/vnd.syncml-devinf', + TYPE_SYNCML_ICALENDAR : 'application/vnd.syncml-xcal', + TYPE_SYNCML_EMAIL : 'application/vnd.syncml-xmsg', + TYPE_SYNCML_BOOKMARK : 'application/vnd.syncml-xbookmark', + TYPE_SYNCML_RELATIONAL_OBJECT : 'application/vnd.syncml-xrelational', + TYPE_OMADS_FOLDER : 'application/vnd.omads-folder', + TYPE_OMADS_FILE : 'application/vnd.omads-file', + TYPE_OMADS_EMAIL : 'application/vnd.omads-email', + TYPE_SQL : 'application/sql', + TYPE_LDAP : 'text/directory', + TYPE_EMAIL : 'message/rfc2822', + TYPE_EMAIL_822 : 'message/rfc822', + TYPE_SIF_CONTACT : 'text/x-s4j-sifc', + TYPE_SIF_NOTE : 'text/x-s4j-sifn', + TYPE_SIF_TASK : 'text/x-s4j-sift', + TYPE_SIF_EVENT : 'text/x-s4j-sife', + + // non-agent URI paths + URI_DEVINFO_1_0 : 'devinf10', + URI_DEVINFO_1_1 : 'devinf11', + URI_DEVINFO_1_2 : 'devinf12', + + // Response codes - Generic + STATUS_INVALID_CODE : 0, + // Response codes - Informational 1xx + STATUS_IN_PROGRESS : 101, + // Response codes - Successful 2xx + STATUS_OK : 200, + STATUS_ITEM_ADDED : 201, + STATUS_ACCEPTED_FOR_PROCESSING : 202, + STATUS_NONAUTHORIATATIVE_RESPONSE : 203, + STATUS_NO_CONTENT : 204, + STATUS_RESET_CONTENT : 205, + STATUS_PARTIAL_CONTENT : 206, + STATUS_CONFLICT_RESOLVED_MERGE : 207, + STATUS_CONFLICT_RESOLVED_CLIENT_DATA : 208, + STATUS_CONFLICT_RESOLVED_DUPLICATE : 209, + STATUS_DELETE_WITHOUT_ARCHIVE : 210, + STATUS_ITEM_NOT_DELETED : 211, + STATUS_AUTHENTICATION_ACCEPTED : 212, + STATUS_CHUNKED_ITEM_ACCEPTED : 213, + STATUS_OPERATION_CANCELLED_OK : 214, + STATUS_NOT_EXECUTED : 215, + STATUS_ATOMIC_ROLLBACK_OK : 216, + STATUS_RESULT_ALERT : 221, + STATUS_NEXT_MESSAGE : 222, + STATUS_NO_END_OF_DATA : 223, + STATUS_SUSPEND : 224, + STATUS_RESUME : 225, + STATUS_DATA_MANAGEMENT : 226, + // status codes 227-250 are reserved for future use, + // Response codes - Redirection 3xx + STATUS_MULTIPLE_CHOICES : 300, + STATUS_MOVED_PERMANENTLY : 301, + STATUS_FOUND : 302, + STATUS_SEE_ANOTHER_URI : 303, + STATUS_NOT_MODIFIED : 304, + STATUS_USE_PROXY : 305, + // Response codes - Originator Exceptions 4xx + STATUS_BAD_REQUEST : 400, + STATUS_INVALID_CREDENTIALS : 401, + STATUS_PAYMENT_REQUIRED : 402, + STATUS_FORBIDDEN : 403, + STATUS_NOT_FOUND : 404, + STATUS_COMMAND_NOT_ALLOWED : 405, + STATUS_OPTIONAL_FEATURE_NOT_SUPPORTED : 406, + STATUS_MISSING_CREDENTIALS : 407, + STATUS_REQUEST_TIMEOUT : 408, + STATUS_UPDATE_CONFLICT : 409, + STATUS_GONE : 410, + STATUS_SIZE_REQUIRED : 411, + STATUS_INCOMPLETE_COMMAND : 412, + STATUS_REQUESTED_ENTITY_TOO_LARGE : 413, + STATUS_URI_TOO_LONG : 414, + STATUS_UNSUPPORTED_MEDIA_TYPE : 415, + STATUS_REQUESTED_SIZE_TOO_BIG : 416, + STATUS_RETRY_LATER : 417, + STATUS_ALREADY_EXISTS : 418, + STATUS_CONFLICT_RESOLVED_SERVER_DATA : 419, + STATUS_DEVICE_FULL : 420, + STATUS_UNKNOWN_SEARCH_GRAMMAR : 421, + STATUS_BAD_CGI_SCRIPT : 422, + STATUS_SOFT_DELETE_CONFLICT : 423, + STATUS_OBJECT_SIZE_MISMATCH : 424, + STATUS_PERMISSION_DENIED : 425, + // Response codes - Recipient Exceptions 5xx + STATUS_COMMAND_FAILED : 500, + STATUS_NOT_IMPLEMENTED : 501, + STATUS_BAD_GATEWAY : 502, + STATUS_SERVICE_UNAVAILABLE : 503, + STATUS_GATEWAY_TIMEOUT : 504, + STATUS_VERSION_NOT_SUPPORTED : 505, + STATUS_PROCESSING_ERROR : 506, + STATUS_ATOMIC_FAILED : 507, + STATUS_REFRESH_REQUIRED : 508, + STATUS_RECIPIENT_EXCEPTION_RESERVED1 : 509, + STATUS_DATASTORE_FAILURE : 510, + STATUS_SERVER_FAILURE : 511, + STATUS_SYNCHRONIZATION_FAILED : 512, + STATUS_PROTOCOL_VERSION_NOT_SUPPORTED : 513, + STATUS_OPERATION_CANCELLED : 514, + STATUS_ATOMIC_ROLLBACK_FAILED : 516, + STATUS_ATOMIC_RESPONSE_TOO_LARGE_TO_FIT : 517, + + // SyncML codecs + CODEC_XML : 'xml', + CODEC_WBXML : 'wbxml', + FORMAT_B64 : 'b64', + FORMAT_AUTO : 'auto', + + // SyncML nodes + NODE_SYNCML : 'SyncML', + NODE_SYNCBODY : 'SyncBody', + + // SyncML commands + CMD_SYNCHDR : 'SyncHdr', + CMD_SYNC : 'Sync', + CMD_ALERT : 'Alert', + CMD_STATUS : 'Status', + CMD_GET : 'Get', + CMD_PUT : 'Put', + CMD_ADD : 'Add', + CMD_REPLACE : 'Replace', + CMD_DELETE : 'Delete', + CMD_RESULTS : 'Results', + CMD_ATOMIC : 'Atomic', + CMD_COPY : 'Copy', + CMD_EXEC : 'Exec', + CMD_MAP : 'Map', + CMD_MAPITEM : 'MapItem', + CMD_SEARCH : 'Search', + CMD_SEQUENCE : 'Sequence', + CMD_FINAL : 'Final', + + // SyncML standard device types + DEVTYPE_HANDHELD : 'handheld', + DEVTYPE_PAGER : 'pager', + DEVTYPE_PDA : 'pda', + DEVTYPE_PHONE : 'phone', + DEVTYPE_SERVER : 'server', + DEVTYPE_SMARTPHONE : 'smartphone', + DEVTYPE_WORKSTATION : 'workstation', + + // Item status codes + ITEM_OK : 0, + ITEM_ADDED : 1, + ITEM_MODIFIED : 2, + ITEM_DELETED : 3, + ITEM_SOFTDELETED : 4, +}; + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/context', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.context +// auth: griffin +// date: 2012/10/22 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'), + router = require('ripple/platform/tizen/2.0/syncml-js-lib/router'), + synchronizer = require('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer'), + protocol = require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'), + localadapter = require('ripple/platform/tizen/2.0/syncml-js-lib/localadapter'), + idxdb = {}, + _self; + +// todo: is this the right place to put this?... +// the reason that i did not put it in the `define` call is +// because it needs access to `this.indexedDB`... +var idxdb = {}; +if ( typeof(window) != 'undefined' && window.indexedDB ) +{ + idxdb.indexedDB = window.indexedDB; + idxdb.IDBKeyRange = window.IDBKeyRange; +} +else +{ + idxdb.indexedDB = this.indexedDB; + idxdb.IDBKeyRange = this.IDBKeyRange; +} + +_self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + exports.Context = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(options) { + // options.storage expects the following properties: + // - indexedDB + // - IDBKeyRange + options = options || {}; + this.storage = options.storage || idxdb; + this.dbname = ( options.prefix || '' ) + 'syncml-js'; + this.autoCommit = options.autoCommit == undefined ? true : options.autoCommit; + this.router = options.router || new router.SmartRouter(); + this.synchronizer = options.synchronizer || new synchronizer.Synchronizer(); + this.protocol = options.protocol || new protocol.Protocol(); + this.codec = options.codec || constant.CODEC_XML; + this.listener = options.listener; + this.ua = options.ua; + this.config = _.defaults({}, options.config, { + trustDevInfo : false, + exposeErrorTrace : false + }); + this._db = null; + this._dbtxn = null; + }, + + //------------------------------------------------------------------------- + getAdapter: function(options, devInfo, cb) { + options = options || {}; + var self = this; + if ( this._db == undefined ) + { + storage.openDatabase(this, function(err, db) { + if ( err ) { + return cb(err); + } + self._db = db; + self._db.onerror = function(event) { + // todo: remove this?... + }; + self._dbtxn = storage.getTransaction(self._db, null, 'readwrite'); + self.getAdapter(options, devInfo, cb); + }); + } + else + { + var ret = new localadapter.LocalAdapter(this, options, devInfo); + return ret._load(cb); + } + }, + + //------------------------------------------------------------------------- + _txn: function() { + try { + // this is a work-around for XPC-based syncml... try to open + // a store, if it fails, we need a new transaction. + var store = this._dbtxn.objectStore('mapping'); + return this._dbtxn; + } catch ( exc ) { + this._dbtxn = storage.getTransaction(this._db, null, 'readwrite'); + return this._dbtxn; + } + }, + + //------------------------------------------------------------------------- + getEasyClientAdapter: function(options, cb) { + try{ + this._getEasyClientAdapter(options, cb); + }catch(e){ + cb(e); + } + }, + + //------------------------------------------------------------------------- + _getEasyClientAdapter: function(options, cb) { + // options should be:= { + // // devID, + // // displayName, + // devInfo: {}, + // stores: [], + // peer: {}, + // routes: [ + // [ source, target ], + // ] + // } + // response: cb(err, adapter, stores, peer); + + var self = this; + + var ret = { + adapter: null, + stores: [], + peer: null + }; + + var setupAdapter = function(cb) { + var adapterOptions = _.omit(options, 'devInfo', 'stores', 'peers', 'routes'); + self.getAdapter(adapterOptions, options.devInfo, function(err, adapter) { + if ( err ) { + return cb(err); + } + ret.adapter = adapter; + if ( adapter.devInfo ) { + return cb(); + } + adapter.setDevInfo(options.devInfo, cb); + }); + }; + + var setupStores = function(cb) { + common.cascade(options.stores, function(storeInfo, cb) { + var store = ret.adapter.getStore(storeInfo.uri); + if ( store != undefined ) + { + if ( storeInfo.agent ) { + store.agent = storeInfo.agent; + } + ret.stores.push(store); + return cb(); + } + ret.adapter.addStore(storeInfo, function(err, store) { + if ( err ) { + return cb(err); + } + ret.stores.push(store); + return cb(); + }); + }, cb); + }; + + var setupPeer = function(cb) { + var peer = _.find(ret.adapter.getPeers(), function(p) { + return p.url == options.peer.url; + }); + if ( peer ) + { + ret.peer = peer; + return cb(); + } + ret.adapter.addPeer(options.peer, function(err, peer) { + if ( err ) { + return cb(err); + } + ret.peer = peer; + common.cascade(options.routes, function(route, cb) { + ret.peer.setRoute(route[0], route[1], cb); + }, cb); + }); + }; + setupAdapter(function(err) { + if ( err ) { + return cb(err); + } + setupStores(function(err) { + if ( err ) { + return cb(err); + } + setupPeer(function(err) { + if ( err ) { + return cb(err); + } + cb(null, ret.adapter, ret.stores, ret.peer); + }); + }); + }); + }, + + //------------------------------------------------------------------------- + close: function(cb) { + if ( this._db ) + this._db.close(); + this._db = null; + cb(null); + } + + }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/ctype', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// auth: metagriffin +// date: 2012/10/13 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'), + _self; + +_self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + exports.ContentTypeInfo = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(ctype, versions, options) { + this.ctype = ctype; + this.versions = _.isArray(versions) ? versions : [versions]; + _.defaults(this, options || {}, { + preferred: false, + transmit: true, + receive: true, + }); + }, + + //------------------------------------------------------------------------- + merge: function(other) { + if ( this.ctype != other.ctype + || ! _.isEqual(this.versions, other.versions) + || this.preferred != other.preferred ) + return false; + this.transmit = this.transmit || other.transmit; + this.receive = this.receive || other.receive; + return true + }, + + //------------------------------------------------------------------------- + toStruct: function() { + return { + ctype: this.ctype, + versions: this.versions, + preferred: this.preferred, + transmit: this.transmit, + receive: this.receive + }; + }, + + //------------------------------------------------------------------------- + toSyncML: function(nodeName, uniqueVerCt) { + if ( _.isFunction(nodeName) ) + { + cb = nodeName; + nodeName = null; + } + else if ( _.isFunction(uniqueVerCt) ) + { + cb = uniqueVerCt; + uniqueVerCt = null; + } + if ( ! nodeName ) + { + nodeName = this.transmit ? 'Tx' : 'Rx'; + if ( this.preferred ) + nodeName += '-Pref'; + } + if ( this.preferred ) + nodeName += '-Pref'; + + if ( uniqueVerCt ) + { + var ret = _.map(this.versions, function(v) { + var tmp = ET.Element(nodeName); + ET.SubElement(tmp, 'CTType').text = this.ctype; + ET.SubElement(tmp, 'VerCT').text = v; + return tmp; + }, this); + return ret; + } + var ret = ET.Element(nodeName); + ET.SubElement(ret, 'CTType').text = this.ctype; + _.each(this.versions, function(v) { + ET.SubElement(ret, 'VerCT').text = v; + }); + return ret; + }, + + describe: function(stream, cb) { + stream.write(this.ctype); + stream.write(this.versions.length == 1 ? ' version ' : ' versions '); + stream.write(this.versions.join(', ')); + var flags = []; + if ( this.preferred ) + flags.push('preferred'); + if ( this.transmit ) + flags.push('tx'); + if ( this.receive ) + flags.push('rx'); + if ( flags.length > 0 ) + { + stream.write(' ('); + stream.write(flags.join(', ')); + stream.write(')'); + } + stream.write('\n'); + } + + }, { + + //------------------------------------------------------------------------- + fromStruct: function(struct) { + return new exports.ContentTypeInfo(struct.ctype, struct.versions, struct); + }, + + //------------------------------------------------------------------------- + fromSyncML: function(xnode) { + return new exports.ContentTypeInfo( + xnode.findtext('CTType'), + _.map(xnode.findall('VerCT'), function(e) { return e.text; }), + { + preferred: xnode.tag.match('-Pref$') != undefined, + transmit: xnode.tag.indexOf('Tx') >= 0, + receive: xnode.tag.indexOf('Rx') >= 0 + } + ); + } + + }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/devinfo', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.devinfo +// auth: griffin +// date: 2012/11/06 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'), + ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'), + _self; + +_self = (function () { + + var exports = {}; + + var strAttributeMap = [ + ['manufacturerName', 'Man'], + ['modelName', 'Mod'], + ['oem', 'OEM'], + ['firmwareVersion', 'FwV'], + ['softwareVersion', 'SwV'], + ['hardwareVersion', 'HwV'], + ['devID', 'DevID'], + ['devType', 'DevTyp'] + ]; + +var boolAttributeMap = [ + ['utc', 'UTC'], + ['largeObjects', 'SupportLargeObjs'], + ['hierarchicalSync', 'SupportHierarchicalSync'], + ['numberOfChanges', 'SupportNumberOfChanges'] + ]; + +//--------------------------------------------------------------------------- +exports.DevInfo = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(adapter, options) { + var self = this; + var options = _.defaults({}, options, { + devType : constant.DEVTYPE_WORKSTATION, + manufacturerName : '-', + modelName : '-', + oem : '-', + hardwareVersion : '-', + firmwareVersion : '-', + softwareVersion : '-', + utc : true, + largeObjects : true, + hierarchicalSync : true, + numberOfChanges : true, + extensions : {} + }); + + // todo: is there anyway to mark attributes as read-only?... + + //: [read-only] these are all read-only attributes + this.devID = options.devID || common.makeID(); + this.devType = options.devType; + this.manufacturerName = options.manufacturerName; + this.modelName = options.modelName; + this.oem = options.oem; + this.hardwareVersion = options.hardwareVersion; + this.firmwareVersion = options.firmwareVersion; + this.softwareVersion = options.softwareVersion; + this.utc = options.utc; + this.largeObjects = options.largeObjects; + this.hierarchicalSync = options.hierarchicalSync; + this.numberOfChanges = options.numberOfChanges; + this.extensions = {}; + + _.each(options.extensions, function(values, name) { + self.setExtension(name, values); + }); + + // --- private attributes + this._a = adapter; + }, + + //------------------------------------------------------------------------- + setExtension: function(name, values) { + this.extensions[name] = _.isArray(values) ? values : [values]; + }, + + //------------------------------------------------------------------------- + getExtensionKeys: function() { + return _.keys(this.extensions); + }, + + //------------------------------------------------------------------------- + getExtension: function(name) { + return this.extensions[name]; + }, + + //------------------------------------------------------------------------- + _load: function(cb) { + cb(); + }, + + //------------------------------------------------------------------------- + _updateModel: function(cb) { + if ( ! this._a._model ) + return cb('devinfo created on un-initialized adapter'); + this._a._model.devInfo = { + devID : this.devID, + devType : this.devType, + manufacturerName : this.manufacturerName, + modelName : this.modelName, + oem : this.oem, + hardwareVersion : this.hardwareVersion, + firmwareVersion : this.firmwareVersion, + softwareVersion : this.softwareVersion, + utc : this.utc, + largeObjects : this.largeObjects, + hierarchicalSync : this.hierarchicalSync, + numberOfChanges : this.numberOfChanges, + extensions : this.extensions + }; + cb(); + }, + + //------------------------------------------------------------------------- + toSyncML: function(dtdVersion, stores) { + dtdVersion = dtdVersion || constant.SYNCML_DTD_VERSION_1_2; + if ( dtdVersion != constant.SYNCML_DTD_VERSION_1_2 ) + throw new Error('unsupported DTD version "' + dtdVersion + '"') + var xret = ET.Element('DevInf', {'xmlns': constant.NAMESPACE_DEVINF}) + ET.SubElement(xret, 'VerDTD').text = dtdVersion; + for ( var idx=0 ; idx 0 ) + for ( var idx=0 ; idx", "text/xml"); + node = doc.childNodes[0]; + if (attributes) { + utils.forEach(attributes, function (value, key) { + node.setAttribute(key, value); + }); + } + + element = { + _doc: doc, + _node: node, + find: function (query) { + return _find(query, this, "NODE"); + }, + findtext: function (query) { + return _find(query, this, "TEXT"); + }, + findall: function (query) { + return _findall(query, this); + }, + getchildren: function () { + return _getchildren(this); + }, + append: function (node) { + this._node.appendChild(node._node); + }, + getroot: function () { + return this; } + }; + + element.__defineSetter__("text", function (text) { + this._node.textContent = text; }); - widgetInfo.preferences = {}; + element.__defineGetter__("text", function () { + return this._node.textContent; + }); - configPreferences = configValidationObject.widget.children.preference.validationResult; + element.__defineGetter__("tag", function () { + return _tag(this); + }); - platform = require('ripple/platform'); - utils.forEach(configPreferences, function (preference) { - preferenceName = preference.attributes.name.value; - if (preferenceName) { - widgetInfo.preferences[preferenceName] = { - "key": preferenceName, - "value": preference.attributes.value.value || "", - "readonly": preference.attributes.readonly.value === "true" - }; + return element; + }; - db.save(preferenceName, - widgetInfo.preferences[preferenceName].value, - platform.getPersistencePrefix(widgetInfo.id)); + ET.SubElement = function(element, name, attributes) { + var subElement = {}, + node; + node = element._doc.createElement(name); + if (attributes) { + utils.forEach(attributes, function (value, key) { + node.setAttribute(key, value); + }); + } + element._node.appendChild(node); + subElement = { + _doc: element._doc, + _node: node, + find: function (query) { + return _find(query, this, "NODE"); + }, + findtext: function (query) { + return _find(query, this, "TEXT"); + }, + findall: function (query) { + return _findall(query, this); + }, + getchildren: function () { + return _getchildren(this); + }, + append: function (node) { + this._node.appendChild(node._node); + }, + getroot: function () { + return this; } + }; + subElement.__defineSetter__("text", function (text) { + this._node.textContent = text; + }); + subElement.__defineGetter__("text", function () { + return this._node.textContent; + }); + subElement.__defineGetter__("tag", function () { + return _tag(this); }); - return widgetInfo; - }, - schema: { - rootElement: "widget", - widget: { - nodeName: "widget", - required: true, - occurrence: 1, - helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in the configuration document and may have the following child elments: name,description,icon,author,license,content,feature and preference.The \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir", - attributes: { - xmlns: { - attributeName: "xmlns", - required: true, - type: "list", - listValues: ["http://www.w3.org/ns/widgets"] - }, - "xmlns:tizen": { - attributeName: "xmlns:tizen", - required: false, - type: "list", - listValues: ["http://tizen.org/ns/widgets"] - }, - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language" - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - id: { - attributeName: "id", - required: false, - type: "string" - }, - version: { - attributeName: "version", - required: false, - type: "string" - }, - height: { - attributeName: "height", - required: false, - type: "integer" - }, - width: { - attributeName: "width", - required: false, - type: "integer" - }, - viewmodes: { - attributeName: "viewmodes", - required: false, - type: "list", - listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"] - }, - defaultlocale: { - attributeName: "defaultlocale", - required: false, - type: "iso-language" - }, + return subElement; + }; + + ET.tostring = function(element) { + return _serializer.serializeToString(element._node); + }; + ET.parse = function(doc) { + var element = {}; + + element = { + _doc: doc, + _node: doc.childNodes[0], + find: function (query) { + return _find(query, this, "NODE"); }, - children: { - name: { - nodeName: "name", - required: false, - occurrence: 0, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - unique: true - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - "short": { - attributeName: "short", - required: false, - type: "string" - } - }, - children: { - span: { - nodeName: "span", - required: false, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - unique: true - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - } - } - } - } - }, - description: { - nodeName: "description", - required: false, - occurrence: 0, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - unique: true - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - } - }, - children: { - span: { - nodeName: "span", - required: false, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - unique: true - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - } - } - } - } - }, - author: { - nodeName: "author", - required: false, - occurrence: 0, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - href: { - attributeName: "href", - required: false, - type: "regex", - regex: constants.REGEX.URL - }, - email: { - attributeName: "email", - required: false, - type: "regex", - regex: constants.REGEX.EMAIL - } - }, - children: { - span: { - nodeName: "span", - required: false, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - unique: true - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - } - } - } - } - }, - license: { - nodeName: "license", - required: false, - occurrence: 0, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - href: { - attributeName: "href", - type: "regex", - required: false, - regex: constants.REGEX.URL - } - }, - children: { - span: { - nodeName: "span", - required: false, - type: "string", - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - unique: true - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - } - } - } - } - }, - icon: { - nodeName: "icon", - required: false, - occurrence: 0, - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - src: { - attributeName: "src", - required: true, - type: "string" - }, - width: { - attributeName: "width", - required: false, - type: "integer" - }, - height: { - attributeName: "height", - required: false, - type: "integer" - } - } - }, - content: { - nodeName: "content", - required: false, - occurrence: 1, - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - unique: true - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - src: { - attributeName: "src", - required: true, - type: "string" - }, - encoding: { - attributeName: "encoding", - required: false, - type: "string" - }, - type: { - attributeName: "type", - required: false, - type: "string" - } - } - }, - setting: { - nodeName: "tizen:setting", - required: false, - occurrence: 0, - attributes: { - 'screen-orientation': { - attributeName: "screen-orientation", - required: false, - type: "list", - listValues: ['portrait', 'landscape'] - }, - 'context-menu': { - attributeName: "context-menu", - required: false, - type: "list", - listValues: ['enable', 'disable'] - }, - 'background-support': { - attributeName: "background-support", - required: false, - type: "list", - listValues: ['enable', 'disable'] + findtext: function (query) { + return _find(query, this, "TEXT"); + }, + findall: function (query) { + return _findall(query, this); + }, + getchildren: function () { + return _getchildren(this); + }, + append: function (node) { + this._node.appendChild(node._node); + }, + getroot: function () { + return this; + } + }; + element.__defineSetter__("text", function (text) { + this._node.textContent = text; + }); + element.__defineGetter__("text", function () { + return this._node.textContent; + }); + element.__defineGetter__("tag", function () { + return _tag(this); + }); + + return element; + }; + + ET.CdataElement = function(str) { + var doc, cdata; + doc = _parser.parseFromString("", "text/xml"); + cdata = doc.createCDATASection(str); + return cdata; + }; + + return ET; +})(); + +_parser = new DOMParser(); +_serializer = new XMLSerializer(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/item', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.item +// auth: griffin +// date: 2012/11/30 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'); + +var _self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + exports.Item = common.Base.extend({ + + //: the unique identifier (within the context of a SyncML datastore) + //: of the current SyncML item. + id: null, + + compare: function(other) { + return ( other === this ? 0 : 1 ); + } + + }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/localadapter', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.localadapter +// auth: griffin +// date: 2012/10/22 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + codec = require('ripple/platform/tizen/2.0/syncml-js-lib/codec'), + storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'), + remote = require('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter'), + storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'), + devinfomod = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'), + adapter = require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'), + state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'), + useragent = require('ripple/platform/tizen/2.0/syncml-js-lib/useragent'), + _self; + +_self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + exports.LocalAdapter = adapter.Adapter.extend({ + + //------------------------------------------------------------------------- + constructor: function(context, options, devInfo) { + + // todo: is there anyway to mark attributes as read-only?... + + //: [read-only] devInfo describes this adapter's device info and + //: capabilities. + this.devInfo = null; + + //: [read-only] the device ID of this adapter. + this.devID = options.devID || null; + + //: [read-only] specifies whether this Adapter represents a local + //: or remote peer. + this.isLocal = true; + + //: [read-only] human-facing name of this adapter + this.displayName = options.displayName || null; + + //: [read-only] the adapter-wide default value of the maximum + //: message size. + this.maxMsgSize = options.maxMsgSize || null; + + //: [read-only] the adapter-wide default value of the maximum + //: object size. + this.maxObjSize = options.maxObjSize || null; + + //: [read-only] specifies default conflict resolution policy for + //: this adapter. if undefined, defaults to constant.POLICY_ERROR. + this.conflictPolicy = options.conflictPolicy || constant.POLICY_ERROR; + + // --- private attributes + this.id = options.id || common.makeID(); + this._c = context; + // TODO: use _.pick() for these options... + this._options = options; + this._devInfo = devInfo; + this._model = null; + this._stores = {}; + this._peers = []; + }, + + //------------------------------------------------------------------------- + _getModel: function() { + return this._model; + }, + + //------------------------------------------------------------------------- + setDevInfo: function(devInfo, cb) { + if ( this._model == undefined ) + this._model = { + id : this.id, + displayName : this.displayName, + maxMsgSize : this.maxMsgSize, + maxObjSize : this.maxObjSize, + conflictPolicy : this.conflictPolicy, + devInfo : null, + stores : [], + peers : [], + isLocal : 1 + }; + + var di = new devinfomod.DevInfo(this, devInfo); + di._updateModel(_.bind(function(err) { + if ( err ) + return cb(err); + + this._model.devID = this._model.devInfo.devID; + this.devID = this._model.devInfo.devID; + this.devInfo = di; + + // since the local devinfo has changed, we need to ensure that + // we rebroadcast it (in case there are any affects...), thus + // resetting all anchors. + // TODO: this seems a little heavy-handed, since this will force + // a slow-sync for each datastore. is that really the best + // thing?... + this._resetAllAnchors(); + + this._save(this._c._txn(), cb); + + }, this)); + }, + + //------------------------------------------------------------------------- + _resetAllAnchors: function() { + _.each(this._model.peers, function(peer) { + _.each(peer.stores, function(store) { + if ( ! store.binding ) + return; + store.binding.localAnchor = null; + store.binding.remoteAnchor = null; + }); + }); + }, + + //------------------------------------------------------------------------- + getPeers: function() { + return this._peers; + }, + + //------------------------------------------------------------------------- + addPeer: function(peerInfo, cb) { + var self = this; + + // TODO: if there is already a peer for the specified URL, then + // we may have a problem!... + + // todo: if we are adding a peer to an adapter that already has + // non-client peers, then we may have a problem!... + // (this is only true while syncml-js is not capable of truly + // operating in peer-to-peer mode) + + var peer = new remote.RemoteAdapter(this, peerInfo); + peer._updateModel(function(err) { + if ( err ) + return cb(err); + self._peers.push(peer); + cb(null, peer); + }); + }, + + //------------------------------------------------------------------------- + save: function(cb) { + this._save(this._c._txn(), cb); + }, + + //------------------------------------------------------------------------- + _save: function(dbtxn, cb) { + var self = this; + self._updateModel(function(err) { + if ( err ) + return cb(err); + storage.put(dbtxn.objectStore('adapter'), self._model, cb); + }); + }, + + //------------------------------------------------------------------------- + _updateModel: function(cb) { + var self = this; + var model = self._model; + model.displayName = self.displayName; + model.devID = self.devID; + model.maxMsgSize = self.maxMsgSize; + model.maxObjSize = self.maxObjSize; + model.conflictPolicy = self.conflictPolicy; + model.isLocal = 1; + common.cascade([ + // update the devInfo model + function(cb) { + if ( ! self.devInfo ) + return cb(); + return self.devInfo._updateModel(cb); }, - 'encryption': { - attributeName: "encryption", - required: true, - type: "list", - listValues: ['enable', 'disable'] + // update the stores model + function(cb) { + model.stores = []; + common.cascade(_.values(self._stores), function(store, cb) { + store._updateModel(cb); + }, cb); }, - 'install-location': { - attributeName: "install-location", - required: false, - type: "list", - listValues: ['auto', 'internal-only', 'perfer-external'] + + // update the peers model + function(cb) { + // NOTE: unlike stores, which can completely regenerate the + // model based on the class, the peers store binding + // and routing info is only in the model, so cannot be + // completely deleted... + common.cascade(self._peers, function(peer, cb) { + peer._updateModel(cb); + }, cb); + } + + ], cb); + }, + + //------------------------------------------------------------------------- + _load: function(cb) { + var self = this; + + // TODO: if options specifies a devID/name/etc, use that... + + storage.getAll( + this._c, + this._c._txn().objectStore('adapter').index('isLocal'), + {only: 1}, + function(err, adapters) { + if ( err ) { + return cb(err); } + if ( adapters.length > 1 ) + return cb('multiple local adapters defined - specify which devID to load'); + if ( adapters.length <= 0 ) + return cb(null, self); + self._loadModel(adapters[0], function(err) { + if ( err ) + return cb(err); + return cb(null, self); + }); } - }, - application: { - nodeName: "tizen:application", - required: true, - occurrence: 1, - attributes: { - id: { - attributeName: "id", - required: true, - type: "string" + ); + }, + + //------------------------------------------------------------------------- + _loadModel: function(model, cb) { + var self = this; + self._model = model; + self.displayName = model.displayName; + self.devID = model.devID; + self.maxMsgSize = model.maxMsgSize; + self.maxObjSize = model.maxObjSize; + self.conflictPolicy = model.conflictPolicy; + common.cascade([ + // load device info + function(cb) { + var di = new devinfomod.DevInfo(self, self._model.devInfo); + di._load(function(err) { + if ( err ) + return cb(err); + self.devInfo = di; + cb(); + }); }, - required_version: { - attributeName: "required_version", - required: true, - type: "string" + // load stores + function(cb) { + common.cascade(model.stores, function(e, cb) { + var store = new storemod.Store(self, e); + store._load(function(err) { + if ( err ) + return cb(err); + self._stores[store.uri] = store; + return cb(); + }); + }, cb); }, - package: { - attributeName: "package", - required: false, - type: "string" + // load peers + function(cb) { + var remotes = _.filter(model.peers, function(e) { + return ! e.isLocal; + }); + self._peers = []; + common.cascade(remotes, function(e, cb) { + var peer = new remote.RemoteAdapter(self, e); + peer._load(function(err) { + if ( err ) + return cb(err); + self._peers.push(peer); + return cb(); + }); + }, cb); } + ], cb); + }, + + //------------------------------------------------------------------------- + sync: function(peer, mode, options, cb) { + // `options` is optional and can have the following properties: + // * `ua` + + // TODO: initialize a new context transaction?... + // todo: or perhaps add a new session.txn?... + + if ( cb == undefined && _.isFunction(options) ) + { + cb = options; + options = {}; + } + options = options || {}; + + var self = this; + var discover = ( mode == constant.SYNCTYPE_DISCOVER ); + if ( discover ) + mode = constant.SYNCTYPE_SLOW_SYNC; + + if ( ! _.find(self._peers, function(p) { return p === peer; }) ) + return cb(new common.InvalidAdapter('invalid peer for adapter')); + if ( mode != constant.SYNCTYPE_AUTO ) + { + mode = common.synctype2alert(mode); + if ( ! mode ) + return cb(new common.TypeError('invalid synctype')); + } + if ( ! self.devInfo ) + return cb(new common.InvalidAdapter('cannot synchronize adapter as client: invalid devInfo')); + + var session = state.makeSession({ + context : self._c, + ua : new useragent.UserAgentMultiplexer([options.ua, self._c.ua]), + txn : _.bind(self._c._txn, self._c), + adapter : self, + peer : peer, + isServer : false, + discover : discover, + info : state.makeSessionInfo({ + id : ( peer.lastSessionID || 0 ) + 1, + msgID : 1, + codec : self._c.codec, + mode : mode + }) + }); + + session.send = function(contentType, data, cb) { + session.peer.sendRequest(session, contentType, data, function(err, response) { + if ( err ) + return cb(err); + // todo: allow the client to force the server to authorize itself as well... + self._receive(session, response, null, cb); + }); + }; + + // TODO: should i do a router.calculate() at this point? + // the reason is that if there was a sync, then a + // .setRoute(), then things may have changed... + // corner-case, yes... but still valid. + + var failed = 0; + + var startSession = function() { + session.context.protocol.initialize(session, null, function(err, commands) { + if ( err ) + return cb(err); + self._transmit(session, commands, function(err) { + if ( err ) + { + if ( ! ( err instanceof common.InvalidCredentials ) + && ! ( err instanceof common.CredentialsRequired ) ) + return cb(err); + if ( err instanceof common.InvalidCredentials ) + failed += 1; + if ( failed > 100 ) + { + return cb(err); } - }, - "tizen:content": { - nodeName: "tizen:content", - required: true, - occurrence: 1, - attributes: { - src: { - attributeName: "src", - required: true, - type: "string" - } + var credErr = err; + var uaEvent = { + session : session, + auth : err.auth, + count : failed + }; + return session.ua.fetchCredentials(uaEvent, function(err, auth) { + if ( err ) + return cb(err); + if ( ! auth ) + return cb(credErr); + if ( auth.persist ) + { + session.peer.auth = auth.type; + session.peer.username = auth.username; + session.peer.password = auth.password; } - }, - control: { - nodeName: "tizen:app-control", - required: false, - occurrence: 0, - children: { - src: { - nodeName: "tizen:src", - required: true, - occurence: 0, - attributes: { - name: { - attributeName: "name", - required: false, - type: "string" - } - } - }, - operation: { - nodeName: "tizen:operation", - required: true, - occurence: 0, - attributes: { - name: { - attributeName: "name", - required: false, - type: "string" - } - } - }, - uri: { - nodeName: "tizen:uri", - required: false, - occurence: 0, - attributes: { - name: { - attributeName: "name", - required: false, - type: "string" - } - } - }, - mime: { - nodeName: "tizen:mime", - required: false, - occurence: 0, - attributes: { - name: { - attributeName: "name", - required: false, - type: "string" - } - } + else + session.auth = auth; + // todo: should i just create a new session?... + session.info.id += 1; + session.info.msgID = 1; + return startSession(); + }); + } + self._save(session.txn(), function(err) { + if ( err ) + return cb(err); + return cb(null, self._session2stats(session)); + }); + }); + }); + }; + + session.context.synchronizer.initStoreSync(session, function(err) { + if ( err ) + return cb(err); + startSession(); + }); + + }, + + //------------------------------------------------------------------------- + _session2stats: function(session) { + var ret = {}; + _.each(_.values(session.info.dsstates), function(ds) { + var stats = _.clone(ds.stats); + stats.mode = common.alert2synctype(ds.mode); + if ( ds.action == 'error' && ds.error ) + stats.error = ds.error; + ret[ds.uri] = stats; + }); + return ret; + }, + + //------------------------------------------------------------------------- + _transmit: function(session, commands, cb) { + var self = this; + if ( session.info.msgID > 20 ) + return cb('too many client/server messages'); + session.context.protocol.negotiate(session, commands, function(err, commands) { + if ( err ) + return cb(err); + if ( session.context.protocol.isComplete(session, commands) ) + { + // we're done! store all the anchors and session IDs and exit... + var pmodel = session.peer._getModel(); + if ( ! pmodel ) + return cb('unexpected error: could not locate this peer in local adapter'); + _.each(session.info.dsstates, function(ds, uri) { + var pstore = _.find(pmodel.stores, function(s) { return s.uri == ds.peerUri; }); + if ( ! pstore ) + return cb('unexpected error: could not locate bound peer store in local adapter'); + pstore.binding.localAnchor = ds.nextAnchor; + pstore.binding.remoteAnchor = ds.peerNextAnchor; + }); + session.peer.lastSessionID = session.info.id; + pmodel.lastSessionID = session.info.id; + return cb(); + } + session.context.protocol.produce(session, commands, function(err, tree) { + if ( err ) + return cb(err); + codec.Codec.autoEncode(tree, session.info.codec, function(err, contentType, data) { + if ( err ) + return cb(err); + // update the session with the last request commands so + // that when we receive the response package, it can be + // compared against that. + // TODO: should that only be done on successful transmit?... + session.info.lastCommands = commands; + session.send(contentType, data, function(err) { + if ( err ) + return cb(err); + cb(); + }); + }) + }); + }); + }, + + //------------------------------------------------------------------------- + authorize: function(request, sessionInfo, authorize, cb) { + var self = this; + var ct = request.headers['Content-Type']; + codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) { + if ( err ) + return cb(err); + self._c.protocol.authorize(xtree, null, authorize, cb); + }); + }, + + //------------------------------------------------------------------------- + getTargetID: function(request, sessionInfo, cb) { + var self = this; + var ct = request.headers['Content-Type']; + codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) { + if ( err ) + return cb(err); + return cb(null, self._c.protocol.getTargetID(xtree)); + }); + }, + + //------------------------------------------------------------------------- + handleRequest: function(request, sessionInfo, authorize, response, options, cb) { + + // TODO: initialize a new context transaction?... + // todo: or perhaps add a new session.txn?... + + if ( cb == undefined && _.isFunction(options) ) + { + cb = options; + options = {}; + } + options = options || {}; + + var self = this; + var session = state.makeSession({ + context : self._c, + ua : new useragent.UserAgentMultiplexer([options.ua, self._c.ua]), + txn : _.bind(self._c._txn, self._c), + adapter : self, + peer : null, + isServer : true, + info : sessionInfo + }); + session.send = response; + this._receive(session, request, authorize, function(err, stats) { + if ( err ) + return cb(err); + self._save(session.txn(), function(err) { + if ( err ) + return cb(err); + return cb(null, self._session2stats(session)); + }); + }); + }, + + //------------------------------------------------------------------------- + _receive: function(session, request, authorize, cb) { + var self = this; + if ( ! session.isServer ) + { + session.info.lastMsgID = session.info.msgID; + session.info.msgID += 1; + } + var ct = request.headers['Content-Type']; + codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) { + if ( err ) + return cb(err); + session.info.codec = codecName; + var do_authorize = ( ! authorize ) ? common.noop : function(cb) { + session.context.protocol.authorize(xtree, null, authorize, function(err) { + return cb(err); + }); + }; + do_authorize(function(err) { + if ( err ) + return cb(err); + session.context.protocol.consume( + session, session.info.lastCommands, xtree, + function(err, commands) { + if ( err ) { + return cb(err); } + if ( session.discover && session.peer.devInfo ) + return cb(null, self._session2stats(session)); + self._transmit(session, commands, function(err) { + if ( err ) + return cb(err); + if ( ! session.isServer ) + return cb(); + self._save(session.txn(), function(err) { + if ( err ) + return cb(err); + return cb(null, self._session2stats(session)); + }); + }); } - }, - "app-widget": { - nodeName: "tizen:app-widget", - required: false, - occurrence: 0, - attributes: { - id: { - attributeName: "id", - required: true, - type: "string" - }, - primary: { - attributeName: "primary", - required: true, - type: "list", - listValues: ['true', 'false'] - }, - "auto-launch": { - attributeName: "auto-launch", - required: false, - type: "list", - listValues: ['true', 'false'] - }, - "update-period": { - attributeName: "update-period", - required: false, - type: "integer" + ); + }); + }) + }, + + }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/matcher', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.matcher +// auth: griffin +// date: 2012/12/05 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + _self; + +_self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + exports._cntpref = function(source, target) { + return ( source.preferred ? 1 : 0 ) + ( target.preferred ? 1 : 0 ); + }; + + //--------------------------------------------------------------------------- + exports._pickTransmitContentType = function(source, target, prefcnt, checkVersion) { + for ( var sidx=0 ; sidx= prefcnt ) + return [sct.ctype, sct.versions[sct.versions.length - 1]]; + continue; +} +for ( var svidx=sct.versions.length ; svidx>0 ; svidx-- ) +{ + var sv = sct.versions[svidx - 1] + for ( var tvidx=tct.versions.length ; tvidx>0 ; tvidx-- ) + { + var tv = tct.versions[tvidx - 1] + if ( sv != tv ) + continue; + if ( exports._cntpref(sct, tct) >= prefcnt ) + return [sct.ctype, sv]; + } +} +} +} +return null; +}; + +//--------------------------------------------------------------------------- +exports.pickTransmitContentType = function(source, target) { + + // TODO: this is probably not the most efficient algorithm!... + // (but it works... ;-) + + // order of preference: + // - transmit => receive, BOTH preferred, VERSION match + // - transmit => receive, ONE preferred, VERSION match + // - transmit => receive, neither preferred, VERSION match + // - transmit => receive, BOTH preferred, no version match + // - transmit => receive, ONE preferred, no version match + // - transmit => receive, neither preferred, no version match + // - tx/rx => tx/rx, BOTH preferred, VERSION match + // - tx/rx => tx/rx, ONE preferred, VERSION match + // - tx/rx => tx/rx, neither preferred, VERSION match + // - tx/rx => tx/rx, BOTH preferred, no version match + // - tx/rx => tx/rx, ONE preferred, no version match + // - tx/rx => tx/rx, neither preferred, no version match + + // todo: make it explicit (or overrideable) that i am depending on the ordering + // of the versions supported to give an indicator of preference... + + var sct = source.getContentTypes(); + var tct = target.getContentTypes(); + + var fct = function(cts, transmit) { + return _.filter(cts, function(ct) { + return transmit ? ct.transmit : ct.receive; + }); + }; + + return exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 2, true) + || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 1, true) + || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 0, true) + || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 2, false) + || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 1, false) + || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 0, false) + || exports._pickTransmitContentType(sct, tct, 2, true) + || exports._pickTransmitContentType(sct, tct, 1, true) + || exports._pickTransmitContentType(sct, tct, 0, true) + || exports._pickTransmitContentType(sct, tct, 2, false) + || exports._pickTransmitContentType(sct, tct, 1, false) + || exports._pickTransmitContentType(sct, tct, 0, false) + || null; + +}; + +// TODO: OH MY GOD. +// this is insanely inefficient. +// i'm embarrassed. +// fortunately, it's hidden really low-level... +// but now you know, doh! please don't blackmail me!... ;-) + +// TODO: this currently requires that both tx and rx match in both +// directions with the same velocity... it should prioritize +// that, but then fallback to giving simplex matches priority. + +//--------------------------------------------------------------------------- +var has_ct = function(a, b, checkVersion, transmit, wildcard) { + a = _.filter(a, function(e) { return transmit ? e.transmit : e.receive }); + b = _.filter(b, function(e) { return transmit ? e.transmit : e.receive }); + for ( var aidx=0 ; aidx +// date: 2012/11/04 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var db = require('ripple/db'), + common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + devinfo = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'), + state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'), + base64 = require('ripple/platform/tizen/2.0/syncml-js-lib/base64'), + ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'), + _firstflag = false, + changednum, _counts; + +var _self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + var getError = function(xnode) { + var ret = { + message: xnode.findtext('Item/Data') + }; + try{ + var xerr = xnode.find('Error'); + }catch(e){ + var xerr = null; + } + if ( ! xerr ) +{ + try{ + var xerr = xnode.find('Item/Error'); + }catch(e){ + var xerr = null; + } +} +if ( ! xerr ) +{ + if ( ! ret.message ) + return null; + return ret; +} +ret.code = xerr.findtext('Code'); +ret.message = xerr.findtext('Message'); +ret.trace = xerr.findtext('Trace'); +return ret; +} + +//--------------------------------------------------------------------------- +var badStatus = function(xnode, kls, attrs) { + if ( ! kls ) + kls = common.ProtocolError; + var code = xnode.findtext('Data'); + var cname = xnode.findtext('Cmd'); + var msg = null; + if ( kls == common.ProtocolError ) + msg = 'unexpected status code ' + code + ' for command "' + cname + '"'; + else + msg = 'received status code ' + code + ' for command "' + cname + '"'; + var error = getError(xnode); + if ( error ) + { + if ( error.code ) + msg += ': [' + error.code + '] ' + error.message; + else + msg += ': ' + error.message; + } + return new kls(msg, undefined, attrs) +}; + +//--------------------------------------------------------------------------- +exports.getError = getError; +exports.badStatus = badStatus; + +//--------------------------------------------------------------------------- +exports.Protocol = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(options) { + }, + + //------------------------------------------------------------------------- + authorize: function(xtree, uri, authorize, cb) { + + // TODO: if this session has been authorized before, don't call authorize + // ie.: + // if ( session.info.authAccepted ) + // return cb(); + // BUT this requires the session object... oops. + + if ( ! authorize ) + authorize = function(uri, data, cb) { return cb(null, data); }; +if ( xtree.tag != 'SyncML' ) + throw new common.ProtocolError('root element was not "SyncML"'); +var xcred = xtree.find('SyncHdr/Cred'); +if ( ! xcred ) + return authorize(uri, null, cb); +var data = xcred.findtext('Data'); +var authtype = xcred.findtext('Meta/Type'); +var format = xcred.findtext('Meta/Format'); +if ( format == constant.FORMAT_B64 ) + data = base64.decode(data); +else if ( format ) + throw new common.UnknownFormatType(format); +switch ( authtype ) +{ + case constant.NAMESPACE_AUTH_BASIC: + { + data = common.splitn(data, ':', 1); + return authorize(uri, { + auth: constant.NAMESPACE_AUTH_BASIC, + username: data[0], + password: data[1] + }, cb); + } + case constant.NAMESPACE_AUTH_MD5: + { + return authorize(uri, { + auth: constant.NAMESPACE_AUTH_BASIC, + digest: data + }, cb); + } + default: + { + return cb(new common.UnknownAuthType( + 'unknown/unimplemented auth type "' + authtype + '"')); + } +} +}, + + //------------------------------------------------------------------------- + getTargetID: function(xtree) { + if ( xtree.tag != 'SyncML' ) + throw new common.ProtocolError('root element was not "SyncML"'); + // todo: do more validity checks?... + return xtree.findtext('SyncHdr/Target/LocURI'); + }, + + //------------------------------------------------------------------------- + isComplete: function(session, commands) { + return (! session.isServer + && commands.length == 3 + && commands[0].name == constant.CMD_SYNCHDR + && commands[1].name == constant.CMD_STATUS + && commands[1].statusOf == constant.CMD_SYNCHDR + && commands[1].statusCode == constant.STATUS_OK + && commands[2].name == constant.CMD_FINAL + ); + }, + + //----------------------<--------------------------------------------------- + initialize: function(session, xtree, cb) { + var cmd = state.makeCommand({ + name : constant.CMD_SYNCHDR, + cmdID : 0, + version : constant.SYNCML_VERSION_1_2, + source : session.info.effectiveID || session.adapter.devID, + sourceName : session.adapter.displayName, + respUri : session.isServer ? session.info.returnUrl : null + }); + + var checkPeer = ( ! session.isServer ) ? function(cb) { + if ( ! xtree ) + return cb(); + var xhdr = xtree.find('SyncHdr'); + // todo: check peer id... + if ( session.info.id != common.int(xhdr.findtext('SessionID')) ) + { + return cb(new common.ProtocolError('session ID mismatch "' + + xhdr.findtext('SessionID') + + '" (expected: ' + session.info.id + ')')); } - }, - children: { - "box-label": { - nodeName: "tizen:box-label", - required: true, - occurence: 1 - }, - "box-icon": { - nodeName: "tizen:box-icon", - required: true, - occurence: 1, - attributes: { - src: { - attributeName: "src", - required: true, - type: "string" - } + // todo: check message id... + cb(); + } : function(cb) { + var xhdr = xtree.find('SyncHdr'); + var peerID = xhdr.findtext('Source/LocURI'); + if ( session.info.peerID && session.info.peerID != peerID ) + { + return cb(new common.ProtocolError('unexpected peer ID "' + peerID + '"')); + } + if ( session.peer && session.peer.devID != peerID ) + { + return cb(new common.ProtocolError('unacceptable peer ID "' + peerID + '"')); + } + session.info.peerID = peerID; + // check that no session swapping occurred + if ( session.info.id != undefined + && session.info.id != common.int(xhdr.findtext('SessionID')) ) + { + return cb(new common.ProtocolError('session ID mismatch "' + + xhdr.findtext('SessionID') + + '" (expected: ' + session.info.id + ')')); } - }, - "box-content": { - nodeName: "tizen:box-content", - required: true, - occurence: 1, - attributes: { - src: { - attributeName: "src", - required: true, - type: "string" - }, - "mouse-event": { - attributeName: "mouse-event", - required: false, - type: "string" - }, - "touch-event": { - attributeName: "touch-event", - required: false, - type: "string" - } - }, - children: { - "box-size": { - nodeName: "tizen:box-size", - required: false, - occurence: 1, - attributes: { - "preview": { - attributeName: "preview", - required: false, - type: "string" - } - } - }, - pd: { - nodeName: "tizen:pd", - required: false, - occurence: 1, - attributes: { - "src": { - attributeName: "src", - required: true, - type: "string" - }, - "width": { - attributeName: "width", - required: true, - type: "integer" - }, - "height": { - attributeName: "height", - required: true, - type: "integer" - } - } - } + session.info.id = common.int(xhdr.findtext('SessionID')); + session.info.msgID = common.int(xhdr.findtext('MsgID')); + if ( session.peer && session.peer.devID == peerID ) + return cb(); + // TODO: i should delete unused peers here... ie. anything that + // hasn't been used in some configurable number of seconds, + // which should probably default to something like a month... + session.peer = _.find(session.adapter.getPeers(), function(peer) { + return ( peer.devID == peerID ); + }); + if ( session.peer ) + { + return cb(); } + var peerInfo = { + devID: peerID, + displayName: xhdr.findtext('Source/LocName'), + maxMsgSize: common.int(xhdr.findtext('Meta/MaxMsgSize')), + maxObjSize: common.int(xhdr.findtext('Meta/MaxObjSize')) + }; + session.adapter.addPeer(peerInfo, function(err, peer) { + if ( err ) + return cb(err); + session.peer = peer; + return cb(); + }); + }; + + checkPeer(function(err) { + + session.info.cmdID = 0; + session.info.pendingMsgID = ( session.isServer + ? session.info.msgID + : session.info.lastMsgID ); + cmd.sessionID = session.info.id; + cmd.msgID = session.info.msgID; + cmd.target = session.peer ? session.peer.devID || null : null; + cmd.targetName = session.peer ? session.peer.displayName || null : null; + cmd.auth = session.auth + ? session.auth.type + : session.peer + ? session.peer.auth + : null; + + if ( err ) + return cb(err, [cmd]); + + if ( cmd.msgID == 1 ) + { + // NOTE: normally, the "server" would not send this info. however, in + // the syncml-js world where it is much more peer-oriented + // instead of client/server, i send this as well... the + // idea being, if two "client" peers are communicating in + // the event of server unavailability, then they may need + // to know each-others limitations... + cmd.maxMsgSize = common.getMaxMemorySize(session.context); + cmd.maxObjSize = common.getMaxMemorySize(session.context); + ///cmd.maxMsgSize = 150000; + ///cmd.maxObjSize = 4000000; + } + cb(null, [cmd]); + }); + }, + + //------------------------------------------------------------------------- + negotiate: function(session, commands, cb) { + // // todo: determine why i decided to clone the commands... + // commands = _.clone(commands); + + if ( commands.length > 0 && _.last(commands).name == constant.CMD_FINAL ) + return cb(null, commands); + + if ( commands.length > 0 + && _.last(commands).name == constant.CMD_ALERT + && _.last(commands).data == constant.STATUS_NEXT_MESSAGE ) + // todo: should i add a "final" here?... + // commands.push(state.makeCommand({name: constant.CMD_FINAL})); + return cb(null, commands); + + var createDevInfoCommands = function(commands, cb) { + // todo: this flag is crap. instead, the local devInfo should have + // a record of which sessionID lead to the recording, and + // base it on that. maybe timestamp too... (but it must be + // in the minutes, just in case...) + session.info.gotinfo = true; + if ( ! session.discover ) + { + commands.push(state.makeCommand({ + name : constant.CMD_PUT, + cmdID : session.nextCmdID(), + type : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec, + source : './' + constant.URI_DEVINFO_1_2, + data : session.adapter.devInfo.toSyncML(constant.SYNCML_DTD_VERSION_1_2, + _.values(session.adapter._stores)) + })); + } + commands.push(state.makeCommand({ + name : constant.CMD_GET, + cmdID : session.nextCmdID(), + type : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec, + target : './' + constant.URI_DEVINFO_1_2 + })); + return cb(null, commands); + }; + + var createCommands = function(commands, cb) { + // request the remote device info if not currently available or + // in discover mode or explicitly re-exchanging it (paranoid mode) + var putget = false; + if ( !! session.discover ) + { + return createDevInfoCommands(commands, cb); + } + if ( ! session.peer.devInfo ) + { + var uaEvent = {session: session}; + return session.ua.acceptDevInfoSwap(uaEvent, function(err) { + if ( err ) + { + return cb(err); + } + return createDevInfoCommands(commands, cb); + }); + } + if ( ! session.context.config.trustDevInfo && ! session.info.gotinfo ) + { + return createDevInfoCommands(commands, cb); + } + // NOTE: in the current handling of "trustDevInfo", i am doing a + // potentially unnecessary extra request/response phase to + // confirm that the devInfo has not changed... i *could* + // issue the put/get as well as the alert, *assuming* that + // no devInfo is going to change... + return session.context.synchronizer.actions(session, commands, cb); + }; + + return createCommands(commands, function(err, commands) { + if ( err ) + return cb(err); + //Hack: Memotoo service need to send alert command at the beging + var args, tmp; + args = db.retrieveObject("syncml-alert-args"); + tmp = { + name : constant.CMD_ALERT, + cmdID : session.nextCmdID(), + data : args.data, + source : args.source, + target : args.target, + maxObjSize : "4000000" + }; + if (args.lastAnchor) { + tmp.lastAnchor = args.lastAnchor; + } + + if (args.nextAnchor) { + tmp.nextAnchor = args.nextAnchor; + } + _firstflag = db.retrieveObject("syncml-first-flag"); + if( !_firstflag) { + commands.push(state.makeCommand(tmp)); + db.saveObject("syncml-first-flag", true); + } + commands.push(state.makeCommand({name: constant.CMD_FINAL})); + cb(null, commands); + }); + }, + + //------------------------------------------------------------------------- + // NOTE: `produce` is equivalent to the `pysyncml.protocol.commands2tree`... + // Consumes state.Command commands and converts them to an ET protocol tree + produce: function(session, commands, cb) { + + if ( commands.length <= 0 ) + return cb('protocol.produce received empty commands'); + + var hdrcmd = commands[0]; + commands = _.rest(commands, 1); + + if ( hdrcmd.name != constant.CMD_SYNCHDR ) + return cb('unexpected first command "' + hdrcmd.name + '"'); + + if ( hdrcmd.version != constant.SYNCML_VERSION_1_2 ) + return cb('unsupported SyncML version "' + hdrcmd.version + '"'); + + var xsync = ET.Element(constant.NODE_SYNCML); + var xhdr = ET.SubElement(xsync, hdrcmd.name); + if ( hdrcmd.version == constant.SYNCML_VERSION_1_2 ) + { + ET.SubElement(xhdr, 'VerDTD').text = constant.SYNCML_DTD_VERSION_1_2; + ET.SubElement(xhdr, 'VerProto').text = hdrcmd.version; + } + + ET.SubElement(xhdr, 'SessionID').text = hdrcmd.sessionID; + ET.SubElement(xhdr, 'MsgID').text = hdrcmd.msgID; + var xsrc = ET.SubElement(xhdr, 'Source'); + ET.SubElement(xsrc, 'LocURI').text = hdrcmd.source; + if ( hdrcmd.sourceName ) + ET.SubElement(xsrc, 'LocName').text = hdrcmd.sourceName; + var xtgt = ET.SubElement(xhdr, 'Target'); + ET.SubElement(xtgt, 'LocURI').text = hdrcmd.target; + if ( hdrcmd.targetName ) + ET.SubElement(xtgt, 'LocName').text = hdrcmd.targetName; + if ( hdrcmd.respUri ) + ET.SubElement(xhdr, 'RespURI').text = hdrcmd.respUri; + + if ( hdrcmd.auth && ! session.info.authAccepted ) + { + // TODO: implement other auth schemes... + if ( hdrcmd.auth != constant.NAMESPACE_AUTH_BASIC ) + return cb('auth method "' + hdrcmd.auth + '" not implemented'); + + if ( hdrcmd.auth == constant.NAMESPACE_AUTH_BASIC ) + { + var xcred = ET.SubElement(xhdr, 'Cred'); + var xmeta = ET.SubElement(xcred, 'Meta'); + ET.SubElement(xmeta, 'Format', {'xmlns': constant.NAMESPACE_METINF}).text = 'b64'; + ET.SubElement(xmeta, 'Type', {'xmlns': constant.NAMESPACE_METINF}).text = hdrcmd.auth; + ET.SubElement(xcred, 'Data').text = base64.encode( + ( session.auth ? session.auth.username : session.peer.username ) + + ':' + ( session.auth ? session.auth.password : session.peer.password ) ); + } + + } + if ( hdrcmd.maxMsgSize || hdrcmd.maxObjSize ) + { + var xmeta = ET.SubElement(xhdr, 'Meta'); + if ( hdrcmd.maxMsgSize ) + ET.SubElement(xmeta, 'MaxMsgSize', + {'xmlns': constant.NAMESPACE_METINF}).text = hdrcmd.maxMsgSize; + if ( hdrcmd.maxObjSize ) + ET.SubElement(xmeta, 'MaxObjSize', + {'xmlns': constant.NAMESPACE_METINF}).text = hdrcmd.maxObjSize; + } + + var xbody = ET.SubElement(xsync, constant.NODE_SYNCBODY); + + for ( var idx=0 ; idx 0 ) ? cmds[0] : null; + var makeErrorCommands = function(err, cb) { + + if ( err.exception ) + + if ( ! session.isServer ) + return cb(err); + + var errcmd = state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : '1', + msgRef : session.info.pendingMsgID, + cmdRef : 0, + sourceRef : xsync.getchildren()[0].findtext('Source/LocURI'), + targetRef : xsync.getchildren()[0].findtext('Target/LocURI'), + statusOf : constant.CMD_SYNCHDR, + statusCode : constant.STATUS_COMMAND_FAILED, + errorMsg : 'an error occurred during processing' + }); + + // TODO: make this configurable as to whether or not any error + // is sent back to the peer as a SyncML "standardized" error + // status... + + // TODO: make sure this is doing what is expected/intended... + if ( err.code || err.name ) + errcmd.errorCode = 'syncml-js.' + ( err.code || err.name ); + errcmd.errorMsg = err.message || common.j(err) || '' + err; + + return cb(null, [hdrcmd, errcmd, + state.makeCommand({name: constant.CMD_FINAL})]); + }; + + if ( err ) + return makeErrorCommands(err, cb); + + try { + self._consume(session, lastcmds, xsync, cmds, function(err, commands) { + if ( err ) + return makeErrorCommands(err, cb); + return cb(null, commands); + }); + } catch ( exc ) { + return makeErrorCommands(exc, cb); + } + + }); + }, + + //------------------------------------------------------------------------- + _consume: function(session, lastcmds, xsync, commands, cb) { + + var self = this; + var hdrcmd = commands[0]; + var statusCode = constant.STATUS_OK; + + // analyze the SyncHdr + var children = xsync.getchildren()[0].getchildren(); + for ( var idx=0 ; idx= blen ) + return cb(new common.ProtocolError( + 'unexpected status node "s' + session.info.id + '.m' + child.findtext('MsgRef') + + '.c' + child.findtext('CmdRef') + ' cmd=' + cname + '"')); + + // TODO: check for unknown elements (and complain?)... + + var code = common.int(child.findtext('Data')); + + if ( code == constant.STATUS_MISSING_CREDENTIALS ) + { + var authtype = child.findtext('Chal/Meta/Type'); + var attrs = {auth: {type: authtype}}; + return cb(badStatus(child, common.CredentialsRequired, attrs)); + } + + if ( code == constant.STATUS_INVALID_CREDENTIALS ) + { + // TODO: get the auth type... from where??... + var authtype = child.findtext('Chal/Meta/Type'); + var attrs = {auth: {type: authtype}}; + return cb(badStatus(child, common.InvalidCredentials, attrs)); + } + + var targetRef = child.findtext('TargetRef'); + if ( targetRef ) + { + // note: doing a normUri on chkcmd.target because it could be "./devinf12"... + if ( session.peer.normUri(targetRef) != session.peer.normUri(chkcmd.target) ) + return cb(new common.ProtocolError('unexpected target-ref "' + + targetRef + '" != "' + chkcmd.target + + '" for command "' + cname + '"')); + } + + var sourceRef = child.findtext('SourceRef'); + if ( sourceRef ) + { + // note: doing a normUri on chkcmd.source because it could be "./devinf12"... + if ( cname == constant.CMD_SYNCHDR ) + { + // this is a little odd, but syncevolution strips the sessionid path + // parameter off for some reason, so compensating here... + if ( _.indexOf([session.adapter.normUri(chkcmd.source), + session.info.effectiveID, + session.info.returnUrl], + session.adapter.normUri(sourceRef)) < 0 + && session.adapter.normUri(chkcmd.source).indexOf(session.adapter.normUri(sourceRef)) != 0 ) + return cb(new common.ProtocolError('unexpected source-ref "' + + sourceRef + '" != "' + chkcmd.source + + '" for command "' + cname + '"')); + } + else + { + if ( session.adapter.normUri(sourceRef) != session.adapter.normUri(chkcmd.source) ) + return cb(new common.ProtocolError('unexpected source-ref "' + + sourceRef + '" != "' + chkcmd.source + + '" for command "' + cname + '"')); + } + } + + // todo: any other common elements?... + + switch ( cname ) + { + + case constant.CMD_SYNCHDR: + { + if ( code != constant.STATUS_OK && code != constant.STATUS_AUTHENTICATION_ACCEPTED ) + return cb(badStatus(child)); + if ( code == constant.STATUS_AUTHENTICATION_ACCEPTED ) + { + // TODO: there is currently nothing that can "reset" the + // authAccepted flag... there should be a trap such + // that if an auth fails, then authAccepted gets set + // to false. + session.info.authAccepted = true; } + return cb(); } - }, - account: { - nodeName: "tizen:account", - required: false, - occurrence: 0, - attributes: { - "multiple-account-support": { - attributeName: "multiple-account-support", - required: true, - type: "list", - listValues: ['true', 'false'] + + case constant.CMD_ALERT: + { + if ( code == constant.STATUS_OK ) + // TODO: do something with the Item/Data/Anchor/Next?... + return cb(); + if ( code == constant.STATUS_REFRESH_REQUIRED && ! session.isServer ) + { + // TODO: support the ability for the UA to control which kind of + // refresh to do (slow-sync, client-refresh, server-refresh) + return cb(); } - }, - children: { - icon: { - nodeName: "tizen:icon", - required: false, - occurence: 1, - attributes: { - section: { - attributeName: "section", - required: true, - type: "string" + return cb(badStatus(child)); + } + + case constant.CMD_GET: + { + if ( code != constant.STATUS_OK ) + return cb(badStatus(child)); + return cb(); + } + + case constant.CMD_PUT: + { + if ( code != constant.STATUS_OK ) + return cb(badStatus(child)); + return cb(); + } + + case constant.CMD_RESULTS: + { + if ( code != constant.STATUS_OK ) + return cb(badStatus(child)); + return cb(); + } + + case constant.CMD_SYNC: + { + // todo: should this be moved into the synchronizer as a "settle" event?... + var ds = session.info.dsstates[session.adapter.normUri(chkcmd.source)] + if ( code != constant.STATUS_OK ) + { + // check for server-side errors... + if ( code >= 500 && code < 600 && child.findtext('Item/Data') ) + { + ds.action = 'error'; + ds.error = getError(child); + ds.stats.peerErr += 1; + return cb(); } + return cb(badStatus(child)); } - }, - "display-name": { - nodeName: "tizen:display-name", - required: false, - occurence: 1, - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "string" - } + if ( ds.action == 'send' ) + { + if ( session.isServer ) + { + ds.action = 'save'; + return cb(); } - }, - capability: { - nodeName: "capability", - required: false, - occurence: 1 + ds.action = common.oneWayOut(session, ds.mode) ? 'done' : 'recv'; + return cb(); } + return cb(new common.ProtocolError('unexpected sync state for action=' + ds.action)); } - }, - feature: { - nodeName: "tizen:privilege", - required: false, - occurrence: 0, - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - name: { - attributeName: "name", - required: true, - type: "list", - listValues: ["http://www.w3.org/TR/geolocation-API/", - "http://www.w3.org/TR/battery-status/", - "http://www.w3.org/TR/vibration/", - "http://www.w3.org/TR/touch-events/", - "http://tizen.org/privilege/tizen", - "http://tizen.org/privilege/application.launch", - "http://tizen.org/privilege/appmanager.kill", "http://tizen.org/privilege/appmanager.certificate", - "http://tizen.org/privilege/time", - "http://tizen.org/privilege/alarm", - "http://tizen.org/privilege/bookmark.read", "http://tizen.org/privilege/bookmark.write", - "http://tizen.org/privilege/contact.read", "http://tizen.org/privilege/contact.write", - "http://tizen.org/privilege/filesystem.write", "http://tizen.org/privilege/filesystem.read", - "http://tizen.org/privilege/calendar.read", "http://tizen.org/privilege/calendar.write", - "http://tizen.org/privilege/callhistory.read", "http://tizen.org/privilege/callhistory.write", - "http://tizen.org/privilege/messaging.send", - "http://tizen.org/privilege/messaging.read", "http://tizen.org/privilege/messaging.write", - "http://tizen.org/privilege/bluetoothmanager", "http://tizen.org/privilege/bluetooth.admin", - "http://tizen.org/privilege/bluetooth.gap", "http://tizen.org/privilege/bluetooth.spp", - "http://tizen.org/privilege/nfc.common", "http://tizen.org/privilege/nfc.admin", - "http://tizen.org/privilege/nfc.tag", "http://tizen.org/privilege/nfc.p2p", - "http://tizen.org/privilege/content.read", "http://tizen.org/privilege/content.write", - "http://tizen.org/privilege/system", "http://tizen.org/privilege/systemmanager", - "http://tizen.org/privilege/setting", - "http://tizen.org/privilege/packagemanager.install", "http://tizen.org/privilege/package.info", - "http://tizen.org/privilege/power", "http://tizen.org/privilege/download", - "http://tizen.org/privilege/notification", - "http://tizen.org/privilege/networkbearerselection", - "http://tizen.org/privilege/push"] - }, - required: { - attributeName: "required", - type: "boolean", - required: false + + case constant.CMD_ADD: + case constant.CMD_REPLACE: + case constant.CMD_DELETE: + { + var scmd = state.makeCommand({ + name : cname, + msgID : hdrcmd.msgID, + cmdID : child.findtext('CmdID'), + sourceRef : sourceRef, + targetRef : targetRef, + data : code + }); + + session.context.synchronizer.settle( + session, scmd, chkcmd, child, + function(err, cmds) { + if ( err ) + return cb(err); + _.each(cmds, function(cmd) { commands.push(cmd); }); + return cb(); + }); + return; + } + + case constant.CMD_MAP: + { + if ( session.isServer ) + return cb(new common.ProtocolError( + 'unexpected server-side status for command "' + cname + '"')); + if ( code != constant.STATUS_OK ) + return cb(badStatus(child)); + return cb(); + } + + default: + { + return cb(new common.ProtocolError('unexpected status for command "' + cname + '"')); + } + + } + + }, cb); + + }; + + // second, check all the non-'Status' commands + + var consumeCommands = function(cb) { + + var gotFinal = false; + + common.cascade(children, function(child, cb) { + + + if ( child.tag == constant.CMD_STATUS ) + return cb(); + + if ( child.tag == constant.CMD_FINAL ) + { + gotFinal = true; + return cb(); + } + + + // todo: restrict this to the following commands?... + // CMD_ALERT, CMD_GET, CMD_PUT, + // CMD_SYNC, CMD_RESULTS, CMD_MAP + + var func = self['_consume_node_' + child.tag.toLowerCase()]; + + if ( ! func ) + return cb(new common.ProtocolError('unexpected command node "' + child.tag + '"')); + + try{ + + func.call(self, session, lastcmds, xsync, child, function(err, cmds) { + if ( err ) + return cb(err); + _.each(cmds, function(cmd) { commands.push(cmd); }); + return cb(); + }); + + }catch(e){ + // log.error('failed invoking protocol sub-consumption of "%s": %s', child.tag, e); + // log.error(' ' + stacktrace({e: e}).join('\n ')); + return cb(new common.InternalError( + 'failed invoking protocol sub-consumption of "' + child.tag + '": ' + e, e)); + } + + }, function(err) { + + if ( err ) + return cb(err); + + if ( ! gotFinal ) + { + commands.push(state.makeCommand({ + name : constant.CMD_ALERT, + cmdID : session.nextCmdID(), + data : constant.STATUS_NEXT_MESSAGE, + source : session.adapter.devID, + target : session.peer.devID, + })); + } + + return cb(); + + }); + + }; + + // do it! + + consumeStatus(function(err) { + + if ( err ) + return cb(err); + + // TODO: is this right?... or should i be getting pissed off and + // raising hell that all my commands were not addressed?... + + _.each(chkcmds, function(chkcmd) { + commands.push(chkcmd); + }); + + return consumeCommands(function(err) { + if ( err ) + return cb(err); + return cb(null, commands); + }); + + }); + + }, + + //------------------------------------------------------------------------- + _consume_node_get: function(session, lastcmds, xsync, xnode, cb) { + var cttype = xnode.findtext('Meta/Type'); + var target = xnode.findtext('Item/Target/LocURI'); + if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0 + && session.adapter.normUri(target) == constant.URI_DEVINFO_1_2 ) + return this._consume_node_get_devinf12(session, lastcmds, xsync, xnode, cb); + // todo: make error status node... + cb(new common.ProtocolError( + 'unexpected "' + constant.CMD_GET + '" command for local "' + target + '"')); + }, + + //------------------------------------------------------------------------- + _consume_node_get_devinf12: function(session, lastcmds, xsync, xnode, cb) { + var ret = []; + ret.push(state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : session.info.pendingMsgID, + cmdRef : xnode.findtext('CmdID'), + statusOf : xnode.tag, + statusCode : constant.STATUS_OK, + targetRef : xnode.findtext('Item/Target/LocURI') + })); + ret.push(state.makeCommand({ + name : constant.CMD_RESULTS, + cmdID : session.nextCmdID(), + msgRef : session.info.pendingMsgID, + cmdRef : xnode.findtext('CmdID'), + type : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec, + source : './' + constant.URI_DEVINFO_1_2, + data : session.adapter.devInfo.toSyncML(constant.SYNCML_DTD_VERSION_1_2, + _.values(session.adapter._stores)) + + })); + cb(null, ret); + }, + + //------------------------------------------------------------------------- + _consume_node_put: function(session, lastcmds, xsync, xnode, cb) { + var cttype = xnode.findtext('Meta/Type'); + var source = xnode.findtext('Item/Source/LocURI'); + if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0 + && session.peer.normUri(source) == constant.URI_DEVINFO_1_2 ) + return this._consume_node_put_devinf12(session, lastcmds, xsync, xnode, cb); + // todo: make error status node... + cb(new common.ProtocolError( + 'unexpected "' + constant.CMD_PUT + '" command for remote "' + source + '"')); + }, + + //------------------------------------------------------------------------- + _consume_node_put_devinf12: function(session, lastcmds, xsync, xnode, cb) { + var xdev = xnode.find('Item/Data/DevInf'); + var res = devinfo.DevInfo.fromSyncML(xdev); + session.peer._setRemoteInfo(res[0], res[1], function(err) { + if ( err ) + return cb(err); + + var okcmd = state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : xsync.findtext('SyncHdr/MsgID'), + cmdRef : xnode.findtext('CmdID'), + sourceRef : xnode.findtext('Item/Source/LocURI'), + statusOf : xnode.tag, + statusCode : constant.STATUS_OK + }); + + if ( session.isServer ) + return cb(null, [okcmd]); + + // TODO: this should only cause a `recalculate` if any + // meta-information actually changed... + + session.context.router.recalculate(session.adapter, session.peer, function(err) { + if ( err ) + return cb(err); + session.context.synchronizer.initStoreSync(session, function(err) { + if ( err ) + return cb(err); + + // TODO: the call to _setRemoteInfo makes the peer + // "dirty" without saving changes to the model... + // make sure the `save` executed in Adapter.sync() + // or Adapter.handleRequest() appropriately causes + // objects to save themselves to the model... + + // session.adapter._save(session.txn(), function(err) { + // if ( err ) + // return cb(err); + + return cb(null, [okcmd]); + + // }); + + }); + }); + }); + }, + + //------------------------------------------------------------------------- + _consume_node_results: function(session, lastcmds, xsync, xnode, cb) { + var cttype = xnode.findtext('Meta/Type'); + var source = xnode.findtext('Item/Source/LocURI'); + if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0 + && session.peer.normUri(source) == constant.URI_DEVINFO_1_2 ) + return this._consume_node_put_devinf12(session, lastcmds, xsync, xnode, cb); + // todo: make error status node... + return cb(new common.ProtocolError('unexpected "' + constant.CMD_RESULTS + + '" command for remote "' + source + '"')) + }, + + //------------------------------------------------------------------------- + _consume_node_alert: function(session, lastcmds, xsync, xnode, cb) { + var code = common.int(xnode.findtext('Data')); + var statusCode = constant.STATUS_OK + switch ( code ) + { + case constant.ALERT_TWO_WAY: + case constant.ALERT_SLOW_SYNC: + case constant.ALERT_ONE_WAY_FROM_CLIENT: + case constant.ALERT_REFRESH_FROM_CLIENT: + case constant.ALERT_ONE_WAY_FROM_SERVER: + case constant.ALERT_REFRESH_FROM_SERVER: + // todo: these should only be received out-of-band: right?... + // case constant.ALERT_TWO_WAY_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: + { + break; + } + default: + { + if ( session.isServer && code == constant.STATUS_RESUME ) + { + code = constant.ALERT_SLOW_SYNC; } - }, - children: { - param: { - nodeName: "param", - required: false, - occurrence: 0, - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - name: { - attributeName: "name", - required: true, - type: "string", - }, - value: { - attributeName: "value", - required: true, - type: "string", - } - } + else + { + return cb(new common.FeatureNotSupported( + 'unimplemented sync mode ' + + code + ' ("' + common.mode2string(code) + '")')); } } - }, - preference: { - nodeName: "preference", - required: false, - occurrence: 0, - attributes: { - "xml:lang": { - attributeName: "xml:lang", - required: false, - type: "iso-language", - }, - dir: { - attributeName: "dir", - required: false, - type: "list", - listValues: ["ltr", "rtl", "lro", "rlo"] - }, - name: { - attributeName: "name", - required: true, - type: "string" + } + + if ( session.isServer ) + { + // TODO: if this is the server, we need to validate that the requested + // sync mode is actually feasible... i.e. check: + // - do the anchors match? + // - have we bound the datastores together? + // - is there a pending sync? + } + + var uri = session.adapter.normUri(xnode.findtext('Item/Target/LocURI')); + var ruri = session.peer.normUri(xnode.findtext('Item/Source/LocURI')); + + // TODO: this should really be done by the synchronizer... as it can + // then also do a lot of checks - potentially responding with + // an error... + + var getDS = function(cb) { + if ( session.isServer ) + { + var ds = session.info.dsstates[uri]; + if ( ds ) + { + ds.action = 'alert'; + return cb(null, ds); + } + + var peerStore = session.peer.getStore(ruri); + if ( ! peerStore ) + return cb(new common.ProtocolError( + 'request to synchronize unknown remote client URI "' + ruri + + '" (to local server URI "' + uri + '")')); + + // todo: if already correctly bound, then we don't need to re-bind + // if ( peerStore._getBinding() ) + // { + // log.critical('(currently bound)'); + // } + // else + // log.critical('(currently unbound)'); + + session.peer.setRoute(uri, ruri, true, function(err) { + if ( err ) + return cb(err); + var peerStore = session.peer.getStore(ruri); + var ds = state.makeStoreSyncState({ + uri : uri, + peerUri : ruri, + lastAnchor : peerStore._getBinding().localAnchor, + mode : null, + action : 'alert' + }); + session.info.dsstates[uri] = ds; + return cb(null, ds); + }); + return; + } + else + { + var ds = session.info.dsstates[uri]; + if ( ! ds ) + return cb(new common.ProtocolError('request for unreflected local datastore "' + + uri + '"')); + ds.action = 'send'; + if ( code == ds.mode ) + return cb(null, ds); + + var uaEvent = { + session : session, + uri : uri, + peerUri : ruri, + modeReq : ds.mode, + modeRes : code + }; + session.ua.acceptSyncModeSwitch(uaEvent, function(err) { + if ( err ) + { + return cb(err); + } + if ( session.context.listener ) + session.context.listener(uaEvent); + return cb(null, ds); + }); + } + }; + + + getDS(function(err, ds) { + + if ( err ) + return cb(err); + + ds.mode = code; + ds.peerLastAnchor = xnode.findtext('Item/Meta/Anchor/Last', null); + ds.peerNextAnchor = xnode.findtext('Item/Meta/Anchor/Next', null); + + if ( ds.peerLastAnchor != session.peer.getStore(ruri)._getBinding().remoteAnchor ) + { + ds.peerLastAnchor = null; + switch ( ds.mode ) + { + case constant.ALERT_SLOW_SYNC: + case constant.ALERT_REFRESH_FROM_CLIENT: + case constant.ALERT_REFRESH_FROM_SERVER: + { + break; + } + default: + { + if ( session.isServer ) + { + ds.mode = constant.ALERT_SLOW_SYNC; + statusCode = constant.STATUS_REFRESH_REQUIRED; + } + else + { + // todo: should i assume that the server knows something + // that i don't and just go along with it?... + return cb(new common.ProtocolError( + 'server-side requested inappropriate ' + common.mode2string(ds.mode) + + ' sync mode on unbound datastore "' + uri + '"')); + } + } + } + } + + return cb(null, [state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : xsync.findtext('SyncHdr/MsgID'), + cmdRef : xnode.findtext('CmdID'), + targetRef : xnode.findtext('Item/Target/LocURI'), + sourceRef : xnode.findtext('Item/Source/LocURI'), + statusOf : xnode.tag, + statusCode : statusCode, + // todo: syncevolution does not echo the remote last anchor... why not? + lastAnchor : ds.peerLastAnchor, + nextAnchor : ds.peerNextAnchor + })]); + + }); + + }, + + //------------------------------------------------------------------------- + _consume_node_sync: function(session, lastcmds, xsync, xnode, cb) { + var self = this; + var uri = xnode.findtext('Target/LocURI'); + var store = session.adapter.getStore(session.adapter.normUri(uri)); + var ds = session.info.dsstates[session.adapter.normUri(uri)]; + var commands = [state.makeCommand({ + name : constant.CMD_SYNC, + msgID : xsync.findtext('SyncHdr/MsgID'), + cmdID : xnode.findtext('CmdID'), + source : xnode.findtext('Source/LocURI'), + target : uri, + data : [], + })]; + var noc = common.int(xnode.findtext('NumberOfChanges')); + if (noc !== undefined) { + changednum = noc; + _counts = 0; + } + common.cascade(xnode.getchildren(), function(child, cb) { + switch ( child.tag ) + { + case 'CmdID': + case 'Target': + case 'Source': + case 'NumberOfChanges': + { + return cb(); + } + case constant.CMD_ADD: + case constant.CMD_REPLACE: + case constant.CMD_DELETE: + { + var func = self['_consume_sync_' + child.tag.toLowerCase()]; + func.call(self, session, lastcmds, store, xsync, child, function(err, cmds) { + if ( err ) + return cb(err); + _.each(cmds, function(cmd) { commands[0].data.push(cmd); }); + return cb(); + }); + return; + } + default: + { + return cb(new common.ProtocolError('unexpected sync command "' + child.tag + '"')); + } + } + }, function(err) { + if ( err ) + return cb(err); + // confirm that i received the right number of changes... + /* + if ( noc != undefined && noc != commands[0].data.length ) + return cb(new common.ProtocolError('number-of-changes mismatch (received ' + + commands[0].data.length + ', expected ' + + noc + ')')); + */ + _counts = _counts + commands[0].data.length; + if ( ds.action != 'error' ) + { + if ( ! session.isServer ) + { + if ( ds.action != 'recv' ) + return cb(new common.ProtocolError('unexpected sync state for URI "' + + uri + '": action=' + ds.action)); + if (changednum != undefined && changednum <= _counts) { + ds.action = 'done'; + changednum = undefined; + _counts = 0; + } + } + else + { + if ( ds.action != 'alert' ) + return cb(new common.ProtocolError( + 'unexpected sync state for URI "' + uri + '": action=' + ds.action)); + ds.action = common.oneWayIn(session, ds.mode) ? 'save' : 'send'; + } + } + return session.context.synchronizer.reactions(session, commands, cb); + }); + }, + + //------------------------------------------------------------------------- + _consume_xnode2item: function(session, lastcmds, store, xsync, xnode, cb) { + var ctype = xnode.findtext('Meta/Type'); + // todo: can the version be specified in the Meta tag?... maybe create an + // extension to SyncML to communicate this?... + var ctver = null; + var format = xnode.findtext('Meta/Format'); + var xitem = xnode.findall('Item/Data'); + if ( xitem.length > 1 ) + return cb(new common.ProtocolError( + '"' + xnode.tag + '" command with non-singular item data nodes')); + if ( xitem.length < 1 ) + return cb(new common.ProtocolError( + '"' + xnode.tag + '" command with missing data node')); + var xitem = xitem[0]; + // todo: confirm that getchildren only returns element nodes... + if ( xitem.getchildren().length == 1 ) + data = xitem.getchildren()[0]; + else + { + data = xitem.text; + if ( format == constant.FORMAT_B64 ) + data = base64.decode(data); + } + return store.agent.loadsItem(data, ctype, ctver, cb); + }, + + //------------------------------------------------------------------------- + _consume_sync_add: function(session, lastcmds, store, xsync, xnode, cb) { + this._consume_xnode2item(session, lastcmds, store, xsync, xnode, function(err, item) { + if ( err ) + return cb(err); + return cb(null, [state.makeCommand({ + name : constant.CMD_ADD, + msgID : xsync.findtext('SyncHdr/MsgID'), + cmdID : xnode.findtext('CmdID'), + source : xnode.findtext('Item/Source/LocURI'), + sourceParent : xnode.findtext('Item/SourceParent/LocURI'), + targetParent : xnode.findtext('Item/TargetParent/LocURI'), + data : item + })]); + }); + }, + + //------------------------------------------------------------------------- + _consume_sync_replace: function(session, lastcmds, store, xsync, xnode, cb) { + this._consume_xnode2item(session, lastcmds, store, xsync, xnode, function(err, item) { + if ( err ) + return cb(err); + return cb(null, [state.makeCommand({ + name : constant.CMD_REPLACE, + msgID : xsync.findtext('SyncHdr/MsgID'), + cmdID : xnode.findtext('CmdID'), + source : xnode.findtext('Item/Source/LocURI'), + sourceParent : xnode.findtext('Item/SourceParent/LocURI'), + target : xnode.findtext('Item/Target/LocURI'), + targetParent : xnode.findtext('Item/TargetParent/LocURI'), + data : item + })]); + }); + }, + + //------------------------------------------------------------------------- + _consume_sync_delete: function(session, lastcmds, store, xsync, xnode, cb) { + return cb(null, [state.makeCommand({ + name : constant.CMD_DELETE, + msgID : xsync.findtext('SyncHdr/MsgID'), + cmdID : xnode.findtext('CmdID'), + source : xnode.findtext('Item/Source/LocURI'), + sourceParent : xnode.findtext('Item/SourceParent/LocURI'), + target : xnode.findtext('Item/Target/LocURI'), + targetParent : xnode.findtext('Item/TargetParent/LocURI') + })]); + }, + + // #---------------------------------------------------------------------------- + // def makeStatus(self, session, xsync, xnode, status=constant.STATUS_OK, **kw): + // return state.Command( + // name = constant.CMD_STATUS, + // cmdID = session.nextCmdID(), + // msgRef = xsync.findtext('SyncHdr/MsgID'), + // cmdRef = xnode.findtext('CmdID'), + // statusOf = xnode.tag, + // statusCode = status, + // **kw + // ) + + //------------------------------------------------------------------------- + _consume_node_map: function(session, lastcmds, xsync, xnode, cb) { + if ( ! session.isServer ) + return cb(new common.ProtocolError( + 'unexpected "Map" command received by client-side SyncML peer')); + // TODO: convert the sender-side to support command.items like + // this as well... + var cmd = state.makeCommand({ + name : constant.CMD_MAP, + msgID : xsync.findtext('SyncHdr/MsgID'), + cmdID : xnode.findtext('CmdID'), + source : xnode.findtext('Source/LocURI'), + target : xnode.findtext('Target/LocURI'), + items : [] + }); + _.each(xnode.findall('MapItem'), function(xnode) { + // todo: support hierarchical sync... + cmd.items.push({ + source : xnode.findtext('Source/LocURI'), + // sourceParent : xnode.findtext('SourceParent/LocURI'), + target : xnode.findtext('Target/LocURI'), + // targetParent : xnode.findtext('TargetParent/LocURI') + }); + }); + return session.context.synchronizer.reactions(session, [cmd], cb); + } + + +}); + +return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.remoteadapter +// auth: griffin +// date: 2012/11/04 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + devinfomod = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'), + adapter = require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'), + storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'), + _self; + +_self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + exports.RemoteAdapter = adapter.Adapter.extend({ + + //------------------------------------------------------------------------- + constructor: function(adapter, options) { + + //: [read-only] the URL of the remote syncml peer, acting as a server, + //: to connect to. + this.url = options.url || null; + + //: [read-only] specifies whether this Adapter represents a local + //: or remote peer. + this.isLocal = false; + + //: [read-only] the DevID of the remote syncml peer (which usually + //: defaults to the URL). + this.devID = options.devID || options.url || null; + + //: [read-only] the authentication method to use to identify the local + //: peer to the remote peer. + ///TODO: this.auth = options.auth || null; + this.auth = 'syncml:auth-basic'; + + //: [read-only] the human-friendly display name of the remote peer. + this.displayName = options.displayName || null; + + //: [read-only] the username to use during credential-based authentication. + this.username = options.username || null; + + //: [read-only] the password to use during credential-based authentication. + this.password = options.password || null; + + //: [read-only] the peer-wide default value of the maximum + //: message size. + this.maxMsgSize = options.maxMsgSize || null; + + //: [read-only] the peer-wide default value of the maximum + //: object size. + this.maxObjSize = options.maxObjSize || null; + + //: [read-only] the DevInfo object for this remote peer. + this.devInfo = null; + + this.lastSessionID = options.lastSessionID || null; + + // --- private attributes + this.id = options.id || common.makeID(); + this._a = adapter; + this._c = adapter._c; + this._stores = {}; + this._proxy = null; + + // TODO: filter these options for db-valid only properties... + this._options = options; + }, + + //------------------------------------------------------------------------- + _load: function(cb) { + + var self = this; + var model = this._getModel(); + + // todo: should this be loading these?... + // self.displayName = model.displayName; + // self.devID = model.devID; + + var loadDevInfo = function(cb) { + var di = new devinfomod.DevInfo(self, model.devInfo); + di._load(function(err) { + if ( err ) + return cb(err); + self.devInfo = di; + cb(); + }); + }; + + var loadStores = function(cb) { + common.cascade(model.stores, function(e, cb) { + var store = new storemod.Store(self, e); + store._load(function(err) { + if ( err ) + return cb(err); + self._stores[store.uri] = store; + return cb(); + }); + }, cb); + }; + + loadDevInfo(function(err) { + if ( err ) + return cb(err); + loadStores(cb); + }); + }, + + //------------------------------------------------------------------------- + _updateModel: function(cb) { + var self = this; + if ( ! this._a._model || ! this._a._model.peers ) + return cb(new common.InternalError('peer created on un-initialized adapter')); + var model = self._getModel(); + // todo: should this be in this._getModel()?... + if ( ! model ) + { + model = { + id: self.id, + devInfo: null, + stores: [], + routes: [] + }; + self._a._model.peers.push(model); + } + + model.isLocal = 0; + model.url = self.url; + model.devID = self.devID; + model.displayName = self.displayName; + model.auth = self.auth; + model.username = self.username; + model.password = self.password; + model.lastSessionID = self.lastSessionID + model.maxMsgSize = self.maxMsgSize; + model.maxObjSize = self.maxObjSize; + + common.cascade([ + + // update the devInfo model + function(cb) { + if ( ! self.devInfo ) + return cb(); + return self.devInfo._updateModel(cb); }, - value: { - type: "string", - required: false, - attributeName: "value" + + // update the stores model + function(cb) { + // TODO: this should really be the responsibility of the Store class... + // NOTE: since bindings are not stored in Store, they need to be saved + // and re-applied. + // TODO: or, perhaps better, i should purge all unwanted stores + // instead of doing this brute-force method... + var bindings = _.object(_.map(model.stores, function(store) { + return [store.uri, store.binding]; + })); + model.stores = []; + common.cascade(_.values(self._stores), function(store, cb) { + store._updateModel(cb); + }, function(err) { + if ( err ) + return cb(err); + _.each(bindings, function(binding, uri) { + var store = _.find(model.stores, function(s) { return s.uri == uri; }); + if ( ! store ) + return; + store.binding = binding; + }); + return cb(); + }); }, - readonly: { - attributeName: "readonly", - type: "boolean", - required: false + + ], cb); + + }, + + //------------------------------------------------------------------------- + _getModel: function() { + return _.find(this._a._model.peers, + function(e) { return e.id == this.id; }, this); + }, + + //------------------------------------------------------------------------- + _setRemoteInfo: function(devInfo, stores, cb) { + var self = this; + self._model = self._getModel(); + devInfo._a = self; + self.devInfo = devInfo; + self.devInfo._updateModel(function(err) { + if ( err ) + return cb(err); + // merge the new datastore info with any pre-existing store bindings + // step 1: prepare the new stores (clean up the URIs) + var lut = _.object(_.map(stores, function(store) { + store.uri = self.normUri(store.uri); + return [store.uri, store]; + })); + // step 2: remove all stores that are no longer mentioned + self._stores = _.object( + _.map( + _.filter(_.keys(self._stores), function(oldUri) { + return _.indexOf(_.keys(lut), oldUri) >= 0; + }), function(uri) { + return [uri, self._stores[uri]]; + } + ) + ); + // step 3: merge the datastore info for existing stores + var merge_stores = function(cb) { + common.cascade(_.values(self._stores), function(store, cb) { + store.merge(lut[store.uri], function(err) { + if ( err ) + return cb(err); + delete lut[store.uri]; + return cb(); + }); + }, cb); + }; + // step 4: add new datastores + var add_stores = function(cb) { + common.cascade(_.values(lut), function(store, cb) { + self.addStore(store, cb); + }, cb); + }; + merge_stores(function(err) { + if ( err ) + return cb(err); + add_stores(cb); + }); + }); + }, + + //------------------------------------------------------------------------- + setRoute: function(localUri, remoteUri, autoMapped, cb) { + if ( _.isFunction(autoMapped) ) + // defaulting 'autoMapped' to false + return this.setRoute(localUri, remoteUri, false, autoMapped); + var pmodel = this._getModel(); + if ( ! pmodel ) + return cb(new common.InternalError('could not locate this peer in local adapter')); + pmodel.routes = _.filter(pmodel.routes, function(r) { + return r.localUri != localUri && r.remoteUri != remoteUri; + }); + pmodel.routes.push({localUri : localUri, + remoteUri : remoteUri, + autoMapped : autoMapped + }); + // now search through previous bindings, breaking incorrect ones... + // NOTE: this requires that a router.recalculate() is called at + // some point later since other valid bindings may now be + // possible... + _.each(pmodel.stores, function(store) { + if ( store.uri != remoteUri + && ( ! store.binding || store.binding.uri != localUri ) ) + { + return; + } + if ( ! store.binding ) + { + store.binding = { + uri : localUri, + autoMapped : autoMapped, + localAnchor : null, + remoteAnchor : null + }; + return; + } + if ( store.uri == remoteUri && store.binding.uri == localUri ) + { + store.binding.autoMapped = store.binding.autoMapped && autoMapped; + return; + } + store.binding = null; + return; + }); + // TODO: this additional route may impact "smart routing" - recalculate?... + // TODO: saving adapter from peer --- SHOULD IT BE DOING THIS?... + // TODO: get transaction from a session!... + this._a._save(this._c._txn(), cb); + }, + + //------------------------------------------------------------------------- + sendRequest: function(session, contentType, data, cb) { + var xmlhttp; + + // TODO: shouldn't proxies just overwrite .sendRequest() ?... + if ( this._proxy ) + return this._proxy.sendRequest(session, contentType, data, cb); + + var req = { + url : session.info.respUri || this.url, + method : 'POST', + headers : {'Content-Type': contentType}, + body : data + }; + + xmlhttp = new XMLHttpRequest(); + xmlhttp.open(req.method, req.url, false); + + xmlhttp.setRequestHeader("Content-Type", contentType); + xmlhttp.send(req.body); + + var response = { + headers: { + "Content-Type": xmlhttp.getResponseHeader("content-type") + }, + body: xmlhttp.responseXML + }; + return cb(null, response); + } + + }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/router', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.router +// auth: griffin +// date: 2012/11/04 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'), + matcher = require('ripple/platform/tizen/2.0/syncml-js-lib/matcher'), + stablematch = require('ripple/platform/tizen/2.0/syncml-js-lib/stablematch'), + _self; + +_self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + exports.Router = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(options) { + }, + + //------------------------------------------------------------------------- + getTargetUri: function(adapter, peer, sourceUri) { + var pmodel = peer._getModel(); + for ( var idx=0 ; idx +// date: 2012/12/29 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var _self = (function () { + + var exports = {}; + + // TODO: figure out how to pull this dynamically from package.json... + exports.version = '0.0.4'; + + //--------------------------------------------------------------------------- + exports.match = function(A, B, rankA, rankB) { + if ( ! A || ! B || ! A.length || ! B.length ) { + return []; + } + if ( A.length == B.length ) { + return exports._match(A, B, rankA, rankB); + } + + // TODO: this is a brute-force implementation of getting both + // lists to be of symmetric length... make this "better". + // for example, build this directly into _match() or use + // deterministic exclusion of the longer data set. + + var sA = _.rest(A, 0); + var sB = _.rest(B, 0); + var mlen = Math.max(sA, sB); + while ( sA.length < mlen ) + sA.push(null); + while ( sB.length < mlen ) + sB.push(null); + var sRA = function(a) { + var ret = rankA(a); + while ( ret.length < mlen ) + ret.push(null); + return ret; + }; + var sRB = function(b) { + var ret = rankB(b); + while ( ret.length < mlen ) + ret.push(null); + return ret; + }; + var ret = exports._match(sA, sB, sRA, sRB); + return _.filter(ret, function(pair) { + return pair[0] != null && pair[1] != null; + }); + }; + + //--------------------------------------------------------------------------- + exports._match = function(A, B, rankA, rankB) { + // this translates sets A and B to indeces, since _imatch can only work + // with sets of elements that can be used as the key in a hash (in this + // implementation). + var iA = _.range(A.length); + var iB = _.range(B.length); + var iRA = function(ia) { + var ret = rankA(A[ia]); + return _.map(ret, function(item) { + return _.indexOf(B, item); + }); + }; + var iRB = function(ib) { + var ret = rankB(B[ib]); + return _.map(ret, function(item) { + return _.indexOf(A, item); + }); + }; + var ret = exports._imatch(iA, iB, iRA, iRB); + return _.map(ret, function(item) { + return [A[item[0]], B[item[1]]]; + }); + }; + + //--------------------------------------------------------------------------- + exports._imatch = function(A, B, rankA, rankB) { + // TODO: improve this... it was a brute-force porting of + // https://github.com/paulgb/Python-Gale-Shapley + // without any eye on optimal outcome or performance... + //: `partners` is a paring hash of { a => [b, rank] } + var partners = {}; + _.each(A, function(a) { + partners[a] = [rankA(a)[0], 0]; + }); + //: `stable` indicates stability of the current pairing in `partners` + var stable = false; + while ( ! stable ) + { + stable = true; + _.each(B, function(b) { + var paired = false; + for ( var n=0 ; n +// date: 2012/10/27 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- -function deviceStatusEventTrigger(setting) { - event.trigger("DeviceStatusChanged", [setting]); -} +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + _self; -module.exports = { - "Config": { - "vibratingMode": { - "name": "Vibrator", - "control": { - "type": "checkbox", - "value": true - }, - "callback": function (setting) { - event.trigger("VibratingModeChanged", [setting]); +_self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + exports.makeCommand = function(options) { + return _.defaults({}, options, { + // ? + }); + }; + + //--------------------------------------------------------------------------- + exports.makeStats = function(options) { + return _.defaults({}, options, { + mode : null, + hereAdd : 0, + hereMod : 0, + hereDel : 0, + hereErr : 0, + peerAdd : 0, + peerMod : 0, + peerDel : 0, + peerErr : 0, + conflicts : 0, + merged : 0, + }); + }; + + //--------------------------------------------------------------------------- + exports.makeSessionInfo = function(options) { + return _.defaults({}, options, { + id : null, + msgID : null, + cmdID : 0, + dsstates : {}, + lastCommands : [], + stats : exports.makeStats() + }); + }; + + //--------------------------------------------------------------------------- + exports.makeStoreSyncState = function(options) { + return _.defaults({}, options, { + uri : null, + peerUri : null, + lastAnchor : null, + nextAnchor : '' + common.ts(), + mode : constant.ALERT_TWO_WAY, + action : null, + stats : exports.makeStats() + }); + }; + + //--------------------------------------------------------------------------- + exports.makeSession = function(options) { + return new (function() { + this.context = options.context || null; + this.ua = options.ua || null; + this.txn = options.txn || options.context.txn; + this.adapter = options.adapter || null; + this.peer = options.peer || null; + this.info = options.info || null; + this.discover = options.discover ? true : false; + this.isServer = options.isServer ? true : false; + this.nextCmdID = function() { + this.info.cmdID += 1; + return this.info.cmdID; + }; + })(); + + // return _.defaults({}, options, { + // context : null, + // adapter : null, + // peer : null, + // info : null + // }); + }; + + var smult = function(s, count) { + var ret = ''; + for ( var idx=0 ; idx0 ; idx-=3 ) + { + if ( ret.length > 0 ) + ret = ',' + ret; + ret = num.charAt(idx - 1) + ret; + if ( idx - 1 > 0 ) + ret = num.charAt(idx - 2) + ret; + if ( idx - 2 > 0 ) + ret = num.charAt(idx - 3) + ret; + } + return ret; + }; + + var center = function(s, wid, pad) { + // todo: is there no way to get sprintf to do this for me???... + pad = pad || ' '; + if ( wid <= s.length ) + return s; + var diff = wid - s.length; + return smult(pad, Math.floor(diff / 2)) + s + smult(pad, Math.ceil(diff / 2)); + }; + + var right = function(s, wid, pad) { + // todo: is there no way to get sprintf to do this for me???... + pad = pad || ' '; + if ( wid <= s.length ) + return s; + return smult(pad, wid - s.length) + s; + }; + + //--------------------------------------------------------------------------- + // TODO: this should probably be put into another package... + exports.describeStats = function(stats, stream, options) { + + // ASCII OBJECTIVE: + // +----------------------------------------------------------------------------------+ + // | TITLE | + // +----------+------+-------------------------+--------------------------+-----------+ + // | | | Local | Remote | Conflicts | + // | Source | Mode | Add | Mod | Del | Err | Add | Mod | Del | Err | Col | Mrg | + // +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+ + // | contacts | <= | - | - | - | - | 10,387 | - | - | - | - | - | + // | note | SS | 1,308 | - | 2 | - | - | - | - | - | - | - | + // +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+ + // | 1,310 local changes and 10,387 remote changes. | + // +----------------------------------------------------------------------------------+ + + // UNICODE OBJECTIVE: + // ┌──────────────────────────────────────────────────────────────────────────────────┐ + // │ TITLE │ + // ├──────────┬──────┬─────────────────────────┬──────────────────────────┬───────────┤ + // │ │ │ Local │ Remote │ Conflicts │ + // │ Source │ Mode │ Add Mod Del Err │ Add Mod Del Err │ Col Mrg │ + // ├──────────┼──────┼───────┼─────┼─────┼─────┼────────┼─────┼─────┼─────┼─────┼─────┤ + // │ contacts │ <= │ │ │ │ │ 10,387 │ │ │ │ │ │ + // │ note │ SS │ 1,308 │ │ 2 │ │ │ │ │ │ │ │ + // ├──────────┴──────┴───────┴─────┴─────┴─────┴────────┴─────┴─────┴─────┴─────┴─────┤ + // │ 1,310 local changes and 10,387 remote changes. │ + // └──────────────────────────────────────────────────────────────────────────────────┘ + + // todo: perhaps the fancy version should have color-coding as well?... + + options = _.defaults({}, options, { + title : null, + details : true, + totals : true, + ascii : false, + gettext : function(text) { return text; } + }); + + var modeStringLut = _.object([ + [constant.SYNCTYPE_TWO_WAY , '<>'], + [constant.SYNCTYPE_SLOW_SYNC , 'SS'], + [constant.SYNCTYPE_ONE_WAY_FROM_CLIENT , '->'], + [constant.SYNCTYPE_REFRESH_FROM_CLIENT , '=>'], + [constant.SYNCTYPE_ONE_WAY_FROM_SERVER , '<-'], + [constant.SYNCTYPE_REFRESH_FROM_SERVER , '<='] + ]); + + if ( options.ascii ) + { + + // unicode graphing characters: ('\xe2\x94\x80' - '\xe2\x94\xc0') + // mapping table unicode ==> ascii + + glyphs = { + '─': '-', + '━': '-', + '│': '|', + '┃': '|', + '┄': '-', + '┅': '-', + '┆': '|', + '┇': '|', + '┈': '-', + '┉': '-', + '┊': '|', + '┋': '|', + '┌': '+', + '┍': '+', + '┎': '+', + '┏': '+', + '┐': '+', + '┑': '+', + '┒': '+', + '┓': '+', + '└': '+', + '┕': '+', + '┖': '+', + '┗': '+', + '┘': '+', + '┙': '+', + '┚': '+', + '┛': '+', + '├': '+', + '┝': '+', + '┞': '+', + '┟': '+', + '┠': '+', + '┡': '+', + '┢': '+', + '┣': '+', + '┤': '+', + '┥': '+', + '┦': '+', + '┧': '+', + '┨': '+', + '┩': '+', + '┪': '+', + '┫': '+', + '┬': '+', + '┭': '+', + '┮': '+', + '┯': '+', + '┰': '+', + '┱': '+', + '┲': '+', + '┳': '+', + '┴': '+', + '┵': '+', + '┶': '+', + '┷': '+', + '┸': '+', + '┹': '+', + '┺': '+', + '┻': '+', + '┼': '+', + '┽': '+', + '┾': '+', + '┿': '+', + }; + + var UnicodeToAsciiStream = common.Stream.extend({ + constructor: function(stream) { + this.stream = stream; + }, + write: function(data) { + if ( data == undefined ) + return; + var ascii = ''; + for ( var idx=0 ; idx wCol + 3 + wMrg ) + { + diff = wCon - ( wCol + 3 + wMrg ); + wCol += diff / 2; + wMrg = wCon - 3 - wCol; + } + else + wCon = wCol + 3 + wMrg; + + if ( options.details ) + tWid = ( wSrc + 3 + wMode + 3 + + wHereAdd + wHereMod + wHereDel + wHereErr + 9 + 3 + + wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 + 3 + + wCon ); + else + tWid = options.title ? options.title.length : 0; + + if ( options.totals ) + { + // TODO: oh dear. from an i18n POV, this is *horrible*!... + sumlist = []; + // for val, singular, plural in [ + _.each([ + [totLoc, options.gettext('local change'), options.gettext('local changes')], + [totRem, options.gettext('remote change'), options.gettext('remote changes')], + [totErr, options.gettext('error'), options.gettext('errors')] + ], function(set) { + if ( set[0] <= 0 ) + return; + sumlist.push(num2str(set[0]) + ' ' + ( set[0] == 1 ? set[1] : set[2] )); + }); + if ( sumlist.length <= 0 ) + sumlist = options.gettext('No changes'); + else if ( sumlist.length == 1 ) + sumlist = sumlist[0]; + else + sumlist = ( sumlist.slice(0, -1).join(', ') + ' ' + + options.gettext('and') + ' ' + sumlist[sumlist.length - 1] ); + if ( totMrg > 0 || totCol > 0 ) + { + sumlist += ': '; + if ( totMrg == 1 ) + sumlist += num2str(totMrg) + ' ' + options.gettext('merge'); + else if ( totMrg > 1 ) + sumlist += num2str(totMrg) + ' ' + options.gettext('merges'); + if ( totMrg > 0 && totCol > 0 ) + sumlist += ' ' + options.gettext('and') + ' '; + if ( totCol == 1 ) + sumlist += num2str(totCol) + ' ' + options.gettext('conflict'); + else if ( totCol > 1 ) + sumlist += num2str(totCol) + ' ' + options.gettext('conflicts'); + } + sumlist += '.'; + if ( sumlist.length > tWid ) + { + wSrc += sumlist.length - tWid; + tWid = sumlist.length; } } - }, - "DEVICE_ORIENTATION": { - "status": { - "name": "Status", - "control": { - "type": "label", - "innertext": "PORTRAIT_PRIMARY", - "value": "PORTRAIT_PRIMARY" - }, - "event": "LayoutChanged" + + if ( options.title ) + { + stream.write('┏━' + smult('━', tWid) + '━┓\n'); + stream.write('┃ ' + center(options.title, tWid) + ' ┃\n'); } - }, - "CPU": { - "load": { - "name": "Load", - "control": { - "type": "number", - "value": 0.1 - }, - "event": "CpuLoadChanged", - "callback": function (setting) { - if (setting > 1) setting = 1; - if (setting < 0) setting = 0; - event.trigger("CpuLoadChanged", [setting]); - } + + if ( options.details ) + { + if ( options.title ) + stream.write('┡━' + + smult('━', wSrc) + + '━┯━' + + smult('━', wMode) + + '━┯━' + + smult('━', ( wHereAdd + wHereMod + wHereDel + wHereErr + 9 )) + + '━┯━' + + smult('━', ( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 )) + + '━┯━' + + smult('━', wCon) + + '━┩\n' + ); + else + stream.write('┌─' + + smult('─', wSrc) + + '─┬─' + + smult('─', wMode) + + '─┬─' + + smult('─', ( wHereAdd + wHereMod + wHereDel + wHereErr + 9 )) + + '─┬─' + + smult('─', ( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 )) + + '─┬─' + + smult('─', wCon) + + '─┐\n' + ); + + stream.write('│ ' + smult(' ', wSrc)); + stream.write(' │ ' + smult(' ', wMode)); + stream.write(' │ ' + center(options.gettext('Local'), wHereAdd + wHereMod + wHereDel + wHereErr + 9 )); + stream.write(' │ ' + center(options.gettext('Remote'), wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 )); + stream.write(' │ ' + center(options.gettext('Conflicts'), wCon)); + stream.write(' │\n'); + + stream.write('│ ' + right(options.gettext('Source'), wSrc)); + stream.write(' │ ' + center(options.gettext('Mode'), wMode)); + stream.write(' │ ' + center(options.gettext('Add'), wHereAdd)); + stream.write(( options.ascii ? ' │ ' : ' ' ) + center(options.gettext('Mod'), wHereMod)); + stream.write(( options.ascii ? ' │ ' : ' ' ) + center(options.gettext('Del'), wHereDel)); + stream.write(( options.ascii ? ' │ ' : ' ' ) + center(options.gettext('Err'), wHereErr)); + stream.write(' │ ' + center(options.gettext('Add'), wPeerAdd)); + stream.write(( options.ascii ? ' │ ' : ' ' ) + center(options.gettext('Mod'), wPeerMod)); + stream.write(( options.ascii ? ' │ ' : ' ' ) + center(options.gettext('Del'), wPeerDel)); + stream.write(( options.ascii ? ' │ ' : ' ' ) + center(options.gettext('Err'), wPeerErr)); + stream.write(' │ ' + center(options.gettext('Col'), wCol)); + stream.write(( options.ascii ? ' │ ' : ' ' ) + center(options.gettext('Mrg'), wMrg)); + stream.write(' │\n'); + + stream.write('├─' + smult('─', wSrc) + + '─┼─' + smult('─', wMode) + + '─┼─' + smult('─', wHereAdd) + + '─┼─' + smult('─', wHereMod) + + '─┼─' + smult('─', wHereDel) + + '─┼─' + smult('─', wHereErr) + + '─┼─' + smult('─', wPeerAdd) + + '─┼─' + smult('─', wPeerMod) + + '─┼─' + smult('─', wPeerDel) + + '─┼─' + smult('─', wPeerErr) + + '─┼─' + smult('─', wCol) + + '─┼─' + smult('─', wMrg) + + '─┤\n' + ); + + var numcol = function(val, wid) { + if ( val == 0 ) + return ' │ ' + center(options.ascii ? '-' : ' ', wid); + return ' │ ' + right(num2str(val), wid); + }; + + var keys = _.keys(stats); + // todo: sort case insensitively... + keys.sort(); + _.each(keys, function(key) { + var stat = stats[key]; + stream.write('│ ' + right(key, wSrc)); + stream.write(' │ ' + center(modeStringLut[stat.mode], wMode)); + stream.write(numcol(stat.hereAdd, wHereAdd)); + stream.write(numcol(stat.hereMod, wHereMod)); + stream.write(numcol(stat.hereDel, wHereDel)); + stream.write(numcol(stat.hereErr, wHereErr)); + stream.write(numcol(stat.peerAdd, wPeerAdd)); + stream.write(numcol(stat.peerMod, wPeerMod)); + stream.write(numcol(stat.peerDel, wPeerDel)); + stream.write(numcol(stat.peerErr, wPeerErr)); + stream.write(numcol(stat.conflicts, wCol)); + stream.write(numcol(stat.merged, wMrg)); + stream.write(' │\n'); + }); + + if ( options.totals ) + stream.write('├─'); + else + stream.write('└─'); + + stream.write(smult('─', wSrc) + + '─┴─' + smult('─', wMode) + + '─┴─' + smult('─', wHereAdd) + + '─┴─' + smult('─', wHereMod) + + '─┴─' + smult('─', wHereDel) + + '─┴─' + smult('─', wHereErr) + + '─┴─' + smult('─', wPeerAdd) + + '─┴─' + smult('─', wPeerMod) + + '─┴─' + smult('─', wPeerDel) + + '─┴─' + smult('─', wPeerErr) + + '─┴─' + smult('─', wCol) + + '─┴─' + smult('─', wMrg) + ); + + if ( options.totals ) + stream.write('─┤\n'); + else + stream.write('─┘\n'); } - }, - "STORAGE": { - "type": { - "name": "Type", - "control": { - "type": "select", - "value": StorageTypeTable["INTERNAL"] + + // ─━│┃┄┅┆┇┈┉┊┋┼┽┾┿ + // ┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛ + // ├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫ + // ┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻ + + if ( options.totals ) + { + if ( !! options.title && ! options.details ) + stream.write('┌─' + smult('─', tWid) + '─┐\n'); + stream.write('│ ' + center(sumlist, tWid)); + stream.write(' │\n'); + stream.write('└─' + smult('─', tWid) + '─┘\n'); + } + + return; + + }; + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/storage', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.storage +// auth: griffin +// date: 2012/10/31 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'); + +var _self = (function () { + + var exports = {}; + + //--------------------------------------------------------------------------- + _.extend(exports, { + + //------------------------------------------------------------------------- + errstr: function(target) { + if ( target.error && typeof(target.error.toString) == 'function' ) + return target.error.toString(); + var ret = ''; + var count = 0; + for ( var key in target.error ) + count += 1; + if ( count == 1 && target.error.name ) + ret = '' + target.error.name; + else + { + ret = '{'; + for ( var key in target.error ) + { + ret += key + ': ' + target.error[key]; + count -= 1; + if ( count > 0 ) + ret += ', '; + } + } + if ( target.errorCode ) + { + if ( ret.length <= 0 || ret == '{}' ) + ret = '' + target.errorCode; + else + ret = '[' + target.errorCode + '] ' + ret; + } + if ( ret.length <= 0 || ret == '{}' ) + // last ditch effort... + ret = common.prettyJson(target); + return ret; + }, + + //------------------------------------------------------------------------- + openDatabase: function(context, cb) { + var dbreq = context.storage.indexedDB.open(context.dbname, 1); + dbreq.onblocked = function(event) { + cb({code: 'syncml-js.storage.OD.10', + message: 'database blocked by other process/tab/window'}); + }; + dbreq.onerror = function(event) { + var errmsg = exports.errstr(event.target); + cb({code: 'syncml-js.storage.OD.20', + message: 'failed to open syncml-js database: ' + errmsg}); + }; + dbreq.onupgradeneeded = function(event) { + + + var db = event.target.result; + + var adapterTable = db.createObjectStore('adapter', {keyPath: 'id'}); + adapterTable.createIndex('isLocal', 'isLocal', {unique: false}); + adapterTable.createIndex('devID', 'devID', {unique: true}); + + var mappingTable = db.createObjectStore( + 'mapping', + {keyPath: ['store_id', 'guid']}); + mappingTable.createIndex('store_id', 'store_id', {unique: false}); + // mappingTable.createIndex('guid', 'guid', {unique: false}); + // mappingTable.createIndex('luid', 'luid', {unique: false}); + + var changeTable = db.createObjectStore( + 'change', + {keyPath: ['store_id', 'item_id']}); + changeTable.createIndex('store_id', 'store_id', {unique: false}); + // changeTable.createIndex('item_id', 'item_id', {unique: false}); + + }; + dbreq.onsuccess = function(event) { + cb(null, event.target.result); + }; }, - "options": (function () { - var optionList = {}; - utils.forEach(StorageTypeTable, function (key, value) { - optionList[key] = StorageTypeTable[value]; + + //------------------------------------------------------------------------- + getTransaction: function(db, tables, mode) { + // NOTE: the spec says passing in null should be valid... but + // mozilla's indexedDB seems to barf with: + // [Exception... "The operation failed because the + // requested database object could not be found. For + // example, an object store did not exist but was + // being opened." code: "8" nsresult: "0x80660003 + // (NotFoundError)" + if ( ! tables ) + tables = ['adapter','mapping','change']; + if ( ! mode ) + mode = 'readwrite'; + return db.transaction(tables, mode); + }, + + //------------------------------------------------------------------------- + dumpDatabase: function(context, cb) { + + var ret = {}; + var txn = context._txn(); + + var steps = [ + function(cb) { + exports.getAll(context, txn.objectStore('adapter'), {}, function(err, adapters) { + ret.adapter = adapters; + return cb(err); + }); + }, + function(cb) { + exports.getAll(context, txn.objectStore('mapping'), {}, function(err, mappings) { + ret.mapping = mappings; + return cb(err); + }); + }, + function(cb) { + exports.getAll(context, txn.objectStore('change'), {}, function(err, changes) { + ret.change = changes; + return cb(err); + }); + } + ]; + + common.cascade(steps, function(step, cb) { + return step(cb); + }, function(err) { + return cb(err, ret); }); + }, - return optionList; - }()) - }, - "capacity": { - "name": "Capacity", - "control": { - "type": "label", - "value": 16000000000 + //------------------------------------------------------------------------- + clearDatabase: function(context, cb) { + var dbreq = context.storage.indexedDB.open(context.dbname, 1); + dbreq.onblocked = function(event) { + cb({code: 'syncml-js.storage.CD.10', + message: 'database blocked by other process/tab/window'}); + }; + dbreq.onerror = function(event) { + var errmsg = exports.errstr(event.target); + cb({code: 'syncml-js.storage.CD.20', + message: 'failed to open syncml-js database: ' + errmsg}); + }; + dbreq.onsuccess = function(event) { + var db = event.target.result; + db.onerror = dbreq.onerror; + async.map(['adapter', 'mapping', 'change'], function(name, cb) { + cb(); + }, function(err) { + if ( err ) + return cb(err); + db.close(); + }); + }; }, - }, - "availableCapacity": { - "name": "AvailableCapacity", - "control": { - "type": "number", - "value": 12000000000 + + //------------------------------------------------------------------------- + getAll: function(context, source, options, cb) { + // supported options: + // - range + // - only + options = options || {}; + var range = options.range; + if ( ! range && options.only ) + range = context.storage.IDBKeyRange.only(options.only); + var req = source.openCursor(range); + var ret = []; + req.onsuccess = function(event) { + var cursor = event.target.result; + if ( cursor ) + { + ret.push(cursor.value); + // ret.push({key: cursor.key, value: cursor.value}); + return cursor.continue(); + } + cb(null, ret); + }; + req.onerror = function(event) { + cb(exports.errstr(event.target)); + }; }, - "callback": function (setting) { - event.trigger("AvailCapacityChanged", [setting]); - } - }, - "isRemovable": { - "name": "IsRemovable", - "control": { - "type": "checkbox", - "value": true - } - } - }, - "BUILD": { - "model": { - "name": "Model", - "control": { - "type": "label", - "innertext": "tizen-2.1 build", - "value": "tizen-2.1 build" - } - }, - "manufacturer": { - "name": "Manufacturer", - "control": { - "type": "label", - "innertext": "Tizen", - "value": "Tizen" - } - } - }, - "LOCALE": { - "language": { - "name": "Language", - "control": { - "type": "select", - "value": LocaleTable["eng_USA"] + + //------------------------------------------------------------------------- + put: function(store, object, cb) { + var req = store.put(object); + req.onsuccess = function(event) { cb(); }; + req.onerror = function(event) { + cb(exports.errstr(event.target)); + }; }, - "options": (function () { - var optionList = {}; - utils.forEach(LocaleTable, function (key, value) { - optionList[key] = LocaleTable[value]; - }); - return optionList; - }()) - }, - "country": { - "name": "Country", - "control": { - "type": "select", - "value": LocaleTable["eng_USA"] + //------------------------------------------------------------------------- + delete: function(store, objectID, cb) { + var req = store.delete(objectID); + req.onsuccess = function(event) { cb(); }; + req.onerror = function(event) { + cb(exports.errstr(event.target)); + }; }, - "options": (function () { - var optionList = {}; - utils.forEach(LocaleTable, function (key, value) { - optionList[key] = LocaleTable[value]; - }); - return optionList; - }()) - } - }, - "DISPLAY": { - "resolutionWidth": { - "name": "Resolution Width", - "control": { - "type": "label", - "value": 0 - } - }, - "resolutionHeight": { - "name": "Resolution Height", - "control": { - "type": "label", - "value": 0 - } - }, - "dotsPerInchWidth": { - "name": "DPI-X", - "control": { - "type": "label", - "value": 0 - } - }, - "dotsPerInchHeight": { - "name": "DPI-Y", - "control": { - "type": "label", - "value": 0 + //------------------------------------------------------------------------- + deleteAll: function(source, matches, cb) { + var req = source.openCursor(); + req.onsuccess = function(event) { + var cursor = event.target.result; + if ( cursor ) + { + for (key in matches) + if ( matches[key] != cursor.value[key] ) + return cursor.continue(); + exports.delete(source, cursor.key, function(err) { + if ( err ) + return cb(err); + return cursor.continue(); + }); + return; + } + cb(null); + }; + req.onerror = function(event) { + cb(exports.errstr(event.target)); + }; + }, + + //------------------------------------------------------------------------- + iterateCursor: function(openCursor, iterator, cb) { + openCursor.onsuccess = function(event) { + var cursor = event.target.result; + if ( ! cursor ) + return cb(); + iterator(cursor.value.value, cursor.value.id, function(err) { + if ( err ) + return cb(err); + return cursor.continue(); + }); + }; + openCursor.onerror = function(event) { + cb(exports.errstr(event.target)); + }; } + + }); + + return exports; + +})(); + +module.exports = _self; + +}); +define('ripple/platform/tizen/2.0/syncml-js-lib/store', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.store +// auth: griffin +// date: 2012/11/04 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'), + storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'), + ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'); + + +var _self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + exports.Store = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(adapter, options) { + + // todo: some of these attributes should be modifiable... + + //: for local stores, specifies the agent that will implement + //: the actual item operations -- it must implement the + //: syncml-js.Agent API. + this.agent = options.agent || null; + + //: [read-only] specifies the SyncML URI that this store is bound to. + this.uri = ( adapter ? adapter.normUri(options.uri) : options.uri ) || null; + + //: [read-only] specifies the human-readable name for this store. + //: if undefined, defaults to URI. + this.displayName = options.displayName || this.uri || null; + + //: [read-only] specifies the maximum GUID size for items in this store. + //: if undefined, defaults to adapter setting. + this.maxGuidSize = options.maxGuidSize || null; + + //: [read-only] specifies the maximum object size for items in this store. + //: if undefined, defaults to adapter setting. + this.maxObjSize = options.maxObjSize || null; + + //: [read-only] specifies conflict resolution policy for this store. + //: if undefined, defaults to adapter setting. + this.conflictPolicy = options.conflictPolicy || null; + + //: [read-only] specifies which syncTypes this store supports. + //: (defaults to all.) + this.syncTypes = options.syncTypes; + if ( this.syncTypes == undefined || this.syncTypes.length <= 0 ) + { + this.syncTypes = [ + constant.SYNCTYPE_TWO_WAY, + constant.SYNCTYPE_SLOW_SYNC, + constant.SYNCTYPE_ONE_WAY_FROM_CLIENT, + constant.SYNCTYPE_REFRESH_FROM_CLIENT, + constant.SYNCTYPE_ONE_WAY_FROM_SERVER, + constant.SYNCTYPE_REFRESH_FROM_SERVER, + constant.SYNCTYPE_SERVER_ALERTED + ]; + } + + ctypes = options.contentTypes; + if ( ! ctypes && options.agent ) + ctypes = options.agent.getContentTypes(); + + this.contentTypes = _.map(ctypes, function(e) { + if ( e instanceof ctype.ContentTypeInfo ) { + return e; + } + return ctype.ContentTypeInfo.fromStruct(e); + }); + + // --- private attributes + this.id = options.id || common.makeID(); + this._a = adapter; }, - "physicalWidth": { - "name": "Physical Width", - "control": { - "type": "label", - "value": 0 - } + + //------------------------------------------------------------------------- + _load: function(cb) { + cb(); }, - "physicalHeight": { - "name": "Physical Height", - "control": { - "type": "label", - "value": 0 - } + + //------------------------------------------------------------------------- + _getModel: function() { + var self = this; + var uri = self._a.normUri(self.uri); + return _.find(this._a._getModel().stores, + function(s) { return self._a.normUri(s.uri) == uri; }); }, - "brightness": { - "name": "Brightness", - "control": { - "type": "number", - "value": 1 - }, - "event": "DisplayBrightnessChanged", - "callback": function (setting) { - if (setting > 1) setting = 1; - if (setting < 0) setting = 0; - event.trigger("DisplayBrightnessChanged", [setting]); - } - } - }, - "NETWORK": { - "networkType": { - "name": "Network Type", - "control" : { - "type": "select", - "value": NetworkTypeTable["NONE"] - }, - "options": (function () { - var optionList = {}; - utils.forEach(NetworkTypeTable, function (key, value) { - optionList[key] = NetworkTypeTable[value]; - }); - return optionList; - }()) - } - }, - "WIFI_NETWORK": { - "status": { - "name": "Status", - "control": { - "type": "checkbox", - "value": false - }, - "event": "WiFiNetworkStatusChanged", - "callback": function (setting) { - event.trigger("WiFiNetworkStatusChanged", [setting]); - } + //------------------------------------------------------------------------- + _updateModel: function(cb) { + if ( ! this._a._model || ! this._a._model.stores ) + return cb('store created on un-initialized adapter'); + // TODO: this squashes any data that may already be there, such + // as *BINDING* info!... + this._a._model.stores = _.filter(this._a._model.stores, function(e) { + return e.uri != this.uri; + }, this); + this._a._model.stores.push({ + id : this.id, + uri : this.uri, + displayName : this.displayName, + syncTypes : this.syncTypes, + maxGuidSize : this.maxGuidSize, + maxObjSize : this.maxObjSize, + conflictPolicy : this.conflictPolicy, + contentTypes : _.map(this.contentTypes, function(e) { return e.toStruct(); }) + }); + cb(); }, - "ssid": { - "name": "SSID", - "control": { - "type": "text", - "value": "Tizen WiFi" - } + + //------------------------------------------------------------------------- + _getBinding: function() { + return this._getModel().binding; }, - "ipAddress": { - "name": "IP Address", - "control": { - "type": "text", - "value": "192.168.0.1" + + //------------------------------------------------------------------------- + _setBinding: function(binding) { + this._getModel().binding = binding; + }, + + //------------------------------------------------------------------------- + getContentTypes: function() { + if ( this.agent != undefined ) { + return this.agent.getContentTypes(); } + return this.contentTypes; }, - "ipv6Address": { - "name": "IPv6 Address", - "control": { - "type": "text", - "value": "2001:db8:85a3:0:0:0:70:7334" + + //------------------------------------------------------------------------- + getPeerStore: function(peer) { + var peerUri = null; + if ( this._a.isLocal ) { + peerUri = this._a._c.router.getTargetUri(this._a, peer, this.uri); + } + else { + var binding = this.getBinding(); + peerUri = binding ? binding.uri : null; + } + if ( ! peerUri ) { + return null; } + return peer.getStore(peerUri); }, - "signalStrength": { - "name": "Signal Strength", - "control": { - "type": "select", - "value": 0 - }, - "options": (function () { - var i, - optionList = {}; - for (i = 0; i <= 10; i++) { - optionList[i] = i; - } + //------------------------------------------------------------------------- + merge: function(store, cb) { + if ( this.uri != store.uri ) + return cb(new common.InternalError( + 'unexpected merging of stores with different URIs ("' + this.uri + + '" != "' + store.uri + '")')); + if ( ! _.isEqual(this.contentTypes, store.contentTypes) ) + { + // todo: this is a bit drastic... perhaps have an operational setting + // which controls how paranoid to be?... + this._setBinding(null); + } + this.displayName = store.displayName; + this.contentTypes = _.rest(store.contentTypes, 0); + this.syncTypes = _.rest(store.syncTypes, 0); + this.maxGuidSize = store.maxGuidSize; + this.maxObjSize = store.maxObjSize; + this.agent = store.agent; + this.conflictPolicy = store.conflictPolicy; + return cb(); + }, - return optionList; - }()) - } - }, - "CELLULAR_NETWORK": { - "status": { - "name": "Status", - "control": { - "type": "checkbox", - "value": true - }, - "event": "CellularNetworkStatusChanged", - "callback": function (setting) { - event.trigger("CellularNetworkStatusChanged", [setting]); - } + //------------------------------------------------------------------------- + _clearAllMappings: function(cb) { + if ( this._a.isLocal ) + return cb(new common.InternalError( + 'unexpected mapping request for local store')); + var mapping = this._a._c._txn().objectStore('mapping'); + storage.deleteAll(mapping, {store_id: this.id}, cb); }, - "apn": { - "name": "APN", - "control": { - "type": "text", - "value": "Tizen" - } + + //------------------------------------------------------------------------- + _setMapping: function(guid, luid, cb) { + var self = this; + if ( this._a.isLocal ) + return cb(new common.InternalError( + 'unexpected mapping request for local store')); + // delete all previous mappings for this guid/store (there should + // be at most one)... but paranoia rules. + var mapping = this._a._c._txn().objectStore('mapping'); + storage.deleteAll(mapping, {store_id: this.id, guid: guid}, function(err) { + if ( err ) { + return cb(err); + } + storage.put(mapping, {store_id: self.id, guid: guid, luid: luid}, function(err) { + if ( err ) { + return cb(err); + } + cb(); + }); + }); }, - "ipAddress": { - "name": "IP Address", - "control": { - "type": "text", - "value": "10.0.2.16" - } + + //------------------------------------------------------------------------- + _getMapping: function(guid, cb) { + if ( this._a.isLocal ) + return cb(new common.InternalError( + 'unexpected mapping request for local store')); + // todo: there must be a way to use IndexedDB since i have everything + // needed to generate the keyPath!... eg: + // objectStore.get({store_id:X,guid:Y})?... + var mapdb = this._a._c._txn().objectStore('mapping').index('store_id'); + storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) { + if ( err ) { + return cb(err); + } + var item = _.find(list, function(item) { + return item.guid == guid; + }); + return cb(null, item ? item.luid : null); + }); }, - "ipv6Address": { - "name": "IPv6 Address", - "control": { - "type": "text", - "value": "2001:db8:85a3:0:0:0:70:7334" - } + + //------------------------------------------------------------------------- + _getMappings: function(cb) { + if ( this._a.isLocal ) + return cb(new common.InternalError( + 'unexpected mapping request for local store')); + var mapdb = this._a._c._txn().objectStore('mapping').index('store_id'); + storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) { + if ( err ) + return cb(err); + return cb(null, _.map(list, function(item) { + return [item.guid, item.luid]; + })); + }); }, - "mcc": { - "name": "MCC", - "control": { - "type": "number", - "value": 460 - } + + //------------------------------------------------------------------------- + _getReverseMapping: function(luid, cb) { + if ( this._a.isLocal ) + return cb(new common.InternalError( + 'unexpected mapping request for local store')); + // todo: there must be a way to use IndexedDB since i have everything + // needed to generate the keyPath!... eg: + // objectStore.get({store_id:X,guid:Y})?... + var mapdb = this._a._c._txn().objectStore('mapping').index('store_id'); + storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) { + if ( err ) + return cb(err); + var item = _.find(list, function(item) { + return item.luid == luid; + }); + return cb(null, item ? item.guid : null); + }); }, - "mnc": { - "name": "MNC", - "control": { - "type": "number", - "value": 0 + + //------------------------------------------------------------------------- + registerChange: function(itemID, state, options, cb) { + // options can include: + // - changeSpec (string) + // - excludePeerID (string) + + if ( ! _.contains([constant.ITEM_ADDED, constant.ITEM_MODIFIED, + constant.ITEM_DELETED], state) ) + return cb(new common.TypeError( + 'registerChange: invalid state "' + state + '"')); + + options = options || {}; + var self = this; + if ( self._a.isLocal ) + { + // TODO: THIS NEEDS TO BE SIGNIFICANTLY OPTIMIZED!... either: + // a) optimize this reverse lookup, or + // b) use a query that targets exactly the set of stores needed + // note that a pre-emptive model.session.flush() may be necessary. + common.cascade(self._a.getPeers(), function(peer, cb) { + if ( options.excludePeerID && options.excludePeerID == peer.id ) + return cb(); + common.cascade(peer.getStores(), function(store, cb) { + var binding = store._getBinding() + if ( ! binding || binding.uri != self.uri ) + return cb(); + store.registerChange(itemID, state, options, cb); + }, cb); + }, cb); + return; } - }, - "cellId": { - "name": "Cell ID", - "control": { - "type": "number", - "value": 0 + + // todo: a non-ADD change event for an ID that has never been + // seen does not create an error... should it??? that would mean + // that syncml-js needs to track that. not a good idea. + + itemID = '' + itemID; + var handled = false; + + // paranoia + if ( options.changeSpec && state != constant.ITEM_MODIFIED ) + { + options.changeSpec = null; } + + var check_update = function(cb) { + self._getChange(itemID, function(err, change) { + if ( err ) + return cb(err); + if ( ! change) + return cb(); + var badstate = function(action) { + }; + // note: many of the following change.state / state combinations + // should never occur. the following tries to recover gracefully. + // todo: should i raise an error for "illogical" conditions? + switch ( change.state ) + { + case constant.ITEM_ADDED: + { + if ( state != constant.ITEM_DELETED ) + { + // ADD + anything except DELETE stays ADD + handled = true; + return cb(); + } + // ADD + DELETE cancels out + handled = true; + var changeTab = self._a._c._txn().objectStore('change'); + storage.deleteAll(changeTab, change, function(err) { + if ( err ) + return cb(err); + return cb(); + }); + return; + } + case constant.ITEM_MODIFIED: + { + if ( state == constant.ITEM_ADDED ) + { + badstate('squelching changeSpec'); + delete change.changeSpec; + break; + } + if ( state == constant.ITEM_DELETED ) + { + change.state = state; + delete change.changeSpec; + break; + } + if ( change.changeSpec ) + { + if ( options.changeSpec ) + change.changeSpec += ';' + options.changeSpec; + else + delete change.changeSpec; + } + break; + } + case constant.ITEM_DELETED: + { + if ( state == constant.ITEM_DELETED ) + { + badstate('ignoring'); + handled = true; + return cb(); + } + badstate('reverting to modified'); + change.state = constant.ITEM_MODIFIED; + delete change.changeSpec; + break; + } + default: + { + return cb(new common.InternalError( + 'unexpected recorded change state "' + change.state + + '" for item ID "' + itemID + '"')); + } + } + // update the change + // todo: do i need to delete it first? + handled = true; + return storage.put( + self._a._c._txn().objectStore('change'), + change, + cb); + }); + }; + + var check_mapping = ( self._a._isMapper() || state == constant.ITEM_ADDED ) + ? common.noop + : function(cb) { + // doing a `_getMapping` for non-add events to make sure that + // the remote peer actually has this object before we tell it + // to modify or delete an item... + self._getMapping(itemID, function(err, luid) { + if ( err ) + return cb(err); + if ( luid ) + return cb(); + // this item does not exist as (or has not been mapped to) an + // item on the remote peer and is not an `ADD` event, so can + // therefore be ignored - mark it as "handled". + handled = true; + return cb(); + }); + }; + + // todo: there is a weirdness here wrt `handled` in the case + // of check_mapping and deletes... ie. there is a bit of + // a responsibility violation (handled does not actually + // mean handled...) + + check_update(function(err) { + if ( err ) + return cb(err); + if ( handled ) + return cb(); + check_mapping(function(err) { + if ( err ) + return cb(err); + if ( handled && state != constant.ITEM_DELETED ) + return cb(); + // note: if it is a delete event, and it has not been mapped + // yet, so does not yet exist on the peer, therefore + // propagate nothing -- continuing just to execute the + // deleteAll(). + var changeTab = self._a._c._txn().objectStore('change'); + change = {store_id: self.id, item_id: itemID}; + // todo: is this deleteAll really necessary?... paranoia rules! + storage.deleteAll(changeTab, change, function(err) { + if ( err ) + return cb(err); + if ( handled ) + return cb(); + change.state = state; + change.changeSpec = options.changeSpec; + storage.put(changeTab, change, cb); + }); + }); + }); }, - "lac": { - "name": "LAC", - "control": { - "type": "number", - "value": 0 - } + + //------------------------------------------------------------------------- + _getChange: function(itemID, cb) { + // returns cb(null, CHANGE) + // change ::= { store_id: ID, item_id: GUID, state: STATE, changeSpec: SPEC } + itemID = '' + itemID; + var self = this; + // todo: there must be a way to use IndexedDB since i have everything + // needed to generate the keyPath!... eg: + // objectStore.get({store_id:X,guid:Y})?... + var changedb = self._a._c._txn().objectStore('change').index('store_id'); + storage.getAll(self._a._c, changedb, {only: self.id}, function(err, changes) { + if ( err ) + return cb(err); + var change = _.find(changes, function(change) { + return change.item_id == itemID; + }); + return cb(null, change); + }); }, - "isRoaming": { - "name": "Roaming", - "control": { - "type": "checkbox", - "value": true - } + + //------------------------------------------------------------------------- + _delChange: function(options, cb) { + // - if options is null/empty, delete all changes recorded + // for this store + + // // todo: this is *technically* subject to a race condition... but the + // // same peer should really not be synchronizing at the same time... + // // todo: also potentially check Change.registered... + // // TODO: this could be solved by: + // // a) never updating a Change record (only deleting and replacing) + // // b) deleting Change records by ID instead of by store/item/state... + + // var objstore = session.context._txn().objectStore('change'); + // storage.iterateCursor( + // objstore.index('store_id').openCursor(peerStore.id), + // function(value, key, cb) { + // if ( value.itemID != chkcmd.source || value.state != constant.ITEM_ADDED ) + // return; + // storage.delete(objstore, key, cb); + // }, cb); + + var dbstore = this._a._c._txn().objectStore('change'); + var matches = {store_id: this.id}; + if ( options.itemID ) + matches.item_id = options.itemID; + if ( options.state ) + matches.state = options.state; + storage.deleteAll(dbstore, matches, cb); }, - "isFlightMode": { - "name": "Flight Mode", - "control": { - "type": "checkbox", - "value": false + + //------------------------------------------------------------------------- + toSyncML: function() { + var xstore = ET.Element('DataStore'); + if ( this.uri ) + ET.SubElement(xstore, 'SourceRef').text = this.uri; + if ( this.displayName ) + ET.SubElement(xstore, 'DisplayName').text = this.displayName; + if ( this.maxGuidSize ) + { + // todo: this should ONLY be sent by the client... (according to the + // spec, but not according to funambol behavior...) + ET.SubElement(xstore, 'MaxGUIDSize').text = this.maxGuidSize; } - }, - "imei": { - "name": "IMEI", - "control": { - "type": "text", - "value": "012417005203000" + if ( this.maxObjSize ) + ET.SubElement(xstore, 'MaxObjSize').text = this.maxObjSize; + + var ctypes = this.getContentTypes(); + + if ( ctypes && ctypes.length > 0 ) + { + var pref = _.filter(ctypes, function(ct) { return ct.receive && ct.preferred; }); + + // todo: should i just take the first one?... + if ( pref.length > 1 ) + throw new Error('agents can prefer at most one receive content-type'); + + if ( pref.length == 1 ) + { + pref = pref[0].toSyncML('Rx', true); + pref[0].tag = 'Rx-Pref'; + _.each(pref, function(xnode) { xstore.append(xnode); }); + } + + _.each( + _.filter(ctypes, function(ct) { return ct.receive && ! ct.preferred; }), + function(ct) { + _.each(ct.toSyncML('Rx', true), function(xnode) { + xstore.append(xnode); + }); + }); + + var pref = _.filter(ctypes, function(ct) { return ct.transmit && ct.preferred; }); + + // todo: should i just take the first one?... + if ( pref.length > 1 ) + throw new Error('agents can prefer at most one transmit content-type'); + + if ( pref.length == 1 ) + { + pref = pref[0].toSyncML('Tx', true); + pref[0].tag = 'Tx-Pref'; + _.each(pref, function(xnode) { xstore.append(xnode); }); + } + + _.each( + _.filter(ctypes, function(ct) { return ct.transmit && ! ct.preferred; }), + function(ct) { + _.each(ct.toSyncML('Tx', true), function(xnode) { + xstore.append(xnode); + }); + }); + } - } - }, - "SIM": { - "operatorName": { - "name": "Operator Name", - "control": { - "type": "text", - "value": "Tizen" + + if ( this.syncTypes && this.syncTypes.length > 0 ) + { + var xcap = ET.SubElement(xstore, 'SyncCap'); + for ( var idx=0 ; idx +// date: 2012/11/05 +// copy: (C) CopyLoose 2012 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- + +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'), + state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'), + protocol = require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'), + storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'), + _self; + +_self = (function () { + + var exports = {}; + var badStatus = protocol.badStatus; + + //--------------------------------------------------------------------------- + exports.Synchronizer = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(options) { }, - "mcc": { - "name": "MCC", - "control": { - "type": "number", - "value": 460 + + //------------------------------------------------------------------------- + initStoreSync: function(session, cb) { + async.eachSeries(session.peer._getModel().stores, function(rstore, cb) { + // TODO: should the server-side be doing this? probably not + // since store mapping is a client-side decision... + var ruri = session.peer.normUri(rstore.uri); + if ( session.info.dsstates[ruri] || ! rstore.binding ) + return cb(); + var lstore = session.adapter.getStore(rstore.binding.uri); + if ( ! lstore || ! lstore.agent ) + return cb(); + var ds = state.makeStoreSyncState({ + uri : lstore.uri, + peerUri : ruri, + lastAnchor : rstore.binding.localAnchor, + mode : session.info.mode || constant.ALERT_TWO_WAY, + action : 'alert' + }); + if ( ! ds.lastAnchor ) + { + switch ( ds.mode ) + { + case constant.ALERT_SLOW_SYNC: + case constant.ALERT_REFRESH_FROM_CLIENT: + case constant.ALERT_REFRESH_FROM_SERVER: + { + break; + } + case constant.ALERT_TWO_WAY: + case constant.ALERT_ONE_WAY_FROM_CLIENT: + case constant.ALERT_ONE_WAY_FROM_SERVER: + { + if ( session.info.mode == constant.SYNCTYPE_AUTO ) + { + ds.mode = constant.ALERT_SLOW_SYNC; + break; + } + var uaEvent = { + session : session, + store : lstore, + peerStore : rstore, + modeReq : ds.mode + }; + return session.ua.chooseRefreshRequired(uaEvent, function(err, mode) { + if ( err ) + return cb(err); + if ( ! _.contains([constant.ALERT_SLOW_SYNC, + constant.ALERT_REFRESH_FROM_CLIENT, + constant.ALERT_REFRESH_FROM_SERVER], mode) ) + return cb(new common.TypeError( + 'invalid mode chosen for refresh: ' + common.j(mode))); + ds.mode = mode; + session.info.dsstates[ds.uri] = ds; + return cb(); + }); + } + default: + { + return cb(new common.InternalError( + 'unexpected sync mode "' + ds.mode + '" requested')); + } } - }, - "mnc": { - "name": "MNC", - "control": { - "type": "number", - "value": 0 } + session.info.dsstates[ds.uri] = ds; + return cb(); + }, cb); }, - "msin": { - "name": "MSIN", - "control": { - "type": "text", - "value": "H1 H2 H3 S 12345" - } + + //------------------------------------------------------------------------- + // SYNCHRONIZATION PHASE: ACTION + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + actions: function(session, commands, cb) { + var self = this; + common.cascade(_.keys(session.info.dsstates), function(uri, cb) { + var ds = session.info.dsstates[uri]; + if ( ds.action == 'done' ) + return cb(); + // TODO: is this the right handling of an "error" dsstate?... + if ( ds.action == 'error' ) + return cb(); + var func = self['_action_' + ds.action.toLowerCase()]; + if ( ! func ) + return cb(new common.InternalError( + 'unexpected store action "' + ds.action + '"')); + try{ + func.call(self, session, ds, function(err, cmds) { + if ( err ) + return cb(err); + _.each(cmds, function(cmd) { commands.push(cmd); }); + return cb(); + }); + }catch(e){ + return cb(new common.InternalError( + 'failed invoking synchronizer action: ' + e, e)); + } + }, function(err) { + if ( err ) + return cb(err); + return cb(null, commands); + }); }, - "spn": { - "name": "SPN", - "control": { - "type": "text", - "value": "TizenSPN" + + //------------------------------------------------------------------------- + _action_alert: function(session, dsstate, cb) { + + var src = session.adapter.getStore(dsstate.uri); + var tgt = session.peer.getStore(dsstate.peerUri); + + // TODO: ensure that mode is acceptable... + + // todo: perhaps i should only specify maxObjSize if it differs from + // adapter.maxObjSize?... + + return cb(null, [state.makeCommand({ + name : constant.CMD_ALERT, + cmdID : session.nextCmdID(), + data : dsstate.mode, + source : src.uri, + target : tgt.uri, + lastAnchor : dsstate.lastAnchor, + nextAnchor : dsstate.nextAnchor, + maxObjSize : src.maxObjSize, + })]); + + }, + + //------------------------------------------------------------------------- + _action_send: function(session, dsstate, cb) { + var store = session.adapter.getStore(dsstate.uri); + var agent = store.agent; + var peerStore = session.peer.getStore(dsstate.peerUri); + + var cmd = state.makeCommand({ + name : constant.CMD_SYNC, + cmdID : session.nextCmdID(), + source : dsstate.uri, + // target : adapter.router.getTargetUri(uri), + target : dsstate.peerUri + }); + + switch ( dsstate.mode ) + { + case constant.ALERT_TWO_WAY: + case constant.ALERT_SLOW_SYNC: + case constant.ALERT_ONE_WAY_FROM_CLIENT: + case constant.ALERT_REFRESH_FROM_CLIENT: + case constant.ALERT_ONE_WAY_FROM_SERVER: + case constant.ALERT_REFRESH_FROM_SERVER: + // todo: these should only be received out-of-band, right?... + // case constant.ALERT_TWO_WAY_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: + // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: + // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: + { + break; + } + default: + { + return cb(new common.InternalError( + 'unexpected sync mode "' + common.mode2string(dsstate.mode) + '"')); + } } - } - }, - "PERIPHERAL": { - "isVideoOutputOn": { - "name": "Video Output", - "control": { - "type": "checkbox", - "value": false + + if ( session.isServer ) + { + if ( dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT + || dsstate.mode == constant.ALERT_ONE_WAY_FROM_CLIENT ) + { + cmd.noc = 0; + return cb(null, [cmd]); + } } - } - } -}; + if ( ! session.isServer ) + { + if ( dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER + || dsstate.mode == constant.ALERT_ONE_WAY_FROM_SERVER ) + { + cmd.noc = 0; + return cb(null, [cmd]); + } + } -}); -define('ripple/platform/tizen/2.0/spec/sensor', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var event = require('ripple/event'); + switch ( dsstate.mode ) + { -function sensorStatusEventTrigger(setting) { - event.trigger("SensorStatusChanged", [setting]); -} + case constant.ALERT_TWO_WAY: + case constant.ALERT_ONE_WAY_FROM_CLIENT: // when ! session.isServer + case constant.ALERT_ONE_WAY_FROM_SERVER: // when session.isServer + { + // send local changes + + storage.getAll( + session.context, + session.txn().objectStore('change').index('store_id'), + {only: peerStore.id}, + function(err, changes) { + if ( err ) + return cb(err); + var ctype = session.context.router.getBestTransmitContentType( + session.adapter, session.peer, dsstate.uri); + cmd.data = []; + + // TODO: add support for hierarchical operations... + // including MOVE, COPY, etc. + + // TODO: this assumes that the entire object set can fit in memory... + // perhaps, as a work-around, just keep a reference to the object + // and then stream-based serialize it actually gets converted to + // XML. + + common.cascade(changes, function(change, cb) { + + if ( dsstate.conflicts && _.indexOf(dsstate.conflicts, change.item_id) >= 0 ) + return cb(); + + var scmdtype = null; + switch ( change.state ) + { + case constant.ITEM_ADDED: scmdtype = constant.CMD_ADD; break; + case constant.ITEM_MODIFIED: scmdtype = constant.CMD_REPLACE; break; + case constant.ITEM_DELETED: scmdtype = constant.CMD_DELETE; break; + default: + { + return cb(); + } + } -module.exports = { - "Accelerometer": { - "resolution": 0.039239998906850815, - "minDelay": 20, - "range": 20.051639556884766, - "name": "Accelerometer", - "type": "Accelerometer" - }, - "MagneticField": { - "x": { - "name": "X", - "control": { - "type": "range", - "value": 100.0000000000000000, - "min": 0.0000000000000000, - "max": 200.0000000000000000, - "step": 0.0000000000000001 - }, - "callback": function (setting) { - event.trigger("MagneticField-xChanged", [setting]); + // todo: do something with the ctype version (ie. ctype[1])?... + var scmd = state.makeCommand({ + name : scmdtype, + cmdID : session.nextCmdID(), + format : constant.FORMAT_AUTO, + type : change.state != constant.ITEM_DELETED ? ctype[0] : null, + uri : dsstate.uri + }); + + // TODO: need to add hierarchical addition support here... + + var set_data = scmdtype == constant.CMD_DELETE ? common.noop : function(cb) { + + agent.getItem(change.item_id, function(err, item) { + if ( err ) + return cb(err); + agent.dumpsItem(item, ctype[0], ctype[1], function(err, data, nct, nv) { + if ( err ) + return cb(err); + scmd.data = data; + scmd.type = nct || scmd.type; + // todo: what to do with the content-type version?... eg. + // scmd.version = nv || scmd.version; + // TODO: support hierarchical sync + // if ( agent.hierarchicalSync && item.parent ) + // scmd.sourceParent = '' + item.parent + return cb(); + }); + }); + }; + + var set_target = scmdtype == constant.CMD_ADD ? function(cb) { + scmd.source = change.item_id; + cb(); + } : function(cb) { + if ( ! session.isServer ) + { + scmd.source = change.item_id; + return cb(); + } + peerStore._getMapping(change.item_id, function(err, luid) { + if ( err ) + return cb(err); + if ( luid ) + scmd.target = luid; + else + scmd.source = change.item_id; + cb(); + }); + }; + + set_data(function(err) { + if ( err ) + return cb(err); + set_target(function(err) { + if ( err ) + return cb(err); + cmd.data.push(scmd); + return cb(); + }); + }); + }, function(err) { + if ( err ) + return cb(err); + cmd.noc = cmd.data.length; + return cb(null, [cmd]); + }); + } + ); + return; + } + case constant.ALERT_SLOW_SYNC: + case constant.ALERT_REFRESH_FROM_SERVER: // when session.isServer + case constant.ALERT_REFRESH_FROM_CLIENT: // when ! session.isServer + { + // todo: this approach assumes that the entire object set can fit + // in memory... perhaps move to an iterator-based approach?... + cmd.data = []; + + agent.getAllItems(function(err, items) { + + if ( err ) + return cb(err); + + // TODO: support hierarchical sync... + + if ( agent.hierarchicalSync ) + { + return cb(new common.NotImplementedError('hierarchical-sync')); + // orditems = [] # the ordered items + // dunitems = dict() # lut of the ordered items + // curitems = dict() # lut of current items (for loop detection) + // lutitems = dict([(item.id, item) for item in items]) + // def appenditem(item): + // if item.id in dunitems: + // return + // if item.id in curitems: + // raise common.LogicalError('recursive item hierarchy detected at item %r' % (item,)) + // curitems[item.id] = True + // if item.parent is not None: + // appenditem(lutitems[item.parent]) + // orditems.append(item) + // dunitems[item.id] = item + // for item in items: + // curitems = dict() + // appenditem(item) + } + + var ctype = session.context.router.getBestTransmitContentType( + session.adapter, session.peer, dsstate.uri); + + common.cascade(items, function(item, cb) { + + // TODO: these should all be non-deleted items, right?... + + if ( _.indexOf(dsstate.conflicts, '' + item.id) >= 0 ) + return cb(); + + // note: need to check for mappings since on slow-sync, the + // server will already have received the client's "add" commands + // at this point (and therefore should not send them back...) + var check_sync = function(cb) { + if ( ! session.isServer ) + return cb(null, true); + peerStore._getMapping(item.id, function(err, luid) { + return cb(err, luid ? false : true); + }); + }; + + check_sync(function(err, dosync) { + if ( err ) + return cb(err); + + if ( ! dosync ) + return cb(); + + agent.dumpsItem( + item, ctype[0], ctype[1], + function(err, data, new_ct, new_v) { + + if ( err ) + return cb(err); + + // todo: do something with the content-type version... + var scmd = state.makeCommand({ + name : constant.CMD_ADD, + cmdID : session.nextCmdID(), + format : constant.FORMAT_AUTO, + type : new_ct || ctype[0], + uri : dsstate.uri, + source : '' + item.id, + data : data + }); + + if ( agent.hierarchicalSync ) + { + // TODO: support hierarchical sync... + // if agent.hierarchicalSync and item.parent is not None: + // scmd.sourceParent = str(item.parent) + return cb(new common.NotImplementedError('hierarchical-sync')); + } + + cmd.data.push(scmd); + return cb(); + }); + + }); + + }, function(err) { + if ( err ) + return cb(err); + cmd.noc = cmd.data.length; + return cb(null, [cmd]); + }); + + }); + return; + } } - }, - "y": { - "name": "Y", - "control": { - "type": "range", - "value": 100.0000000000000000, - "min": 0.0000000000000000, - "max": 200.0000000000000000, - "step": 0.0000000000000001 - }, - "callback": function (setting) { - event.trigger("MagneticField-yChanged", [setting]); - } - }, + return cb(new common.InternalError( + 'unexpected sync situation (action=' + dsstate.action + + ', mode=' + common.mode2string(dsstate.mode) + + ', isServer=' + ( session.isServer ? '1' : '0' ) + ')')); + }, + + //------------------------------------------------------------------------- + _action_save: function(session, dsstate, cb) { + if ( ! session.isServer ) + // TODO: for now, only servers should take the "save" action - the client + // will explicitly do this at the end of the .sync() method. + // ... mostly because clients don't call synchronizer.actions() + // one final time ... + // *BUT* perhaps that should be changed?... for example, .sync() + // could call synchronizer.actions() to cause action_save's to occur + // *AND* verify that synchronizer.actions() does not return anything... + return cb(new common.InternalError( + 'unexpected sync save situation (action=' + dsstate.action + + ', mode=' + common.mode2string(dsstate.mode) + + ', isServer=' + ( session.isServer ? '1' : '0' ) + ')')); + + var peerStore = session.peer.getStore(dsstate.peerUri); + var binding = peerStore._getBinding(); + binding.localAnchor = dsstate.nextAnchor; + binding.remoteAnchor = dsstate.peerNextAnchor; + return cb(null); + }, + + //------------------------------------------------------------------------- + // SYNCHRONIZATION PHASE: REACTION + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + reactions: function(session, commands, cb) { + var self = this; + var ret = []; + session.hierlut = null; + common.cascade(commands, function(cmd, cb) { + var func = self['_reaction_' + cmd.name.toLowerCase()]; + if ( ! func ) + return cb(new common.InternalError( + 'unexpected store reaction "' + cmd.name + '"')); + try{ + func.call(self, session, cmd, function(err, cmds) { + if ( err ) { + return cb(err); + } + _.each(cmds, function(cmd) { ret.push(cmd); }); + return cb(); + }); + }catch(e){ + return cb(new common.InternalError( + 'failed invoking synchronizer reaction: ' + e, e)); + } + }, function(err) { + session.hierlut = null; + if ( err ) + return cb(err); + return cb(null, ret); + }); + }, + + //------------------------------------------------------------------------- + _reaction_sync: function(session, command, cb) { + var self = this; + var ret = [state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : command.msgID, + cmdRef : command.cmdID, + targetRef : command.target, + sourceRef : command.source, + statusOf : command.name, + statusCode : constant.STATUS_OK + })]; + var store = session.adapter.getStore(session.adapter.normUri(command.target)); + var dsstate = session.info.dsstates[store.uri]; + if ( ! store.agent ) + { + // todo: this is a bit different handling than anywhere else... + // should everywhere else be like here, or the other way + // round?... + // the "REAL BIG ISSUE" is that atomicity of the changes + // is a little vague at this point... + dsstate.stats.hereErr += 1; + dsstate.action = 'error'; + dsstate.error = { + message: 'Sync agent for store "' + store.uri + '" not available', + code: 'syncml-js.TypeError' + }; + ret[0].statusCode = constant.STATUS_SERVICE_UNAVAILABLE; + ret[0].errorMsg = dsstate.error.message; + ret[0].errorCode = dsstate.error.code; + return cb(null, ret); + } + + if ( store.agent.hierarchicalSync ) + session.hierlut = {}; + + var preprocess = common.noop; + + if ( ( ! session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER ) + || ( session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT ) ) + { + // delete all local items + preprocess = function(cb) { + store.agent.getAllItems(function(err, items) { + if ( err ) + return cb(err); + common.cascade(items, function(item, cb) { + store.agent.deleteItem(item.id, function(err) { + if ( err ) + return cb(err); + dsstate.stats.hereDel += 1; + if ( ! session.isServer ) + return cb(); + store.registerChange(item.id, constant.ITEM_DELETED, + {excludePeerID: session.peer.id}, cb); + }); + }, function(err) { + if ( err ) + return cb(err); + return store.getPeerStore(session.peer)._delChange({}, cb); + }); + }); + }; + } + + if ( dsstate.mode == constant.ALERT_SLOW_SYNC + || ( session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER ) ) + { + // delete all mappings and pending changes + var peerStore = store.getPeerStore(session.peer); + var prepreprocess = preprocess; + preprocess = function(cb) { + prepreprocess(function(err) { + if ( err ) + return cb(err); + peerStore._delChange({}, function(err) { + if ( err ) + return cb(err); + peerStore._clearAllMappings(cb); + }); + }); + }; + } + + preprocess(function(err) { + if ( err ) + return cb(err); + + if ( command.data.length <= 0 ) + return cb(null, ret); + + // paranoia: verify that i should be receiving data... + if ( ! ( dsstate.mode == constant.ALERT_TWO_WAY + || dsstate.mode == constant.ALERT_SLOW_SYNC + || ( ! session.isServer + && ( dsstate.mode == constant.ALERT_ONE_WAY_FROM_SERVER + || dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER ) ) + || ( session.isServer + && ( dsstate.mode == constant.ALERT_ONE_WAY_FROM_CLIENT + || dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT ) ) ) ) + return cb(new common.ProtocolError( + 'unexpected sync data (role="' + + ( session.isServer ? 'server' : 'client' ) + + '", mode="' + common.mode2string(dsstate.mode) + + '")')); + + common.cascade(command.data, function(cmd, cb) { + + // NOTE: commented this paranoia setting out, since the server + // *may* decide to update/delete a client item... + // e.g. conflict-resolved-merge (207) + // TODO: perhaps i should only allow non-ADDs for those items + // that i received a conflict-resolved-merge (207) for?... + + // // paranoia: non-'add' sync commands should only be received in non-refresh modes + // if ( cmd.name != constant.CMD_ADD + // && _.indexOf([constant.ALERT_TWO_WAY, + // constant.ALERT_ONE_WAY_FROM_SERVER, + // constant.ALERT_ONE_WAY_FROM_CLIENT], dsstate.mode) < 0 ) + // return cb(new common.ProtocolError( + // 'unexpected non-add sync command (role="' + // + ( session.isServer ? 'server' : 'client' ) + // + '", mode="' + common.mode2string(dsstate.mode) + // + '", command="' + cmd.name + // + '")')); + + self._reaction_syncdispatch(session, cmd, store, dsstate, function(err, cmds) { + if ( err ) + return cb(err); + _.each(cmds, function(cmd) { ret.push(cmd); }); + return cb(); + }); + + }, function(err) { + if ( err ) + return cb(err); + return cb(null, ret); + }); + }); + }, + + //------------------------------------------------------------------------- + _reaction_syncdispatch: function(session, cmd, store, dsstate, cb) { + + var self = this; + var func = self['_reaction_sync_' + cmd.name.toLowerCase()]; + if ( ! func ) + return cb(new common.ProtocolError( + 'unexpected reaction requested for sync command "' + cmd.name + '"')); + + var check_for_conflicts = common.noop; + + if ( session.isServer + && cmd.name != constant.CMD_ADD + && dsstate.mode != constant.ALERT_REFRESH_FROM_CLIENT ) + { + // server, non-add, non-slowsync, non-refresh commands: check for conflicts. + // note that certain types of content could be a conflict even if it is an + // "Add" command; for example, two files with the same name cannot be added + // from separate clients. + + check_for_conflicts = function(cb) { + + // todo: allow agents to raise a ConflictError... + // ==> perhaps this is already covered by the .matchItem() API?... + + var policy = store.conflictPolicy || session.adapter.conflictPolicy; + var peerStore = session.peer.getStore(dsstate.peerUri); + self.getSourceMapping( + session, constant.CMD_SYNC, cmd, peerStore, cmd.source, + function(err, itemID) { + + if ( err ) + return cb(err); + if ( ! itemID ) + // this shouldn't happen... + return cb(); + + peerStore._getChange(itemID, function(err, change) { + if ( err ) + return cb(err); + if ( ! change ) + return cb(); + + var retcmd = state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : cmd.msgID, + cmdRef : cmd.cmdID, + sourceRef : cmd.source, + targetRef : cmd.target, + statusOf : cmd.name, + // todo: make this error message a bit more descriptive... + errorMsg : 'command "' + cmd.name + '" conflict for item ID "' + + itemID + '" (state: ' + common.state2string(change.state) + ')' + }); + + + // four possible states: mod-mod, mod-del, del-mod, del-del + if ( ! dsstate.conflicts ) + dsstate.conflicts = []; + + // handle mod-mod (but only if change-tracking is enabled) + if ( change.state == constant.ITEM_MODIFIED + && cmd.name == constant.CMD_REPLACE ) + { + cmd._conflict = retcmd; + cmd._change = change; + return cb(); + } + + // handle del-del + if ( change.state == constant.ITEM_DELETED + && cmd.name == constant.CMD_DELETE ) + { + // both changes are deletes... that's not a conflict. + // TODO: should i really be doing all this here?... it does not + // follow the pattern.. + peerStore._delChange({ + itemID: change.item_id, + state: change.state + }, function(err) { + if ( err ) + return cb(err); + dsstate.stats.peerDel += 1; + dsstate.stats.hereDel += 1; + dsstate.stats.merged += 1; + retcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_MERGE; + retcmd.errorCode = null; + retcmd.errorMsg = null; + return cb(null, [retcmd]); + }); + return; + } + + // handle del-mod or mod-del + if ( ( change.state == constant.ITEM_DELETED + || cmd.name == constant.CMD_DELETE ) + && policy != constant.POLICY_ERROR ) + { + // one of them is a delete and a conflict that can be solved + // by the framework + cmd._conflict = retcmd; + cmd._change = change; + return cb(); + } + + dsstate.conflicts.push(itemID); + dsstate.stats.peerErr += 1; + dsstate.stats.conflicts += 1; + retcmd.statusCode = constant.STATUS_UPDATE_CONFLICT; + retcmd.errorCode = 'syncml-js.synchronizer.RSd.10'; + return cb(null, [retcmd]); + }); + } + ); + }; + } + + check_for_conflicts(function(err, cmds) { + if ( err || cmds ) + return cb(err, cmds); + try{ + func.call(self, session, cmd, store, dsstate, cb); + }catch(e){ + return cb(new common.InternalError( + 'failed invoking synchronizer sync reaction: ' + e, e)); + } + }); + + }, + + //------------------------------------------------------------------------- + _reaction_sync_add: function(session, cmd, store, dsstate, cb) { + var curitem = null; + var item = null; + if ( store.agent.hierarchicalSync ) + { + if ( cmd.targetParent ) + cmd.data.parent = cmd.targetParent; + else if ( cmd.sourceParent ) + cmd.data.parent = session.hierlut[cmd.sourceParent]; + } + + var matcher = common.noop; + if ( session.isServer && dsstate.mode == constant.ALERT_SLOW_SYNC ) + { + // TODO: if the matched item is already mapped to another client-side + // object, then this should cancel the matching... + matcher = function(cb) { + store.agent.matchItem(cmd.data, function(err, match) { + if ( err ) + return cb(err); + if ( ! match || ! match.compare ) + return cb(); + curitem = match; + if ( match.compare(cmd.data) == 0 ) + return cb(); + store.agent.mergeItems(curitem, cmd.data, null, function(err) { + // TODO: if there is a common.ConflictError, set + // curitem to null and continue without error... + if ( err ) + return cb(err); + store.registerChange(curitem.id, constant.ITEM_MODIFIED, + {changeSpec: cspec, excludePeerID: session.peer.id}, + cb); + }); + }); + }; + } + + matcher(function(err) { + if ( err ) + return cb(err); + var adder = common.noop; + if ( ! curitem ) + adder = function(cb) { + store.agent.addItem(cmd.data, function(err, newitem) { + if ( err ) + return cb(err); + item = newitem; + dsstate.stats.hereAdd += 1; + store.registerChange(item.id, constant.ITEM_ADDED, + {excludePeerID: session.peer.id}, cb); + }); + }; + else + item = curitem; + return adder(function(err) { + if ( err ) + return cb(err); + + if ( store.agent.hierarchicalSync ) + session.hierlut[cmd.source] = item.id; + + var ret = [state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : cmd.msgID, + cmdRef : cmd.cmdID, + sourceRef : cmd.source, + statusOf : cmd.name, + statusCode : ( curitem + ? constant.STATUS_ALREADY_EXISTS + : constant.STATUS_ITEM_ADDED ) + })]; + + if ( ! session.isServer ) + { + ret.push(state.makeCommand({ + name : constant.CMD_MAP, + cmdID : session.nextCmdID(), + source : store.uri, + target : dsstate.peerUri, + sourceItem : item.id, + targetItem : cmd.source + })); + return cb(null, ret); + } + + var peerStore = session.peer.getStore(dsstate.peerUri); + peerStore._setMapping(item.id, cmd.source, function(err) { + if ( err ) + return cb(err); + return cb(null, ret); + }); + + }); + }); + + }, + + //------------------------------------------------------------------------- + getSourceMapping: function(session, cmdctxt, cmd, peerStore, luid, cb) { + peerStore._getReverseMapping(luid, function(err, guid) { + + if ( err ) + return cb(err); + + if ( guid ) + return cb(null, guid); + + return cb(new common.InvalidItem( + 'unexpected "' + cmdctxt + '/' + cmd.name + + '" request for unmapped item ID "' + luid + '"')); + + // todo: pysyncml generates a nice cmd-specific error node: + // (which is probably over-kill) + + // curmap = adapter._context._model.Mapping.q(store_id=peerStore.id, luid=luid).one() + // return str(curmap.guid) + // except NoResultFound: + // msg = 'unexpected "%s/%s" request for unmapped item ID: %r' % (cmdctxt, cmd.name, luid) + // # todo: this is a bit of a hack when cmdctxt == 'Status'... + // return state.Command( + // name = constant.CMD_STATUS, + // cmdID = session.nextCmdID(), + // msgRef = cmd.msgID, + // cmdRef = cmd.cmdID, + // sourceRef = cmd.source, + // targetRef = cmd.target, + // statusOf = cmd.name if cmdctxt != constant.CMD_STATUS else cmdctxt, + // statusCode = constant.STATUS_COMMAND_FAILED, + // errorCode = __name__ + '.' + self.__class__.__name__ + '.GSM.10', + // errorMsg = msg, + // ) + + }); + }, + + //------------------------------------------------------------------------- + _reaction_sync_replace: function(session, cmd, store, dsstate, cb) { + + // TODO: handle hierarchical-sync... + var self = this; + var item = cmd.data; + var get_item_id = ( ! session.isServer ) ? function(cb) { + item.id = cmd.target; + return cb(); + } : function(cb) { + var peerStore = session.peer.getStore(dsstate.peerUri); + self.getSourceMapping( + session, constant.CMD_SYNC, cmd, peerStore, cmd.source, + function(err, guid) { + + if ( err ) + return cb(err); + + // todo: what if guid is null?... + + item.id = guid; + return cb(); + } + ); + }; + + var okcmd = state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : cmd.msgID, + cmdRef : cmd.cmdID, + targetRef : cmd.target, + sourceRef : cmd.source, + statusOf : cmd.name, + statusCode : constant.STATUS_OK + }); + + var handle_conflict = ( ! cmd._conflict ) ? common.noop : function(cb) { + + // if cmd._conflict is not None: + // try: + // if cmd._change.state == constant.ITEM_DELETED: + // raise common.ConflictError('item deleted') + // if cmd._change.changeSpec is None: + // raise common.ConflictError('no change tracking enabled - falling back to policy') + // cspec = store.agent.mergeItems(store.agent.getItem(item.id), item, cmd._change.changeSpec) + // dsstate.stats.hereMod += 1 + // store.registerChange(item.id, constant.ITEM_MODIFIED, + // changeSpec=cspec, excludePeerID=adapter.peer.id) + // okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_MERGE + // # NOTE: *not* suppressing the change that is registered from server + // # to client, since the merge may have resulted in an item that + // # is not identical to the one on the client. + // return [okcmd] + // except common.ConflictError, e: + // # conflict types: client=mod/server=mod or client=mod/server=del + // if store.conflictPolicy == constant.POLICY_CLIENT_WINS: + // adapter._context._model.session.delete(cmd._change) + // dsstate.stats.merged += 1 + // okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA + // if cmd._change.state == constant.ITEM_DELETED: + // # todo: this "re-creation" of a new item is detrimental to + // # clients that are tracking changes to an item (for + // # example, a SyncML svn client bridge...). but then, to + // # them, this item may already have been deleted. ugh. + // dsstate.stats.hereMod += 1 + // item = store.agent.addItem(item) + // peerStore = store.peer + // adapter._context._model.Mapping.q(store_id=peerStore.id, guid=item.id).delete() + // newmap = adapter._context._model.Mapping(store_id=peerStore.id, + // guid=item.id, + // luid=cmd.source) + // adapter._context._model.session.add(newmap) + // store.registerChange(item.id, constant.ITEM_ADDED, + // excludePeerID=adapter.peer.id) + // return [okcmd] + // # falling back to standard handling... + // elif store.conflictPolicy == constant.POLICY_SERVER_WINS: + // dsstate.stats.merged += 1 + // okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA + // return [okcmd] + // else: + // # store.conflictPolicy == constant.POLICY_ERROR or other... + // dsstate.stats.peerErr += 1 + // dsstate.stats.conflicts += 1 + // cmd._conflict.errorMsg += ', agent failed merge: ' + str(e) + // cmd._conflict.statusCode = constant.STATUS_UPDATE_CONFLICT + // cmd._conflict.errorCode = common.fullClassname(self) + '.RSR.10' + // dsstate.conflicts.append(str(item.id)) + // return [cmd._conflict] + + cb(); + + }; + + // TODO: support hierarchical-sync... + // if ( store.agent.hierarchicalSync ) + // session.hierlut[cmd.source] = item.id; + + get_item_id(function(err) { + if ( err ) + return cb(err); + handle_conflict(function(err) { + if ( err ) + return cb(err); + store.agent.replaceItem(item, session.isServer, function(err, cspec) { + if ( err ) + return cb(err); + dsstate.stats.hereMod += 1; + store.registerChange( + item.id, constant.ITEM_MODIFIED, + {changeSpec: cspec, excludePeerID: session.peer.id}, + function(err) { + if ( err ) + return cb(err); + return cb(null, [okcmd]); + } + ); + }); + }); + }); + + }, + + //------------------------------------------------------------------------- + _reaction_sync_delete: function(session, cmd, store, dsstate, cb) { + + var self = this; + var status = constant.STATUS_OK; + var itemID = null; + + var get_item_id = ( ! session.isServer ) ? function(cb) { + itemID = cmd.target; + return cb(); + } : function(cb) { + var peerStore = session.peer.getStore(dsstate.peerUri); + self.getSourceMapping( + session, constant.CMD_SYNC, cmd, peerStore, cmd.source, + function(err, guid) { + + // if not isinstance(itemID, basestring): + // return [itemID] + + if ( err ) + return cb(err); + + // todo: what if guid is null?... + + itemID = guid; + if ( ! cmd._conflict ) + return cb(); + var policy = store.conflictPolicy || session.adapter.conflictPolicy; + switch ( policy ) + { + + case constant.POLICY_CLIENT_WINS: + { + + + // TODO ::: implement these... + + // // adapter._context._model.session.delete(cmd._change) + // // status = constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA + // // session.dsstates[store.uri].stats.merged += 1 + // // # falling back to standard handling... + + // break; + + } + case constant.POLICY_SERVER_WINS: + { + + + // // adapter._context._model.session.delete(cmd._change) + // // store.peer.registerChange(itemID, constant.ITEM_ADDED) + // // session.dsstates[store.uri].stats.merged += 1 + // // cmd._conflict.statusCode = constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA + // // cmd._conflict.errorCode = None + // // cmd._conflict.errorMsg = None + // // return [cmd._conflict] + + // break; + + } + + default: + { + // a constant.POLICY_ERROR policy should have been handled by the dispatch + return cb(new common.InternalError( + 'unexpected conflictPolicy: %s', '' + policy)); + } + } + } + ); + + }; + + get_item_id(function(err) { + if ( err ) + return cb(err); + store.agent.deleteItem(itemID, function(err) { + if ( err ) + return cb(err); + dsstate.stats.hereDel += 1; + store.registerChange( + itemID, constant.ITEM_DELETED, {excludePeerID: session.peer.id}, + function(err) { + if ( err ) + return cb(err); + return cb(null, [state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : cmd.msgID, + cmdRef : cmd.cmdID, + targetRef : cmd.target, + sourceRef : cmd.source, + statusOf : cmd.name, + // todo: should this return DELETE_WITHOUT_ARCHIVE instead of OK?... + // statusCode = constant.STATUS_DELETE_WITHOUT_ARCHIVE, + statusCode : status + })]); + } + ); + }); + }); + + }, + + //------------------------------------------------------------------------- + _reaction_map: function(session, command, cb) { + var peerStore = session.peer.getStore(command.source); + if ( command.target != peerStore._getBinding().uri ) + return cb(new common.NoSuchRoute( + 'unexpected "Map" event for unbound stores (local: "' + + command.target + ', remote: "' + command.source + '")')); + common.cascade(command.items, function(item, cb) { + // todo: support hierarchical sync... + peerStore._setMapping(item.target, item.source, cb); + }, function(err) { + if ( err ) + return cb(err); + return cb(null, [state.makeCommand({ + name : constant.CMD_STATUS, + cmdID : session.nextCmdID(), + msgRef : command.msgID, + cmdRef : command.cmdID, + targetRef : command.target, + sourceRef : command.source, + statusOf : command.name, + statusCode : constant.STATUS_OK + })]); + }); + }, + + //------------------------------------------------------------------------- + // SYNCHRONIZATION PHASE: SETTLE + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + settle: function(session, cmd, chkcmd, xnode, cb) { + + // TODO: remove the "xnode" parameter... it is a hack so that i can + // call badStatus() the same way as in protocol.js + // todo: there is a bit of a disconnect between how action and reaction + // phases are called (for a list of commands), whereas the settle + // phase is called on a per-item basis... not ideal, but the protocol + // is really set up that way :( + // TODO: check all valid values of ``data``... + // todo: anything else in common?... + // todo: trap errors... + + var func = this['_settle_' + cmd.name.toLowerCase()]; + if ( ! func ) + return cb(new common.ProtocolError('unexpected settle command "' + cmd.name + '"')); + return func.call(this, session, cmd, chkcmd, xnode, cb); + }, + + //------------------------------------------------------------------------- + _settle_add: function(session, cmd, chkcmd, xnode, cb) { + switch ( cmd.data ) + { + default: + { + return cb(badStatus(xnode)); + } + case constant.STATUS_OK: + case constant.STATUS_ITEM_ADDED: + case constant.STATUS_CONFLICT_RESOLVED_DUPLICATE: + { + session.info.dsstates[chkcmd.uri].stats.peerAdd += 1; + break; + } + case constant.STATUS_ALREADY_EXISTS: + case constant.STATUS_CONFLICT_RESOLVED_MERGE: + // todo: should this conflict-resolved-merge status be stored so + // that only this item can have a non-"ADD" during initial + // sync?... + case constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA: + { + session.info.dsstates[chkcmd.uri].stats.merged += 1; + break; + } + } + + var peerStore = session.peer.getStore( + session.context.router.getTargetUri( + session.adapter, session.peer, chkcmd.uri)); + + peerStore._delChange({ + itemID: chkcmd.source, + state: constant.ITEM_ADDED + }, cb); + }, + + //------------------------------------------------------------------------- + _settle_replace: function(session, cmd, chkcmd, xnode, cb) { + + var self = this; + var dsstate = session.info.dsstates[chkcmd.uri]; + + if ( ! session.isServer && cmd.data == constant.STATUS_UPDATE_CONFLICT ) + { + dsstate.stats.hereErr += 1; + dsstate.stats.conflicts += 1; + return cb(); + } + if ( cmd.data != constant.STATUS_OK + && cmd.data != constant.STATUS_CONFLICT_RESOLVED_MERGE + && cmd.data != constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA + && cmd.data != constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA ) + return cb(badStatus(xnode)); + if ( cmd.data == constant.STATUS_CONFLICT_RESOLVED_MERGE + || cmd.data == constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA + || cmd.data == constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA ) + dsstate.stats.merged += 1; + if ( cmd.data != constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA ) + dsstate.stats.peerMod += 1; + + var peerStore = session.peer.getStore( + session.context.router.getTargetUri( + session.adapter, session.peer, chkcmd.uri)); + + var get_item_id = ( ! session.isServer ) ? function(cb) { + return cb(null, chkcmd.source); + } : function(cb) { + // if not isinstance(locItemID, basestring): + // return locItemID + + self.getSourceMapping( + session, constant.CMD_STATUS, cmd, peerStore, chkcmd.target, + function(err, guid) { return cb(err, guid); } + ); + }; + + get_item_id(function(err, locItemID) { + + if ( err ) + return cb(err); + + // todo: this is *technically* subject to a race condition... but the + // same peer should really not be synchronizing at the same time... + // todo: also potentially check Change.registered... + // TODO: this could be solved by: + // a) never updating a Change record (only deleting and replacing) + // b) deleting Change records by ID instead of by store/item/state... - "z": { - "name": "Z", - "control": { - "type": "range", - "value": 100.0000000000000000, - "min": 0.0000000000000000, - "max": 200.0000000000000000, - "step": 0.0000000000000001 - }, - "callback": function (setting) { - event.trigger("MagneticField-zChanged", [setting]); - } - }, + peerStore._delChange({ + itemID : locItemID, + state : constant.ITEM_MODIFIED, + }, cb); - "resolution": 1, - "minDelay": 20, - "range": 359, - "name": "MagneticField", - "type": "MagneticField" - }, - "Rotation": { - "resolution": 1, - "minDelay": 20, - "range": 359, - "name": "Rotation", - "type": "Rotation" - }, - "Orientation": { - "resolution": 1, - "minDelay": 20, - "range": 359, - "name": "Orientation", - "type": "Orientation" - } -}; + }); -}); -define('ripple/platform/tizen/2.0/spec/ui', function (require, exports, module) { -/* - * Copyright 2011 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -module.exports = { - plugins: [ - "sensors", - "communication", - "geoView", - "widgetConfig", - "deviceSettings", - "application", - "network", - "power", - "download", - "package" - ] -}; + }, + + //------------------------------------------------------------------------- + _settle_delete: function(session, cmd, chkcmd, xnode, cb) { + var self = this; + var dsstate = session.info.dsstates[chkcmd.uri]; + if ( ! session.isServer && cmd.data == constant.STATUS_UPDATE_CONFLICT ) + { + dsstate.stats.hereErr += 1; + dsstate.stats.conflicts += 1; + return cb(); + } + if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_MERGE ) + { + dsstate.stats.hereDel += 1; + dsstate.stats.peerDel += 1; + dsstate.stats.merged += 1; + } + else if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA ) + { + dsstate.stats.peerDel += 1; + dsstate.stats.merged += 1; + } + else if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA ) + dsstate.stats.merged += 1; + else if ( cmd.data == constant.STATUS_ITEM_NOT_DELETED ) + { + // note: the reason that this *may* be ok is that some servers (funambol) + // will report ITEM_NOT_DELETED when the item did not exist, thus this + // is "alright"... + // todo: perhaps this should be raised as an error if the + // remote peer != funambol?... + } + else if ( cmd.data == constant.STATUS_OK ) + dsstate.stats.peerDel += 1; + else + return cb(badStatus(xnode)); + + var peerStore = session.peer.getStore( + session.context.router.getTargetUri( + session.adapter, session.peer, chkcmd.uri)); + + // todo: handle hierarchical sync... + var get_locItemID = ( ! chkcmd.target ) ? function(cb) { + cb(null, chkcmd.source); + } : function(cb) { + self.getSourceMapping( + session, constant.CMD_STATUS, cmd, peerStore, chkcmd.target, + function(err, guid) { return cb(err, guid); } + ); + }; + + // todo: this is *technically* subject to a race condition... but the + // same peer should really not be synchronizing at the same time... + // todo: also potentially check Change.registered... + // TODO: this could be solved by: + // a) never updating a Change record (only deleting and replacing) + // b) deleting Change records by ID instead of by store/item/state... + + get_locItemID(function(err, locItemID) { + if ( err ) + return cb(err); + peerStore._delChange({ + itemID : locItemID, + state : constant.ITEM_DELETED, + }, cb); + }); + + } + + }); + + return exports; + +})(); + +module.exports = _self; }); -define('ripple/platform/tizen/2.0/spec', function (require, exports, module) { -/* - * Copyright 2012 Intel Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +define('ripple/platform/tizen/2.0/syncml-js-lib/useragent', function (require, exports, module) { +// -*- coding: utf-8 -*- +//----------------------------------------------------------------------------- +// file: $Id$ +// lib: syncml-js.useragent +// auth: griffin +// date: 2013/06/07 +// copy: (C) CopyLoose 2013 UberDev , No Rights Reserved. +//----------------------------------------------------------------------------- -module.exports = { +var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'), + constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'), + _self; - id: "tizen", - version: "2.1", - name: "TIZEN", +_self = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + exports.UserAgent = common.Base.extend({ + // primary handlers: + acceptSyncModeSwitch: null, // function(EVENT, CALLBACK(ERR)) + acceptDevInfoSwap: null, // function(EVENT, CALLBACK(ERR)) + chooseRefreshRequired: null, // function(EVENT, CALLBACK(ERR, TYPE)) + fetchCredentials: null, // function(EVENT, CALLBACK(ERR, AUTH)) + // fallback handlers: + accept: null, // function(TYPE, EVENT, CALLBACK(ERR)) + choose: null, // function(TYPE, EVENT, CALLBACK(ERR, CHOICE)) + fetch: null, // function(TYPE, EVENT, CALLBACK(ERR, STRUCT)) + // catchall handler: + handle: null // function(ACTION, TYPE, EVENT, CALLBACK(ERR, RESULT...)) + }); + + //--------------------------------------------------------------------------- + exports.UserAgentMultiplexer = common.Base.extend({ + + //------------------------------------------------------------------------- + constructor: function(uaList) { + this.ualist = uaList; + }, - persistencePrefix: "tizen1-", + //------------------------------------------------------------------------- + _getHandler: function(name) { + for ( var idx=0 ; idx 0 ) + { + var choice = _.find(event.choices, function(c) { return c.default; }); + if ( ! choice ) + choice = event.choices[0]; + if ( choice.value ) + choice = choice.value; + return cb(null, choice); } + if ( spec.type == 'auth.challenge' ) + return cb(); + return cb(new common.NotImplementedError( + 'user-agent handler for event type "' + spec.type + '" (action: "' + + spec.action + '") not found or defined')); } - } -}; + + }); + + return exports; + +})(); + +module.exports = _self; }); define('ripple/platform/tizen/2.0/systeminfo', function (require, exports, module) { @@ -90456,9 +102339,10 @@ define('ripple/platform/tizen/2.0/systeminfo', function (require, exports, modul * limitations under the License. */ -var utils = require('ripple/utils'), - deviceSettings = require('ripple/deviceSettings'), +var deviceSettings = require('ripple/deviceSettings'), db = require('ripple/db'), + t = require('ripple/platform/tizen/2.0/typedef'), + TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), constants = require('ripple/constants'), event = require('ripple/event'), tizen_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), @@ -90472,34 +102356,26 @@ var utils = require('ripple/utils'), _powerData = {}, _security = { "http://tizen.org/privilege/system": ["SystemInfoSIM", "webApiVersion", "nativeApiVersion", "platformVersion"], - "http://tizen.org/privilege/systemmanager": ["NetworkImei"], - all: true + "http://tizen.org/privilege/systemmanager": ["NetworkImei"] }, - _propertyValues = {}, _self; -function _asynchErrorCallback(errorCallback, errorCode) { - if (errorCallback) { - setTimeout(function () { - errorCallback(errorCode); - }, 1); - } -} - function _prepareObj(obj, aspect, property, value) { if ((aspect === "CELLULAR_NETWORK") && (property === "imei")) { obj.__defineGetter__("imei", function () { - if (!_security.all && !_security.NetworkImei) { + if (!_security.NetworkImei) { throw new WebAPIError(errorcode.SECURITY_ERR); } return deviceSettings.retrieve("CELLULAR_NETWORK.imei"); }); } else { if (aspect === "WIFI_NETWORK" || aspect === "CELLULAR_NETWORK") { - if (obj["status"] === true) { - obj["status"] = "ON"; - } else { - obj["status"] = "OFF"; + if (property === 'status') { + if (value === true) { + value = "ON"; + } else { + value = "OFF"; + } } } obj.__defineGetter__(property, function () { @@ -90508,28 +102384,29 @@ function _prepareObj(obj, aspect, property, value) { } } -function _getValue(aspect, successCallback, errorCallback) { +function _getValue(aspect, successCallback) { var properties = [], value, index = 0, property, obj = {}; - if ((aspect === "SIM") && !_security.all && !_security.SystemInfoSIM) { + if ((aspect === "SIM") && !_security.SystemInfoSIM) { throw new WebAPIError(errorcode.SECURITY_ERR); } if (aspect === "BATTERY") { - successCallback(utils.copy(_powerData)); + successCallback(_powerData); return; } properties = _propertyMap[aspect]; for (; index < properties.length; index++) { property = properties[index]; - value = deviceSettings.retrieve(aspect + "." + property); _prepareObj(obj, aspect, property, value); } if (aspect === "STORAGE") { - obj = [obj]; + obj.__defineGetter__("units", function () { + return [obj]; + }); } successCallback(obj); @@ -90548,15 +102425,23 @@ function _initialize() { _propertyMap.BATTERY.push("level"); _propertyMap.BATTERY.push("isCharging"); - _powerData.isCharging = false; - vol = db.retrieve(constants.BATTERY.VOLUME) || 100.0; + _powerData.__defineGetter__("isCharging", function () { + return false; + }); - _powerData.level = Number((vol / 100.0).toFixed(4)); + vol = db.retrieve(constants.BATTERY.VOLUME) || 100.0; + _powerData.__defineGetter__("level", function () { + return Number((vol / 100.0).toFixed(4)); + }); event.on("BatteryEvent", function (status) { - _powerData.isCharging = status.charging; - _powerData.level = Number(status.level.toFixed(4)); + _powerData.__defineGetter__("isCharging", function () { + return status.charging; + }); + _powerData.__defineGetter__("level", function () { + return Number(status.level.toFixed(4)); + }); }); } @@ -90615,22 +102500,22 @@ function _rtnCapability() { return false; }); _self.__defineGetter__("platformVersion", function () { - if (!_security.all && !_security.platformVersion) { + if (!_security.platformVersion) { throw new WebAPIError(errorcode.SECURITY_ERR); } - return "2.1"; + return "2.2"; }); _self.__defineGetter__("webApiVersion", function () { - if (!_security.all && !_security.webApiVersion) { + if (!_security.webApiVersion) { throw new WebAPIError(errorcode.SECURITY_ERR); } - return "2.1"; + return "2.2"; }); _self.__defineGetter__("nativeApiVersion", function () { - if (!_security.all && !_security.nativeApiVersion) { + if (!_security.nativeApiVersion) { throw new WebAPIError(errorcode.SECURITY_ERR); } - return "2.1"; + return "2.2"; }); _self.__defineGetter__("platformName", function () { return "Tizen"; @@ -90785,6 +102670,12 @@ function _rtnCapability() { _self.__defineGetter__("nativeOspCompatible", function () { return false; }); + _self.__defineGetter__("inputKeyBack", function () { + return true; + }); + _self.__defineGetter__("inputKeyMenu", function () { + return true; + }); return _self; } @@ -90801,16 +102692,22 @@ _self = function () { } function getPropertyValue(propertyId, successCallback, errorCallback) { - if (typeof propertyId !== 'string') { + if (arguments.length === 2) { + errorCallback = null; + } + if (!(new TypeCoerce(t.DOMString)).match(propertyId)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } if (_isPropertyFound(propertyId) === false) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (typeof successCallback !== "function" || (errorCallback !== null && errorCallback !== undefined && typeof errorCallback !== "function")) { + if (!(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (!(new TypeCoerce(t.ErrorCallback)).match(errorCallback) && (arguments.length !== 2)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } + return tizen_utils.validateTypeMismatch(successCallback, errorCallback, "getPropertyValue", function () { setTimeout(_getValue(propertyId, successCallback, errorCallback), 1); // Simulate a async operation @@ -90822,7 +102719,27 @@ _self = function () { function addPropertyValueChangeListener(propertyId, successCallback, options) { // no error callback in spec, as of 2.0.0 RC7. var WatchOBJ; - + if (arguments.length === 2) { + options = null; + } + if (!(new TypeCoerce(t.DOMString)).match(propertyId)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (_isPropertyFound(propertyId) === false) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (!(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + if (options !== null) { + if ((typeof options !== 'object') || + (options.hasOwnProperty("timeout") && typeof options.timeout !== 'number') || + (options.hasOwnProperty("highThrashold") && typeof options.highThrashold !== 'number') || + (options.hasOwnProperty("lowThrashold") && typeof options.lowThrashold !== 'number')) + { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + } WatchOBJ = function (deviceEventType, propertyId, successCallback) { var obj = this; this.eventType = deviceEventType; @@ -90843,22 +102760,6 @@ _self = function () { }; }; - if (typeof propertyId !== 'string') { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - if (_isPropertyFound(propertyId) === false) { - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); - } - if (options !== undefined && options !== null) { - if ((typeof options !== 'object') || - (options.hasOwnProperty("timeout") && typeof options.timeout !== 'number') || - (options.hasOwnProperty("highThrashold") && typeof options.highThrashold !== 'number') || - (options.hasOwnProperty("lowThrashold") && typeof options.lowThrashold !== 'number')) - { - throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); - } - } - return tizen_utils.validateTypeMismatch(successCallback, null, "addPropertyValueChangeListener", function () { var watchId = (new Date()).getTime(), _options = new Object(options), @@ -90938,15 +102839,12 @@ _self = function () { } function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); } } @@ -90982,22 +102880,17 @@ define('ripple/platform/tizen/2.0/systemsetting', function (require, exports, mo * limitations under the License. */ -var utils = require('ripple/utils'), - db = require('ripple/db'), - constants = require('ripple/constants'), +var db = require('ripple/db'), event = require('ripple/event'), - tizen_utils = require('ripple/platform/tizen/2.0/tizen1_utils'), t = require('ripple/platform/tizen/2.0/typedef'), TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), errorcode = require('ripple/platform/tizen/2.0/errorcode'), - WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'), WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), _systemSettingTypes = ["HOME_SCREEN", "LOCK_SCREEN", "INCOMING_CALL", "NOTIFICATION_EMAIL"], _systemSettings = {}, DBSYSTEMSETTING_KEY = "tizen2-systemsetting", _security = { - "http://tizen.org/privilege/setting": ["setProperty"], - all: true + "http://tizen.org/privilege/setting": ["setProperty"] }, _self = {}; @@ -91018,89 +102911,66 @@ function _initialize() { } _self = function () { - function setProperty (type, value, successCallback, errorCallback) { - if (!_security.all && !_security.setProperty) { - throw new WebAPIError(errorcode.SECURITY_ERR); + function setProperty(type, value, successCallback, errorCallback) { + if (!_security.setProperty) { + throw new WebAPIException(errorcode.SECURITY_ERR); } if (!(new TypeCoerce(t.DOMString)).match(type)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } if (!_isTypeFound(type)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR)); - } - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } if (!(new TypeCoerce(t.DOMString)).match(value)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } if (!(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } + if (!(new TypeCoerce(t.ErrorCallback)).match(errorCallback) && (arguments.length !== 3)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY); _systemSettings[type] = value; - db.saveObject(DBSYSTEMSETTING_KEY, _systemSettings); event.trigger("SystemSettingChanged"); - successCallback(); + setTimeout(function () { + successCallback(); + }, 1); } - function getProperty (type, successCallback, errorCallback) { + function getProperty(type, successCallback, errorCallback) { + if (arguments.length === 2) { + errorCallback = null; + } if (!(new TypeCoerce(t.DOMString)).match(type)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } if (!_isTypeFound(type)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR)); - } - throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } if (!(new TypeCoerce(t.SuccessCallback)).match(successCallback)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } - if (errorCallback && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) { - if (errorCallback) { - errorCallback(new WebAPIError(errorcode.TYPE_MISMATCH_ERR)); - } + + if (!(new TypeCoerce(t.ErrorCallback)).match(errorCallback) && (arguments.length !== 2)) { throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); } _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY); - successCallback(_systemSettings[type]); + setTimeout(function () { + successCallback(_systemSettings[type]); + }, 1); } function handleSubFeatures(subFeatures) { - for (var subFeature in subFeatures) { - if (_security[subFeature].length === 0) { - _security.all = true; - return; + var i, subFeature; + + for (subFeature in subFeatures) { + for (i in _security[subFeature]) { + _security[_security[subFeature][i]] = true; } - _security.all = false; - utils.forEach(_security[subFeature], function (method) { - _security[method] = true; - }); } } @@ -91147,8 +103017,8 @@ _self = { return new TZDate(); }, getLocalTimezone: function () { - var tz = db.retrieve("tizen-timezone") || "Coordinated Universal Time"; - return tz; + var localtz = db.retrieve("tizen-timezone") || "UTC"; + return localtz; }, getAvailableTimezones: function () { var ret = tz.getAllTimezone(); @@ -91197,78 +103067,180 @@ define('ripple/platform/tizen/2.0/timezone_info', function (require, exports, mo */ var _timezone_data = { - "Samoa": {diff: -11, abbr: "WST"}, - "Hawaii": {diff: -10, abbr: "HAST"}, - "Alaska": {diff: -9, abbr: "AKST"}, - "Baja California": {diff: -8, abbr: "PST"}, - "Arizona": {diff: -7, abbr: "MST"}, - "Chihuahua, La Paz, Mazatlan": {diff: -7, abbr: "MST"}, - "Guadalajara, Mexico City, Monterrey": {diff: -6, abbr: "CST"}, - "Bogota, Lima, Quito": {diff: -5, abbr: "PET"}, - "Asuncion": {diff: -4, abbr: "PYST"}, - "Cuiaba": {diff: -4, abbr: "AMST"}, - "Georgetown, La Paz, Manaus, San Juan": {diff: -4, abbr: "BOT"}, - "Santiago": {diff: -4, abbr: "CLST"}, - "Brasilia": {diff: -3, abbr: "BRST"}, - "Buenos Aires": {diff: -3, abbr: "ART"}, - "Cayenne, Fortaleza": {diff: -3, abbr: "GFT"}, - "Greenland": {diff: -3, abbr: "WGT"}, - "Montevideo": {diff: -3, abbr: "UYST"}, - "Azores": {diff: -1, abbr: "AZOT"}, - "Casablanca": {diff: 0, abbr: "UTC"}, - "Coordinated Universal Time": {diff: 0, abbr: "UTC"}, - "Dublin, Edinburgh, Lisbon, London": {diff: 0, abbr: "UTC"}, - "Monrovia, Reykjavik": {diff: 0, abbr: "UTC"}, - "Amsterdam, Berlin, Bern": {diff: 1, abbr: "CET"}, - "Rome, Stockholm, Vienna": {diff: 1, abbr: "CET"}, - "Belgrade, Bratislava, Budapest": {diff: 1, abbr: "CET"}, - "Ljubljana, Prague": {diff: 1, abbr: "CET"}, - "Brussels, Copenhagen, Madrid, Paris": {diff: 1, abbr: "CET"}, - "Sarajevo, Skopje, Warsaw, Zagreb": {diff: 1, abbr: "CET"}, - "Windhoek": {diff: 1, abbr: "WAST"}, - "Amman": {diff: 2, abbr: "EEST"}, - "Athens, Bucharest": {diff: 2, abbr: "EET"}, - "Beirut": {diff: 2, abbr: "EET"}, - "Cairo": {diff: 2, abbr: "EET"}, - "Damascus": {diff: 2, abbr: "EET"}, - "Harare, Pretoria": {diff: 2, abbr: "SAST"}, - "Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius": {diff: 2, abbr: "EET"}, - "Istanbul": {diff: 2, abbr: "EET"}, - "Jerusalem": {diff: 2, abbr: "IST"}, - "Baghdad": {diff: 3, abbr: "AST"}, - "Kuwait, Riyadh": {diff: 3, abbr: "AST"}, - "Nairobi": {diff: 3, abbr: "EAT"}, - "Abu Dhabi, Muscat": {diff: 4, abbr: "GST"}, - "Baku": {diff: 4, abbr: "AZT"}, - "Moscow, St. Petersburg, Volgograd": {diff: 4, abbr: "MSK"}, - "Tbilisi": {diff: 4, abbr: "GET"}, - "Yerevan": {diff: 4, abbr: "AMT"}, - "Islamabad, Karachi": {diff: 5, abbr: "PKT"}, - "Tashkent": {diff: 5, abbr: "UZT"}, - "Astana": {diff: 6, abbr: "ALMT"}, - "Dhaka": {diff: 6, abbr: "BST"}, - "Ekaterinburg": {diff: 6, abbr: "YEKT"}, - "Bangkok, Hanoi, Jakarta": {diff: 7, abbr: "ICT"}, - "Novosibirsk": {diff: 7, abbr: "NOVT"}, - "Beijing, Chongqing, Hong Kong, Urumqi": {diff: 8, abbr: "CST"}, - "Krasnoyarsk": {diff: 8, abbr: "KRAT"}, - "Kuala Lumpur, Singapore": {diff: 8, abbr: "SGT"}, - "Perth": {diff: 8, abbr: "WST"}, - "Taipei": {diff: 8, abbr: "CST"}, - "Ulaanbaatar": {diff: 8, abbr: "ULAT"}, - "Irkutsk": {diff: 9, abbr: "IRKT"}, - "Osaka, Sapporo, Tokyo": {diff: 9, abbr: "JST"}, - "Seoul": {diff: 9, abbr: "KST"}, - "Brisbane": {diff: 10, abbr: "EST"}, - "Canberra, Melbourne, Sydney": {diff: 10, abbr: "EST"}, - "Guam, Port Moresby": {diff: 10, abbr: ""}, - "Hobart": {diff: 10, abbr: "EDT"}, - "Yakutsk": {diff: 10, abbr: "YAKT"}, - "Solomon Is., New Caledonia": {diff: 11, abbr: "SBT"}, - "Vladivostok": {diff: 11, abbr: "VLAT"}, - "Auckland, Wellington": {diff: 12, abbr: "NZDT"}, - "Fiji": {diff: 12, abbr: "FJST"}, - "Magadan": {diff: 12, abbr: "MAGT"} + "UTC": {diff: 0, abbr: "UTC"}, + "Africa/Cairo": {diff: 2, abbr: "EET"}, + "Africa/Casablanca": {diff: 0, abbr: "UTC"}, + "Africa/Dakar": {diff: 0, abbr: "UTC"}, + "Africa/Freetown": {diff: 0, abbr: "UTC"}, + "Africa/Johannesburg": {diff: 2, abbr: "SAST"}, + "Africa/Luanda": {diff: 1, abbr: "WAT"}, + "America/Anchorage": {diff: -9, abbr: "AKDT"}, + "America/Antigua": {diff: -4, abbr: "AST"}, + "America/Aruba": {diff: -4, abbr: "AST"}, + "America/Barbados": {diff: -4, abbr: "AST"}, + "America/Belize": {diff: -6, abbr: "CST"}, + "America/Bogota": {diff: -5, abbr: "COT"}, + "America/Buenos_Aires": {diff: -3, abbr: "ART"}, + "America/Cancun": {diff: -6, abbr: "CDT"}, + "America/Cayenne": {diff: -3, abbr: "GFT"}, + "America/Cayman": {diff: -5, abbr: "EST"}, + "America/Chicago": {diff: -6, abbr: "CST"}, + "America/Chihuahua": {diff: -7, abbr: "MST"}, + "America/Costa_Rica": {diff: -6, abbr: "CST"}, + "America/Denver": {diff: -7, abbr: "MST"}, + "America/Detroit": {diff: -5, abbr: "EST"}, + "America/Dominica": {diff: -4, abbr: "AST"}, + "America/Edmonton": {diff: -7, abbr: "MST"}, + "America/El_Salvador": {diff: -6, abbr: "CST"}, + "America/Guatemala": {diff: -6, abbr: "CST"}, + "America/Havana": {diff: -5, abbr: "CST"}, + "America/Indianapolis": {diff: -5, abbr: "EST"}, + "America/Jamaica": {diff: -5, abbr: "EST"}, + "America/Lima": {diff: -5, abbr: "PET"}, + "America/Los_Angeles": {diff: -8, abbr: "PST"}, + "America/Louisville": {diff: -5, abbr: "EST"}, + "America/Mexico_City": {diff: -6, abbr: "CST"}, + "America/Montevideo": {diff: -2, abbr: "UYST"}, + "America/Montreal": {diff: -5, abbr: "EST"}, + "America/New_York": {diff: -5, abbr: "EST"}, + "America/Panama": {diff: -5, abbr: "EST"}, + "America/Phoenix": {diff: -7, abbr: "MST"}, + "America/Puerto_Rico": {diff: -4, abbr: "AST"}, + "America/Santiago": {diff: -3, abbr: "CLST"}, + "America/Santo_Domingo": {diff: -4, abbr: "AST"}, + "America/Sao_Paulo": {diff: -4, abbr: "AST"}, + "America/Tijuana": {diff: -8, abbr: "PST"}, + "America/Vancouver": {diff: -8, abbr: "PST"}, + "America/Winnipeg": {diff: -6, abbr: "CST"}, + "Antarctica/South_Pole": {diff: 13, abbr: "NZDT"}, + "Arctic/Longyearbyen": {diff: 13, abbr: "CET"}, + "Asia/Amman": {diff: 2, abbr: "EET"}, + "Asia/Baghdad": {diff: 3, abbr: "AST"}, + "Asia/Bahrain": {diff: 3, abbr: "AST"}, + "Asia/Bangkok": {diff: 7, abbr: "ICT"}, + "Asia/Beirut": {diff: 2, abbr: "EET"}, + "Asia/Chungking": {diff: 8, abbr: "CST"}, + "Asia/Dubai": {diff: 4, abbr: "GST"}, + "Asia/Harbin": {diff: 8, abbr: "CST"}, + "Asia/Ho_Chi_Minh": {diff: 7, abbr: "IST"}, + "Asia/Hong_Kong": {diff: 8, abbr: "HKT"}, + "Asia/Istanbul": {diff: 2, abbr: "EET"}, + "Asia/Jakarta": {diff: 7, abbr: "WIT"}, + "Asia/Jerusalem": {diff: 2, abbr: "IST"}, + "Asia/Karachi": {diff: 5, abbr: "PKT"}, + "Asia/Kuala_Lumpur": {diff: 8, abbr: "MYT"}, + "Asia/Kuwait": {diff: 3, abbr: "AST"}, + "Asia/Macao": {diff: 8, abbr: "CST"}, + "Asia/Manila": {diff: 8, abbr: "PHT"}, + "Asia/Pyongyang": {diff: 9, abbr: "KST"}, + "Asia/Qatar": {diff: 3, abbr: "AST"}, + "Asia/Saigon": {diff: 7, abbr: "ICT"}, + "Asia/Seoul": {diff: 9, abbr: "KST"}, + "Asia/Shanghai": {diff: 8, abbr: "CST"}, + "Asia/Singapore": {diff: 8, abbr: "SGT"}, + "Asia/Taipei": {diff: 8, abbr: "CST"}, + "Asia/Tel_Aviv": {diff: 2, abbr: "IST"}, + "Asia/Tokyo": {diff: 9, abbr: "JST"}, + "Asia/Urumqi": {diff: 8, abbr: "CST"}, + "Atlantic/Bermuda": {diff: -4, abbr: "AST"}, + "Atlantic/Canary": {diff: 0, abbr: "WET"}, + "Atlantic/Cape_Verde": {diff: -1, abbr: "CVT"}, + "Atlantic/Reykjavik": {diff: 0, abbr: "GMT"}, + "Australia/Brisbane": {diff: 10, abbr: "EST"}, + "Australia/Canberra": {diff: 11, abbr: "EST"}, + "Australia/Darwin": {diff: 9.5, abbr: "CST"}, + "Australia/Melbourne": {diff: 11, abbr: "EST"}, + "Australia/North": {diff: 9.5, abbr: "CST"}, + "Australia/Perth": {diff: 8, abbr: "WST"}, + "Australia/Queensland": {diff: 10, abbr: "EST"}, + "Australia/South": {diff: 10.5, abbr: "CST"}, + "Australia/Sydney": {diff: 11, abbr: "EST"}, + "Australia/West": {diff: 8, abbr: "WST"}, + "Australia/Victoria": {diff: 11, abbr: "EST"}, + "Europe/Amsterdam": {diff: 1, abbr: "CET"}, + "Europe/Athens": {diff: 2, abbr: "EET"}, + "Europe/Belgrade": {diff: 1, abbr: "CET"}, + "Europe/Berlin": {diff: 1, abbr: "CET"}, + "Europe/Brussels": {diff: 1, abbr: "CET"}, + "Europe/Bucharest": {diff: 2, abbr: "EET"}, + "Europe/Budapest": {diff: 1, abbr: "CET"}, + "Europe/Copenhagen": {diff: 1, abbr: "CET"}, + "Europe/Dublin": {diff: 0, abbr: "GMT"}, + "Europe/Helsinki": {diff: 2, abbr: "EET"}, + "Europe/Istanbul": {diff: 2, abbr: "EET"}, + "Europe/Kaliningrad": {diff: 3, abbr: "FET"}, + "Europe/Kiev": {diff: 2, abbr: "EET"}, + "Europe/Lisbon": {diff: 0, abbr: "WET"}, + "Europe/London": {diff: 0, abbr: "GMT"}, + "Europe/Luxembourg": {diff: 1, abbr: "CET"}, + "Europe/Madrid": {diff: 1, abbr: "CET"}, + "Europe/Minsk": {diff: 3, abbr: "FET"}, + "Europe/Monaco": {diff: 1, abbr: "CET"}, + "Europe/Moscow": {diff: 4, abbr: "MSK"}, + "Europe/Oslo": {diff: 1, abbr: "CET"}, + "Europe/Paris": {diff: 1, abbr: "CET"}, + "Europe/Prague": {diff: 1, abbr: "CET"}, + "Europe/Rome": {diff: 1, abbr: "CET"}, + "Europe/San_Marino": {diff: 1, abbr: "CET"}, + "Europe/Sarajevo": {diff: 1, abbr: "CET"}, + "Europe/Stockholm": {diff: 1, abbr: "CET"}, + "Europe/Vatican": {diff: 1, abbr: "CET"}, + "Europe/Vienna": {diff: 1, abbr: "CET"}, + "Europe/Warsaw": {diff: 1, abbr: "CET"}, + "Europe/Zurich": {diff: 2, abbr: "EET"}, + "Indian/Christmas": {diff: 7, abbr: "CXT"}, + "Indian/Maldives": {diff: 5, abbr: "MVT"}, + "Pacific/Auckland": {diff: 12, abbr: "NZST"}, + "Pacific/Easter": {diff: -6, abbr: "EAST"}, + "Pacific/Fiji": {diff: 12, abbr: "FJT"}, + "Pacific/Guam": {diff: 10, abbr: "ChST"}, + "Pacific/Honolulu": {diff: -10, abbr: "HST"}, + "Pacific/Midway": {diff: -11, abbr: "SST"}, + "Pacific/Saipan": {diff: 10, abbr: "ChST"}, + "Pacific/Samoa": {diff: -11, abbr: "SST"}, + "Pacific/Tahiti": {diff: -10, abbr: "TAHT"}, + "UCT": {diff: 0, abbr: "UCT"}, + "SST": {diff: 0, abbr: "SST"}, + "GMT": {diff: 0, abbr: "GMT"}, + "Greenwich": {diff: 0, abbr: "GMT"}, + "US/Alaska": {diff: -9, abbr: "AKST"}, + "US/Eastern": {diff: -5, abbr: "EST"}, + "US/Central": {diff: -6, abbr: "CST"}, + "US/Mountain": {diff: -7, abbr: "MST"}, + "US/Pacific": {diff: -8, abbr: "PST"}, + "Universal": {diff: 0, abbr: "UTC"}, + "Zulu": {diff: 0, abbr: "UTC"}, + "Etc/GMT": {diff: 0, abbr: "Etc/GMT"}, + "Etc/GMT+0": {diff: 0, abbr: "Etc/GMT+0"}, + "Etc/GMT+1": {diff: -1, abbr: "Etc/GMT+1"}, + "Etc/GMT+10": {diff: -10, abbr: "Etc/GMT+10"}, + "Etc/GMT+11": {diff: -11, abbr: "Etc/GMT+11"}, + "Etc/GMT+12": {diff: -12, abbr: "Etc/GMT+12"}, + "Etc/GMT+2": {diff: -2, abbr: "Etc/GMT+2"}, + "Etc/GMT+3": {diff: -3, abbr: "Etc/GMT+3"}, + "Etc/GMT+4": {diff: -4, abbr: "Etc/GMT+4"}, + "Etc/GMT+5": {diff: -5, abbr: "Etc/GMT+5"}, + "Etc/GMT+6": {diff: -6, abbr: "Etc/GMT+6"}, + "Etc/GMT+7": {diff: -7, abbr: "Etc/GMT+7"}, + "Etc/GMT+8": {diff: -8, abbr: "Etc/GMT+8"}, + "Etc/GMT+9": {diff: -9, abbr: "Etc/GMT+9"}, + "Etc/GMT-0": {diff: 0, abbr: "Etc/GMT-0"}, + "Etc/GMT-1": {diff: 1, abbr: "Etc/GMT-1"}, + "Etc/GMT-10": {diff: 10, abbr: "Etc/GMT-10"}, + "Etc/GMT-11": {diff: 11, abbr: "Etc/GMT-11"}, + "Etc/GMT-12": {diff: 12, abbr: "Etc/GMT-12"}, + "Etc/GMT-13": {diff: 13, abbr: "Etc/GMT-13"}, + "Etc/GMT-14": {diff: 14, abbr: "Etc/GMT-14"}, + "Etc/GMT-2": {diff: 2, abbr: "Etc/GMT-2"}, + "Etc/GMT-3": {diff: 3, abbr: "Etc/GMT-3"}, + "Etc/GMT-4": {diff: 4, abbr: "Etc/GMT-4"}, + "Etc/GMT-5": {diff: 5, abbr: "Etc/GMT-5"}, + "Etc/GMT-6": {diff: 6, abbr: "Etc/GMT-6"}, + "Etc/GMT-7": {diff: 7, abbr: "Etc/GMT-7"}, + "Etc/GMT-8": {diff: 8, abbr: "Etc/GMT-8"}, + "Etc/GMT-9": {diff: 9, abbr: "Etc/GMT-9"}, + "Etc/GMT0": {diff: 0, abbr: "Etc/GMT0"}, + "Etc/Greenwich": {diff: 0, abbr: "GMT"} }; module.exports = { @@ -92139,6 +104111,142 @@ _initialize(); module.exports = _self; }); +define('ripple/platform/tizen/2.0/typecast', function (require, exports, module) { +/* + * Copyright 2013 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var typedef = require('ripple/platform/tizen/2.0/typedef'), + errorcode = require('ripple/platform/tizen/2.0/errorcode'), + WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'), + TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'), + _self; + +function cast(pattern) { + /* + * Type cast for each known type. The function name is the exact name of the + * corresponding type. + * + * obj + * Variable to be casted + * + * aux + * Auxiliary descriptor of obj. It can be any one or combination of below + * strings, or ignored in most cases. + * + * "?" Nullable types + * "[]" Arrays + * + * arbitrary + * A boolean parameter, which indicates that whether obj requires to be + * verified. It can be ignored in most cases. + * + * true Indicates obj may contain invalid values + * false Indicates obj must be verified constrainedly + * + * Return + * Casted object. + */ + + return function (obj, aux, arbitrary) { + var tc, isNullable; + + aux = aux ? String(aux) : ""; + tc = new TypeCoerce((aux.indexOf("[]") !== -1) ? [pattern] : pattern); + isNullable = (aux.indexOf("?") !== -1); + + if ((isNullable && obj) || !isNullable) { + if ((obj = tc.cast(obj)) === null) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + } + + if (!arbitrary) { + if (((isNullable && obj) || !isNullable) && !tc.validate(obj)) { + throw new WebAPIException(errorcode.INVALID_VALUES_ERR); + } + } + + return obj; + }; +} + +function castArgs(pattern) { + /* + * Type cast for each known method of interface. The function name is the + * exact name of the corresponding interface. + * + * method + * String of method name + * + * argv + * arguments. The keyword 'arguments' will be always passed in. + */ + + return function (method, argv) { + var argvType, argvTypeLength, argc, i, tc, isNullable; + + argvType = pattern[method]; + + if (argvType === null) + return; + + argvTypeLength = argv.callee.length; + argc = (argv.length < argvTypeLength) ? argv.length : argvTypeLength; + + for (i = 0; i < argvTypeLength; ++i) { + isNullable = !!(argvType._optional && argvType._optional[i]); + + if (i > argc - 1) { + if (!isNullable) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + argv[i] = null; + continue; + } + + tc = new TypeCoerce(argvType[i]); + + if ((argv[i] === null) || (argv[i] === undefined)) { + if (!isNullable || (argv[i] !== null)) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + } else if ((argv[i] = tc.cast(argv[i])) === null) { + throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR); + } + } + }; +} + +_self = (function () { + var typecast = {}, i; + + for (i in typedef) { + typecast[i] = cast(typedef[i]); + } + + for (i in typedef.interface) { + typecast[i] = castArgs(typedef.interface[i]); + } + + return typecast; +}()); + +module.exports = _self; + +}); define('ripple/platform/tizen/2.0/typecoerce', function (require, exports, module) { /* * Copyright 2013 Intel Corporation. @@ -92156,20 +104264,41 @@ define('ripple/platform/tizen/2.0/typecoerce', function (require, exports, modul * limitations under the License. */ -var utils = require('ripple/utils'), - t = require('ripple/platform/tizen/2.0/typedef'), +var t = require('ripple/platform/tizen/2.0/typedef'), _self; _self = function (pattern) { var typeCoerce, typeOfPattern; // private + function getExtendedType(val) { + var type; + + switch (val) { + case "any": // Any type + type = "any"; + break; + + case "double": + case "float": + type = "float"; + break; + + default: // Derivative type name: e.g., "AbstractFilter" + type = ""; + break; + } + + return type; + } + function getType(val, isPattern) { var type = Object.prototype.toString.call(val); switch (type) { case "[object Array]": - type = (isPattern && (val.length > 1) && (typeof val[0] === "string")) ? "enum" : "Array"; + type = (isPattern && (val.length > 1) && + (typeof val[0] === "string")) ? "enum" : "Array"; break; case "[object Boolean]": @@ -92181,11 +104310,11 @@ _self = function (pattern) { break; case "[object Function]": - type = "function"; + type = "Function"; break; case "[object Number]": - type = "number"; + type = "Number"; break; case "[object Object]": @@ -92193,84 +104322,174 @@ _self = function (pattern) { break; case "[object String]": - if (!isPattern) { - type = "DOMString"; - break; - } + type = (isPattern && !!val) ? getExtendedType(val) : "DOMString"; + break; + } - switch (val) { - case "": // Empty string: generic string type - type = "DOMString"; - break; + return type; + } + + function isInstance(base, derived, obj) { + var attr; - case "any": // Any type - type = "any"; + for (attr in derived) { + switch (attr) { + case "_optional": + case "_derived": break; - default: // Non-empty string: type name, e.g., "AbstractFilter" - type = "Type"; + default: + if ((!derived._optional || !derived._optional[attr]) && + !(attr in obj)) { + return false; + } break; } - break; } - return type; + for (attr in obj) { + if (!(attr in base) && !(attr in derived)) { + return false; + } + } + + return true; } // public function cast(obj) { - var validObj, - validValue, - elementType, + var typeMap, typeOfObj = getType(obj, false); - switch (typeOfPattern) { - case "DOMString": - validObj = (typeOfObj !== typeOfPattern) ? String(obj) : obj; - break; + typeMap = { + "Array": function () { + var arr = [], elementType, i; - case "number": - validObj = (typeOfObj !== typeOfPattern) ? Number(obj) : obj; - break; + if (typeOfObj !== typeOfPattern) { + return null; + } - case "Object": - if (typeOfObj !== typeOfPattern) { - validObj = {}; - } else { - validObj = obj; - utils.forEach(validObj, function (value, key) { - if (pattern[key] === undefined) { - delete validObj[key]; - } else { - validValue = _self(pattern[key]).cast(value); - if (validObj[key] !== validValue) - validObj[key] = validValue; + elementType = _self(pattern[0]); + for (i in obj) { + arr[i] = elementType.cast(obj[i]); + if (arr[i] === null) + return null; + } + + return arr; + }, + + "DOMString": function () { + switch (typeOfObj) { + case "Date": + case "DOMString": + case "Number": + obj = String(obj).trim(); + break; + + default: + obj = null; + break; + } + + return obj; + }, + + "Date": function () { + return (typeOfObj === typeOfPattern) ? obj : null; + }, + + "Function": function () { + return (typeOfObj === typeOfPattern) ? obj : null; + }, + + "Number": function () { + var n = parseInt(obj, 10); + + if (isNaN(n)) + return null; + + return (obj === n) ? n : parseFloat(obj); + }, + + "Object": function () { + var ret = {}, attr, i, isMatched = false; + + if (typeOfObj !== typeOfPattern) { + return null; + } + + for (attr in pattern) { + switch (attr) { + case "_optional": + break; + + case "_derived": + for (i in pattern._derived) { + if (isInstance(pattern, pattern._derived[i], obj)) { + isMatched = true; + break; + } + } + ret = _self(pattern._derived[isMatched ? i : 0]) + .cast(obj); + break; + + default: + if (!pattern._optional || !pattern._optional[attr] || + (obj[attr] !== undefined) && (obj[attr] !== null)) { + ret[attr] = _self(pattern[attr]).cast(obj[attr]); + if (ret[attr] === null) { + return null; + } + } + break; } - }); - } - break; + } - case "Array": - if (typeOfObj !== typeOfPattern) { - validObj = []; - } else { - validObj = obj; - elementType = _self(pattern[0]); - utils.forEach(validObj, function (element, index) { - validObj[index] = elementType.cast(element); - }); + return ret; + }, + + "any": function () { + return obj; + }, + + "boolean": function () { + return (typeOfObj === typeOfPattern) ? obj : null; + }, + + "enum": function () { + var i; + + obj = String(obj).trim(); + for (i in pattern) { + if (obj === pattern[i]) { + return obj; + } + } + + return null; + }, + + "float": function () { + var f = parseFloat(obj, 10); + + return (isNaN(f) ? null : f); + }, + + "": function () { + return _self(t[pattern]).cast(obj); } - break; - } + }; - return validObj; + return typeMap[typeOfPattern](); } function match(obj) { - var matchTab, + var typeMap, typeOfObj = getType(obj, false); - matchTab = { + typeMap = { "Array": function () { var elementType, i; @@ -92295,8 +104514,16 @@ _self = function (pattern) { return (typeOfObj === typeOfPattern); }, + "Function": function () { + return (typeOfObj === typeOfPattern); + }, + + "Number": function () { + return (typeOfObj === typeOfPattern); + }, + "Object": function () { - var attr, isMatched = false, i; + var attr, i, isMatched = false; if (typeOfObj !== typeOfPattern) return false; @@ -92319,10 +104546,11 @@ _self = function (pattern) { default: if (pattern._optional && pattern._optional[attr]) { isMatched = ((obj[attr] === null) || - (obj[attr] === undefined) || - _self(pattern[attr]).match(obj[attr])); + (obj[attr] === undefined) || + _self(pattern[attr]).match(obj[attr])); } else { - isMatched = (obj[attr] !== undefined) && _self(pattern[attr]).match(obj[attr]); + isMatched = (obj[attr] !== undefined) && + _self(pattern[attr]).match(obj[attr]); } break; } @@ -92344,10 +104572,6 @@ _self = function (pattern) { return isMatched; }, - "Type": function () { - return _self(t[pattern]).match(obj); - }, - "any": function () { return true; }, @@ -92366,23 +104590,113 @@ _self = function (pattern) { return false; }, - "function": function () { - return (typeOfObj === typeOfPattern); + "float": function () { + return (typeOfObj === "Number"); }, - "number": function () { - return (typeOfObj === typeOfPattern); + "": function () { + return _self(t[pattern]).match(obj); } }; - return matchTab[typeOfPattern](); + return typeMap[typeOfPattern](); + } + + function validate(obj) { + var typeMap, + typeOfObj = getType(obj, false); + + typeMap = { + "Array": function () { + var elementType, i; + + if (typeOfObj !== typeOfPattern) + return false; + + elementType = _self(pattern[0]); + for (i in obj) { + if (!elementType.validate(obj[i])) { + return false; + } + } + + return true; + }, + + "DOMString": function () { + return (obj !== ""); + }, + + "Number": function () { + return (obj !== 0); + }, + + "Object": function () { + var attr, i, isValid = false, isMatched = false; + + if (typeOfObj !== typeOfPattern) + return false; + + for (attr in pattern) { + switch (attr) { + case "_optional": + break; + + case "_derived": + for (i in pattern._derived) { + if (isInstance(pattern, pattern._derived[i], obj)) { + isMatched = true; + break; + } + } + isValid = _self(pattern._derived[isMatched ? i : 0]) + .validate(obj); + break; + + default: + if (pattern._optional && pattern._optional[attr]) { + isValid = true; + } else { + isValid = _self(pattern[attr]).validate(obj[attr]); + } + break; + } + + if (!isValid) + break; + } + + return isValid; + }, + + "enum": function () { + for (var i in pattern) { + if (obj === pattern[i]) { + return true; + } + } + + return false; + }, + + "float": function () { + return (obj !== 0); + }, + + "": function () { + return _self(t[pattern]).validate(obj); + } + }; + + return !typeMap[typeOfPattern] || typeMap[typeOfPattern](); } typeOfPattern = getType(pattern, true); typeCoerce = { - cast: cast, - match: match + cast: cast, + match: match, + validate: validate }; return typeCoerce; @@ -92408,19 +104722,21 @@ define('ripple/platform/tizen/2.0/typedef', function (require, exports, module) * limitations under the License. */ +var _t, _i; + /* * Primitive type definition */ -var _t = { +_t = { // Basic DOMString: "", Date: new Date(), Function: function () {}, any: "any", boolean: false, - double: 0.0, - float: 0.0, + double: "double", + float: "float", long: 0, "unsigned long": 0, "unsigned long long": 0, @@ -92446,6 +104762,16 @@ var _t = { "FLIP_VERTICAL", "TRANSPOSE", "ROTATE_90", "TRANSVERSE", "ROTATE_270"], + // Data Control + DataType: ["MAP", "SQL"], + + // Data Sync + SyncMode: ["MANUAL", "PERIODIC", "PUSH"], + SyncType: ["TWO_WAY", "SLOW", "ONE_WAY_FROM_CLIENT", "REFRESH_FROM_CLIENT", "ONE_WAY_FROM_SERVER", "REFRESH_FROM_SERVER"], + SyncInterval: ["5_MINUTES", "15_MINUTES", "1_HOUR", "4_HOURS", "12_HOURS", "1_DAY", "1_WEEK", "1_MONTH"], + SyncServiceType: ["CONTACT", "EVENT"], + SyncStatus: ["SUCCESS", "FAIL", "STOP", "NONE"], + // Messaging MessageServiceTag: ["messaging.sms", "messaging.mms", "messaging.email"], @@ -92472,8 +104798,15 @@ var _t = { * initialized as an empty array, i.e., undefined-initialized array. * * _derived - * Subtype list, which consists of derived subtypes. It only exists in the - * definition of base type. + * Derived types, which used in two cases of definition, + * + * Subtype list + * An array consists of derived subtypes. It exists in the definition of + * a base type. + * + * Union types + * An array consists of member types. It exists in the definition of + * a union type. */ /* @@ -92695,7 +105028,7 @@ _t.ContactWebSite = { }; _t.ContactAnniversary = { - date: _t.DOMString, + date: _t.Date, label: _t.DOMString, _optional: { @@ -92765,7 +105098,7 @@ _t.Contact = { organizations: [_t.ContactOrganization], notes: [_t.DOMString], urls: [_t.ContactWebSite], - ringtoneURI: [_t.DOMString], + ringtoneURI: _t.DOMString, groupIds: [_t.ContactGroupId], convertToString: _t.Function, clone: _t.Function, @@ -92779,13 +105112,7 @@ _t.Contact = { name: true, photoURI: true, birthday: true, - ringtoneURI: true, - // undefined - phoneNumbers: true, - emails: true, - anniversaries: true, - organizations: true, - notes: true + ringtoneURI: true } }; @@ -92795,7 +105122,7 @@ _t.ContactGroup = { name: _t.DOMString, ringtoneURI: _t.DOMString, photoURI: _t.DOMString, - readOnly: _t.DOMString, + readOnly: _t.boolean, _optional: { // nullable @@ -92879,7 +105206,6 @@ _t.AudioContent = { composers: true, lyrics: true, copyright: true, - bitrate: true, trackNumber: true } }; @@ -92892,8 +105218,7 @@ _t.ImageContent = { _optional: { // nullable - geolocation: true, - orientation: true + geolocation: true } }; @@ -92905,7 +105230,7 @@ _t.Content = { mimeType: _t.DOMString, title: _t.DOMString, contentURI: _t.DOMString, - thumbnailURLs: [_t.DOMString], + thumbnailURIs: [_t.DOMString], releaseDate: _t.Date, modifiedDate: _t.Date, size: _t["unsigned long"], @@ -92914,18 +105239,67 @@ _t.Content = { _optional: { // nullable - thumbnailURLs: true, + thumbnailURIs: true, releaseDate: true, modifiedDate: true, - size: true, - description: true, - rating: true + description: true }, _derived: [_t.VideoContent, _t.AudioContent, _t.ImageContent] }; /* + * Data Control + */ + +_t.DataControlSuccessCallback = _t.Function; +_t.DataControlErrorCallback = _t.Function; +_t.DataControlInsertSuccessCallback = _t.Function; +_t.DataControlSelectSuccessCallback = _t.Function; +_t.DataControlGetValueSuccessCallback = _t.Function; + +_t.RowData = { + columns: [_t.DOMString], + values: [_t.DOMString] +}; + +/* + * Data Sync + */ + +_t.SyncProfileId = _t.DOMString; + +_t.SyncInfo = { + url: _t.DOMString, + mode: _t.SyncMode, + type: _t.SyncType, + interval: _t.SyncInterval, + + _optional: { + // nullable + type: true, + interval: true + } +}; + +_t.SyncServiceInfo = { + enable: _t.boolean, + serviceType: _t.SyncServiceType, + serverDatabaseUri: _t.DOMString +}; + +_t.SyncProfileInfo = { + profileName: _t.DOMString, + syncInfo: _t.SyncInfo, + serviceInfo: [_t.SyncServiceInfo], + + _optional: { + // nullable + serviceInfo: true + } +}; + +/* * Messaging */ @@ -92941,6 +105315,23 @@ _t.MessageArraySuccessCallback = _t.Function; _t.MessageConversationArraySuccessCallback = _t.Function; _t.MessageFolderArraySuccessCallback = _t.Function; +_t.MessageFolder = { + id: _t.MessageFolderId, + parentId: _t.MessageFolderId, + serviceId: _t.DOMString, + contentType: _t.MessageServiceTag, + name: _t.DOMString, + path: _t.DOMString, + type: _t.DOMString, + synchronizable: _t.boolean, + + _optional: { + // nullable + parentId: true + } + +}; + _t.MessagesChangeCallback = { messagesadded: _t.Function, messagesupdated: _t.Function, @@ -92983,15 +105374,406 @@ _t.PushNotificationCallback = _t.Function; _t.PackageId = _t.DOMString; _t.PackageProgressCallback = { onprogress: _t.Function, - oncomplete: _t.Function + oncomplete: _t.Function, + + _optional: { + onprogress: true, + oncomplete: true + } }; _t.PackageInformationArraySuccessCallback = _t.Function; _t.PackageInfomationEventCallback = { - oninstalled: _t.Function, - onupdated: _t.Function, - onuninstalled: _t.Function + oninstalled: _t.Function, + onupdated: _t.Function, + onuninstalled: _t.Function, + + _optional: { + oninstalled: true, + onupdated: true, + onuninstalled: true + } +}; + +/* + * Interface prototype definition + */ + +_i = { + // Contact + ContactManager: {}, + AddressBook: {}, + Person: {}, + + // Content + ContentManager: {}, + + // Data Control + DataControlManager: {}, + SQLDataControlConsumer: {}, + MappedDataControlConsumer: {} +}; + +/* + * Contact + */ + +// ContactManager +_i.ContactManager.getAddressBooks = { + 0: _t.AddressBookArraySuccessCallback, + 1: _t.ErrorCallback, + + _optional: { + 1: true + } +}; + +_i.ContactManager.getUnifiedAddressBook = null; +_i.ContactManager.getDefaultAddressBook = null; + +_i.ContactManager.getAddressBook = { + 0: _t.AddressBookId +}; + +_i.ContactManager.get = { + 0: _t.PersonId +}; + +_i.ContactManager.update = { + 0: _t.Person +}; + +_i.ContactManager.updateBatch = { + 0: [_t.Person], + 1: _t.SuccessCallback, + 2: _t.ErrorCallback, + + _optional: { + 1: true, + 2: true + } +}; + +_i.ContactManager.remove = { + 0: _t.PersonId +}; + +_i.ContactManager.removeBatch = { + 0: [_t.PersonId], + 1: _t.SuccessCallback, + 2: _t.ErrorCallback, + + _optional: { + 1: true, + 2: true + } +}; + +_i.ContactManager.find = { + 0: _t.PersonArraySuccessCallback, + 1: _t.ErrorCallback, + 2: _t.AbstractFilter, + 3: _t.SortMode, + + _optional: { + 1: true, + 2: true, + 3: true + } +}; + +_i.ContactManager.addChangeListener = { + 0: _t.PersonsChangeCallback +}; + +_i.ContactManager.removeChangeListener = { + 0: _t.long +}; + +// AddressBook +_i.AddressBook.get = { + 0: _t.ContactId +}; + +_i.AddressBook.add = { + 0: _t.Contact +}; + +_i.AddressBook.addBatch = { + 0: [_t.Contact], + 1: _t.ContactArraySuccessCallback, + 2: _t.ErrorCallback, + + _optional: { + 1: true, + 2: true + } +}; + +_i.AddressBook.update = { + 0: _t.Contact +}; + +_i.AddressBook.updateBatch = { + 0: [_t.Contact], + 1: _t.SuccessCallback, + 2: _t.ErrorCallback, + + _optional: { + 1: true, + 2: true + } +}; + +_i.AddressBook.remove = { + 0: _t.ContactId +}; + +_i.AddressBook.removeBatch = { + 0: [_t.ContactId], + 1: _t.SuccessCallback, + 2: _t.ErrorCallback, + + _optional: { + 1: true, + 2: true + } +}; + +_i.AddressBook.find = { + 0: _t.ContactArraySuccessCallback, + 1: _t.ErrorCallback, + 2: _t.AbstractFilter, + 3: _t.SortMode, + + _optional:{ + 1: true, + 2: true, + 3: true + } +}; + +_i.AddressBook.addChangeListener = { + 0: _t.AddressBookChangeCallback, + 1: _t.ErrorCallback, + + _optional: { + 1: true + } +}; + +_i.AddressBook.removeChangeListener = { + 0: _t.long +}; + +_i.AddressBook.getGroup = { + 0: _t.ContactGroupId +}; + +_i.AddressBook.addGroup = { + 0: _t.ContactGroup +}; + +_i.AddressBook.updateGroup = { + 0: _t.ContactGroup +}; + +_i.AddressBook.removeGroup = { + 0: _t.ContactGroupId +}; + +_i.AddressBook.getGroups = null; + +// Person +_i.Person.link = { + 0: _t.PersonId +}; + +_i.Person.unlink = { + 0: _t.ContactId +}; + +/* + * Content + */ + +// ContentManager +_i.ContentManager.update = { + 0: _t.Content +}; + +_i.ContentManager.updateBatch = { + 0: [_t.Content], + 1: _t.SuccessCallback, + 2: _t.ErrorCallback, + + _optional: { + 1: true, + 2: true + } +}; + +_i.ContentManager.getDirectories = { + 0: _t.ContentDirectoryArraySuccessCallback, + 1: _t.ErrorCallback, + + _optional: { + 1: true + } +}; + +_i.ContentManager.find = { + 0: _t.ContentArraySuccessCallback, + 1: _t.ErrorCallback, + 2: _t.ContentDirectoryId, + 3: _t.AbstractFilter, + 4: _t.SortMode, + 5: _t["unsigned long"], + 6: _t["unsigned long"], + + _optional: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true, + 6: true + } +}; + +_i.ContentManager.scanFile = { + 0: _t.DOMString, + 1: _t.ContentScanSuccessCallback, + 2: _t.ErrorCallback, + + _optional: { + 1: true, + 2: true + } +}; + +_i.ContentManager.setChangeListener = { + 0: _t.ContentChangeCallback +}; + +_i.ContentManager.unsetChangeListener = null; + +/* + * Data Control + */ + +// DataControlManager +_i.DataControlManager.getDataControlConsumer = { + 0: _t.DOMString, + 1: _t.DOMString, + 2: _t.DataType +}; + +// SQLDataControlConsumer +_i.SQLDataControlConsumer.insert = { + 0: _t["unsigned long"], + 1: _t.RowData, + 2: _t.DataControlInsertSuccessCallback, + 3: _t.DataControlErrorCallback, + + _optional: { + 2: true, + 3: true + } +}; + +_i.SQLDataControlConsumer.update = { + 0: _t["unsigned long"], + 1: _t.RowData, + 2: _t.DOMString, + 3: _t.DataControlSuccessCallback, + 4: _t.DataControlErrorCallback, + + _optional: { + 3: true, + 4: true + } +}; + +_i.SQLDataControlConsumer.remove = { + 0: _t["unsigned long"], + 1: _t.DOMString, + 2: _t.DataControlSuccessCallback, + 3: _t.DataControlErrorCallback, + + _optional: { + 2: true, + 3: true + } }; +_i.SQLDataControlConsumer.select = { + 0: _t["unsigned long"], + 1: [_t.DOMString], + 2: _t.DOMString, + 3: _t.DataControlSelectSuccessCallback, + 4: _t.DataControlErrorCallback, + 5: _t["unsigned long"], + 6: _t["unsigned long"], + + _optional: { + 4: true, + 5: true, + 6: true + } +}; + +// MappedDataControlConsumer +_i.MappedDataControlConsumer.addValue = { + 0: _t["unsigned long"], + 1: _t.DOMString, + 2: _t.DOMString, + 3: _t.DataControlSuccessCallback, + 4: _t.DataControlErrorCallback, + + _optional: { + 3: true, + 4: true + } +}; + +_i.MappedDataControlConsumer.removeValue = { + 0: _t["unsigned long"], + 1: _t.DOMString, + 2: _t.DOMString, + 3: _t.DataControlSuccessCallback, + 4: _t.DataControlErrorCallback, + + _optional: { + 4: true + } +}; + +_i.MappedDataControlConsumer.getValue = { + 0: _t["unsigned long"], + 1: _t.DOMString, + 2: _t.DataControlGetValueSuccessCallback, + 3: _t.DataControlErrorCallback, + + _optional: { + 3: true + } +}; + +_i.MappedDataControlConsumer.updateValue = { + 0: _t["unsigned long"], + 1: _t.DOMString, + 2: _t.DOMString, + 3: _t.DOMString, + 4: _t.DataControlSuccessCallback, + 5: _t.DataControlErrorCallback, + + _optional: { + 5: true + } +}; + +_t.interface = _i; + module.exports = _t; }); @@ -93038,7 +105820,7 @@ var vibrator = (function () { function _clearTimeout() { if (vibrateTimeout) { clearInterval(vibrateTimeout); - vibrateTimeout = null; + vibrateTimeout = null; } } @@ -93047,12 +105829,12 @@ var vibrator = (function () { _clearTimeout(); node.css({left: 0, top: 0}, MILLILSECONDS_OF_ONE_VIBRATION); } - + function vibrate() { node.css(movement[movementIndex]); movementIndex = (movementIndex + 1) % 8; } - + function changePulse() { if (emulatorBridge.document().hidden) { return; @@ -93062,7 +105844,7 @@ var vibrator = (function () { runTime = runTime + MILLILSECONDS_OF_ONE_VIBRATION; if (curPost >= vibratorPattern.length) { setTimeout(stopVibrate, 1); - } + } if (runTime > vibratorPattern[curPost]) { curPost = curPost + 1; runTime = 0; @@ -93071,22 +105853,22 @@ var vibrator = (function () { vibrate(); } } - } - + } + function startVibrate(_pattern) { - if (!isVibratorOn()) + if (!isVibratorOn()) return; - vibratorPattern = _pattern; + vibratorPattern = _pattern; _clearTimeout(); - movementIndex = 0; + movementIndex = 0; if (_pattern) { runTime = 0; vibrateTimeout = setInterval(changePulse, MILLILSECONDS_OF_ONE_VIBRATION); - } + } isVibrating = true; } - + return { isVibrating: isVibrating, startVibrate: startVibrate, @@ -93097,7 +105879,7 @@ var vibrator = (function () { _self = { vibrate: function () { var pattern = arguments[0], - i; + i; // If vibrator is off, stop the vibration event.on("VibratingModeChanged", function (value) { @@ -93105,13 +105887,13 @@ _self = { vibrator.stopVibrate(); } }); - + //1. If the hidden attribute [PAGE-VISIBILITY] is set to true, abort these steps. if (emulatorBridge.document().hidden) { return; } - //2. Let pattern be the value of the first argument. + //2. Let pattern be the value of the first argument. if (!tizen1_utils.isValidArray(pattern)) { pattern |= 0; } else { @@ -93120,27 +105902,27 @@ _self = { } } - //3. If pattern is 0, or an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm, if any, and abort these steps. + //3. If pattern is 0, or an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm, if any, and abort these steps. if (pattern === 0 || (tizen1_utils.isValidArray(pattern) && pattern.length === 0)) { vibrator.stopVibrate(); return; } - + //4. If pattern is a list, proceed to the next step. Otherwise run the following substeps: //a. Let list be an initially empty list, and add pattern to list. - //b. Let pattern be list. + //b. Let pattern be list. if (!tizen1_utils.isValidArray(pattern)) { pattern = [pattern]; } //5. If any entry of pattern exceeds an implementation-dependent limit, then the user agent may throw a NotSupportedError exception and abort these steps. - - //6. If the length of pattern is even, then remove the last entry in pattern. + + //6. If the length of pattern is even, then remove the last entry in pattern. if (pattern.length % 2 === 0) { pattern.pop(); } - - //7. Cancel the pre-existing instance of the processing vibration patterns algorithm, if any. + + //7. Cancel the pre-existing instance of the processing vibration patterns algorithm, if any. if (vibrator.isVibrating) { vibrator.stopVibrate(); } @@ -93148,7 +105930,7 @@ _self = { curPost = 0; vibrator.startVibrate(pattern); } -}; +}; module.exports = _self; @@ -114550,7 +127332,7 @@ var db = require('ripple/db'), devices = require('ripple/devices'), constants = require('ripple/constants'), event = require('ripple/event'), - _win, + _win, _doc, _self; @@ -114558,6 +127340,10 @@ function _validateLayoutType(layoutType) { return (layoutType === "landscape" || layoutType === "portrait"); } +function _validateOrientation(orientation) { + return (orientation === "landscape" || orientation === "portrait"); +} + function _getContainers() { return { device: { @@ -114592,8 +127378,8 @@ function _setContainers(containers, device, orientation) { function _getDimensions(device, orientation) { return { - deviceWidth: orientation === "portrait" ? device.viewPort.portrait.width : device.viewPort.landscape.width, - deviceHeight: orientation === "portrait" ? device.viewPort.portrait.height : device.viewPort.landscape.height, + deviceWidth: orientation === "portrait" ? device.screen.width : device.screen.height, + deviceHeight: orientation === "portrait" ? device.screen.height : device.screen.width, paddingLeft: device.viewPort[orientation].paddingLeft, paddingTop: device.viewPort[orientation].paddingTop, viewPort: { @@ -114603,20 +127389,69 @@ function _getDimensions(device, orientation) { }; } -function _formatSkin(containers, dimensions) { +function _formatSkin(containers, dimensions) { + var scaleFactor = dimensions.deviceWidth / dimensions.viewPort.width, + scaleString = "scale(" + scaleFactor + ")"; + containers.device.div.style.width = (dimensions.deviceWidth + 4) + "px"; containers.device.div.style.height = (dimensions.deviceHeight + 4) + "px"; - containers.viewport.div.style.width = dimensions.viewPort.width + "px"; containers.viewport.div.style.height = dimensions.viewPort.height + "px"; - containers.viewport.div.style.padding = dimensions.paddingTop + "px " + (dimensions.deviceWidth - (dimensions.viewPort.width + dimensions.paddingLeft)) + "px " + - (dimensions.deviceHeight - (dimensions.viewPort.height + dimensions.paddingTop)) + "px " + dimensions.paddingLeft + "px"; + containers.viewport.div.style.padding = "0"; + + jQuery('#viewport-container').css('-webkit-transform', scaleString); + jQuery('#viewport-container').css('-webkit-transform-origin', 'left top'); } function _setOrientation(layout) { _win.orientation = window.orientation = layout === "portrait" ? 0 : 90; } +function _upDateHWKeyPanelPosition(orientation, scaleFactor) { + var left = 0; + + if (orientation === 'portrait') { + if (db.retrieve("layout") === "portrait") { + left = 350 + $('#device-layout').width()*scaleFactor; + } else { + left = 470 + $('#device-layout').height()*scaleFactor; + } + } else { + if (db.retrieve("layout") === "portrait") { + left = 490 + $('#device-layout').height()*scaleFactor; + } else { + left = 350 + $('#device-layout').width()*scaleFactor; + } + } + + $("#hwkeys-panel").css("top", "40px"); + $("#hwkeys-panel").css("left", left+"px"); +} + +function _getTransformString(orientation, scaleFactor) { + var transformString = "", + offset; + + if (orientation === "landscape") { + if (db.retrieve("layout") === "portrait") { + offset = devices.getCurrentDevice().screen.height * scaleFactor + 170; + transformString = "translate("+ offset + "px, 0px) rotate(90deg) scale("+ scaleFactor +")"; + } else { + transformString = "translate(0px,0px) rotate(0deg) scale("+ scaleFactor +")"; + } + } else { + if (db.retrieve("layout") === "portrait") { + transformString = "translate(0px,0px) rotate(0deg) scale("+ scaleFactor +")"; + } else { + offset = devices.getCurrentDevice().screen.width * scaleFactor + 150; + transformString = "translate("+ offset + "px, 0px) rotate(90deg) scale("+ scaleFactor +")"; + } + } + + return transformString; +} + + _self = { init: function (win, doc) { _win = win; @@ -114639,11 +127474,9 @@ _self = { } containers = _getContainers(); - _setContainers(containers, device, orientation); dimensions = _getDimensions(device, orientation); - if (!device.skin) { _formatSkin(containers, dimensions); } @@ -114652,18 +127485,39 @@ _self = { }, changeLayoutType: function (layoutType) { + var orientation = db.retrieve("deviceOrientation") || "portrait"; if (!_validateLayoutType(layoutType)) { exception.raise(exception.types.LayoutType, "unknown layout type requested!"); } db.save("layout", layoutType); _self.resize(devices.getCurrentDevice()); - + _self.rotateDevice(orientation); if (!_win) return; - _setOrientation(layoutType); + }, + + scaleDevice: function (scaleFactor) { + var orientation = db.retrieve("deviceOrientation") || "portrait", + transformString = _getTransformString(orientation, scaleFactor); + _upDateHWKeyPanelPosition(orientation, scaleFactor); + db.save("deviceScaleFactor", scaleFactor); + jQuery('#device-layout').css('-webkit-transform-origin', '0% 0%'); + jQuery('#device-layout').css('-webkit-transform', transformString); + }, + rotateDevice: function (orientation) { + if (!_validateOrientation(orientation)) { + exception.raise(exception.types.OrientationType, "unknown orientation type requested!"); + } + + db.save("deviceOrientation", orientation); + jQuery('#device-layout').css('-webkit-transform-origin', '0% 0%'); + jQuery('#device-layout').css('-webkit-transform', + _getTransformString(orientation, db.retrieve("deviceScaleFactor"))); + _upDateHWKeyPanelPosition(orientation, db.retrieve("deviceScaleFactor")) + if (!_win) return; if (_win.onorientationchange) { _win.onorientationchange(); } @@ -114849,6 +127703,65 @@ self = module.exports = { }; }); +define('ripple/ui/plugins/HWKeys', function (require, exports, module) { +/* + * Copyright 2012 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var db = require('ripple/db'), + event = require('ripple/event'); + + +function initHWKey() { + var left = 0, + orientation = db.retrieve('deviceOrientation'), + scaleFactor = db.retrieve('deviceScaleFactor'); + + if (orientation === 'portrait') { + if (db.retrieve("layout") === "portrait") { + left = 350 + $('#device-layout').width()*scaleFactor; + } else { + left = 470 + $('#device-layout').height()*scaleFactor; + } + } else { + if (db.retrieve("layout") === "portrait") { + left = 490 + $('#device-layout').height()*scaleFactor; + } else { + left = 350 + $('#device-layout').width()*scaleFactor; + } + } + + $("#hwkeys-panel").css("top", "40px"); + $("#hwkeys-panel").css("left", left+"px"); + $("#hwkeys-panel").draggable({ cursor: 'move', containment: [0, 52, 1480, 800]}); + + jQuery("#hwkey-menu-btn").bind("click", function () { + event.trigger("tizenhwkeyEvent", ["menu"], true); + }); + jQuery("#hwkey-back-btn").bind("click", function () { + event.trigger("tizenhwkeyEvent", ["back"], true); + }); +} + +module.exports = { + initialize: function () { + initHWKey(); + } +}; + +}); define('ripple/ui/plugins/about-dialog', function (require, exports, module) { /* * Copyright 2011 Research In Motion Limited. @@ -115284,6 +128197,46 @@ var event = require('ripple/event'), }, type: "AUTHOR_ROOT", value: [] + }, + "api1pack00.WebAPITizenPackageTests": { + id: "api1pack00.WebAPITizenPackageTests", + name: "Tizen test app", + iconPath: "001.png", + version: "2.2", + show: true, + categories: ["message"], + size: 2048, + packageId: "api1pack00", + sharedURI: "/usr/local/share/apiuri", + operation: "http://tizen.org/appcontrol/operation/test", + appControl: { + uri: "http://tizen.org/appcontrol/uri/test", + mime: "text/plain", + category: "message", + data: "" + }, + type: "AUTHOR_ROOT", + value: [] + }, + "testpack00.autoWebapiTizenPackageTestApplication": { + id: "testpack00.autoWebapiTizenPackageTestApplication", + name: "Tizen test app 2", + iconPath: "002.png", + version: "3.0", + show: true, + categories: ["message"], + size: 2048, + packageId: "testpack00", + sharedURI: "/usr/local/share/apiuri2", + operation: "http://tizen.org/appcontrol/operation/test2", + appControl: { + uri: "http://tizen.org/appcontrol/uri/test2", + mime: "text/plain", + category: "message", + data: "" + }, + type: "AUTHOR_ROOT", + value: [] } }, _installedAppList = { @@ -115328,6 +128281,48 @@ var event = require('ripple/event'), }, type: "AUTHOR_ROOT", value: [] + }, + "api1pack00.WebAPITizenPackageTests": { + id: "api1pack00.WebAPITizenPackageTests", + name: "Tizen test app", + iconPath: "001.png", + version: "2.2", + show: true, + categories: ["message"], + installDate: new Date(), + size: 2048, + packageId: "api1pack00", + sharedURI: "/usr/local/share/apiuri", + operation: "http://tizen.org/appcontrol/operation/test", + appControl: { + uri: "http://tizen.org/appcontrol/uri/test", + mime: "text/plain", + category: "message", + data: "" + }, + type: "AUTHOR_ROOT", + value: [] + }, + "testpack00.autoWebapiTizenPackageTestApplication": { + id: "testpack00.autoWebapiTizenPackageTestApplication", + name: "Tizen test app 2", + iconPath: "002.png", + version: "3.0", + show: true, + categories: ["message"], + installDate: new Date(), + size: 2048, + packageId: "testpack00", + sharedURI: "/usr/local/share/apiuri2", + operation: "http://tizen.org/appcontrol/operation/test2", + appControl: { + uri: "http://tizen.org/appcontrol/uri/test2", + mime: "text/plain", + category: "message", + data: "" + }, + type: "AUTHOR_ROOT", + value: [] } }; @@ -116127,6 +129122,7 @@ define('ripple/ui/plugins/communication', function (require, exports, module) { var ui = require('ripple/ui'), event = require('ripple/event'), + deviceSettings = require('ripple/deviceSettings'), db = require('ripple/db'), utils = require('ripple/utils'), _messageType = { @@ -116190,6 +129186,7 @@ function _showMsg() { } function _msgEventInitialize() { + jQuery("#communication-messageRadioStatus").hide(); jQuery("#communication-sendMessage").unbind("click").click(function () { var messageItem, number = jQuery("#communication-senderName").val(), @@ -116203,6 +129200,25 @@ function _msgEventInitialize() { attachments: _attachments }; + if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false && + (type === 'sms' || type === 'mms')) { + jQuery("#communication-messageRadioStatus").html('cellular radio is off
Turn it on from Network Management Panel.'); + jQuery("#communication-messageRadioStatus").show(); + setTimeout(function () { + jQuery("#communication-messageRadioStatus").hide(); + }, 3000); + return; + } + if (deviceSettings.retrieve("WIFI_NETWORK.status") === false && + type === 'email') { + jQuery("#communication-messageRadioStatus").html('wifi radio is off
Turn it on from Network Management Panel.'); + jQuery("#communication-messageRadioStatus").show(); + setTimeout(function () { + jQuery("#communication-messageRadioStatus").hide(); + }, 3000); + return; + } + event.trigger("MessageReceived", [message]); _attachments = []; event.trigger("CommWinShow", [true]); @@ -116352,10 +129368,16 @@ function _endCall(callEndReason) { _data.conversationStartTime = null; - if (callEndReason === 'rejected') { + switch (callEndReason) { + case 'rejected': _record.direction = "REJECTED"; - } else { + break; + case 'remote': _record.direction = "RECEIVED"; + break; + case 'local': + _record.direction = "MISSEDNEW"; + break; } event.trigger("CallRecorded", [_record]); @@ -116372,35 +129394,34 @@ function _endCall(callEndReason) { } function _callEventInitialize() { - jQuery("#communication-callStart").toggle( + jQuery("#communication-cellularStatus").hide(); + jQuery("#communication-callStart").unbind('click').click( function () { -/* - if (_data.isInException) { - jQuery("#communication-callStart").removeData(); + if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false) { + jQuery("#communication-cellularStatus").show(); + setTimeout(function () { + jQuery("#communication-cellularStatus").hide(); + }, 3000); + return; } -*/ - if (_data.status === _status.IDLE) { _data.status = _status.DIALED; _initRecord(); + _showCall(); + jQuery("#callSettings tr:last-child td").text("Calliing..."); + jQuery("#communication-callStart > span").text("End Call"); + jQuery("#callSettings input").attr("disabled", "disabled"); } else { - return; - } + _endCall("local"); - _showCall(); - jQuery("#callSettings tr:last-child td").text("Caliing..."); - jQuery("#communication-callStart > span").text("End Call"); - jQuery("#callSettings input").attr("disabled", "disabled"); - }, - function () { - _endCall("local"); + jQuery("#callSettings tr:last-child td").text(""); + jQuery("#communication-callStart > span").text("Call"); + jQuery(".communication-callContainer tr:nth-child(3)").show(); + jQuery(".communication-callContainer tr:last-child").hide(); + jQuery("#callSettings input").removeAttr("disabled"); + } - jQuery("#callSettings tr:last-child td").text(""); - jQuery("#communication-callStart > span").text("Call"); - jQuery(".communication-callContainer tr:nth-child(3)").show(); - jQuery(".communication-callContainer tr:last-child").hide(); - jQuery("#callSettings input").removeAttr("disabled"); } ); @@ -116739,7 +129760,7 @@ function _showConfigWindow() { $(".configuration-window-item:eq(0)").css("color", "#ffffff"); $(".configuration-window-item").unbind('click'); - $(".configuration-window-item").bind("click", function () { + $(".configuration-window-item").bind("click", function () { $(".configuration-window-item").css("background-color", "#eeeeee"); $(".configuration-window-item").css("color", "#333333"); @@ -116854,11 +129875,7 @@ function _showConfigWindow() { require('ripple/deviceSettings').initialize(); require('ripple/ui/plugins/deviceSettings').terminate(); require('ripple/ui/plugins/deviceSettings').initialize(); - //reload application prgrams - programs = db.retrieveObject(_DB_APPLICATION_SAVE_KEY); - db.saveObject(_DB_APPLICATION_KEY, programs); - event.trigger("ApplicationLoad", []); - require('ripple/ui/plugins/application').initialize(); + //reload device setting jQuery(versionSelect).empty(); _settings = db.retrieveObject(_KEY); @@ -116942,6 +129959,7 @@ var event = require('ripple/event'), }, _contentContainer, _network_contentContainer, + DBNETWORKSETTING_KEY = "tizen2-preFlightModeNetworksetting", _CONTAINER_ID = _CONST.CONTENT_CONTAINER_ID; function _retrieveDeviceInfo(key) { @@ -117244,6 +130262,36 @@ function wiFiNetworkStatusCB(value) { document.getElementById("device-settings-WIFI_NETWORK-status").checked = value; } +function flightModeChangedCB(value) { + var networkSettings = {}; + if (value === true) { + networkSettings['wifiSetting'] = deviceSettings.retrieve("WIFI_NETWORK.status"); + networkSettings['cellularSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status"); + //networkSettings['bluetoothSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status"); + //networkSettings['nfcSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status"); + db.saveObject(DBNETWORKSETTING_KEY, networkSettings); + + deviceSettings.persist("CELLULAR_NETWORK.status", false); + deviceSettings.persist("WIFI_NETWORK.status", false); + event.trigger("nfc-power-setting", [false]); + event.trigger("bt-power-setting", [false]); + + document.getElementById("device-settings-WIFI_NETWORK-status").checked = false; + document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = false; + $("#device-settings-CELLULAR_NETWORK-status").parent().append(" (Disabled for Flight Mode)"); + document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = true; + + } else { + networkSettings = db.retrieveObject(DBNETWORKSETTING_KEY)||{"wifiSetting": true, "cellularSetting": true}; + deviceSettings.persist("WIFI_NETWORK.status", networkSettings['wifiSetting']); + deviceSettings.persist("CELLULAR_NETWORK.status", networkSettings['cellularSetting']); + document.getElementById("device-settings-WIFI_NETWORK-status").checked = networkSettings['wifiSetting']; + document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = networkSettings['cellularSetting']; + $("#config_flight_mode_notice").remove(); + document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = false; + } +} + function cellularNetworkStatusCB(value) { document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = value; } @@ -117306,11 +130354,17 @@ module.exports = { }); }); + if (deviceSettings.retrieve("CELLULAR_NETWORK.isFlightMode") === true) { + $("#device-settings-CELLULAR_NETWORK-status").parent().append(" (Disabled for Flight Mode)"); + document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = true; + } + event.on("DisplayBrightnessChanged", displayBrightnessCB); event.on("DisplayBrightnessChangedByPower", displayBrightnessCB); event.on("CpuLoadChanged", cpuLoadCB); event.on("AvailCapacityChanged", availCapacityCB); event.on("CpuLoadChangedByPower", cpuLoadCB); + event.on("FlightModeChanged", flightModeChangedCB); event.on("WiFiNetworkStatusChanged", wiFiNetworkStatusCB); event.on("CellularNetworkStatusChanged", cellularNetworkStatusCB); event.on("LayoutChanged", layoutCB); @@ -117319,6 +130373,8 @@ module.exports = { event.deleteEventHandler("DisplayBrightnessChanged", displayBrightnessCB); event.deleteEventHandler("DisplayBrightnessChangedByPower", displayBrightnessCB); event.deleteEventHandler("CpuLoadChanged", cpuLoadCB); + event.deleteEventHandler("AvailCapacityChanged", availCapacityCB); + event.deleteEventHandler("FlightModeChanged", flightModeChangedCB); event.deleteEventHandler("CpuLoadChangedByPower", cpuLoadCB); event.deleteEventHandler("WiFiNetworkStatusChanged", wiFiNetworkStatusCB); event.deleteEventHandler("CellularNetworkStatusChanged", cellularNetworkStatusCB); @@ -117344,7 +130400,8 @@ define('ripple/ui/plugins/devices', function (require, exports, module) { * limitations under the License. */ var constants = require('ripple/constants'), - db = require('ripple/db'); + db = require('ripple/db'), + resizer = require('ripple/resizer'); function _getTextZooming(zooming) { return zooming + '%'; @@ -117361,18 +130418,15 @@ module.exports = { initialize: function () { var zooming = document.getElementById(constants.ENCAPSULATOR.ZOOMING); - function updateZoomingValues() { - var zoomingText, scaleFactor, scaleString; - + var zoomingText, scaleFactor; + zoomingText = _getTextZooming(zooming.value); jQuery('#screen-zooming-label').html(zoomingText); // Zooming device skin scaleFactor = zooming.value / 100; - scaleString = "scale(" + scaleFactor + ")"; - jQuery('#device-layout').css('-webkit-transform', scaleString); - jQuery('#device-layout').css('-webkit-transform-origin', 'left top'); + resizer.scaleDevice(scaleFactor); } function initializeValues() { @@ -117420,13 +130474,15 @@ var db = require('ripple/db'), DB_DOWNLOAD_KEY : "tizen1-db-download", resources : [] }, - _cleanInputs, _loadResources, intervalId, + _cleanInputs, intervalId, _downloads; function _get() { _downloads = [ {id: "0001", url : "http://tizen.org/small_file.zip", size : "5", speed : "1.0", estimatedTime : "5", MIMEType : "application/zip"}, {id: "0002", url : "http://tizen.org/big_file.zip", size : "20", speed : "1.0", estimatedTime : "20", MIMEType : "application/zip"}, + {id: "0003", url : "http://download.tizen.org/tct/2_1/webapi-tizen-download-test-image-hq.png", size : "3937596", speed : "1968798", estimatedTime : "2", MIMEType : "image/png"}, + {id: "0004", url : "http://download.tizen.org/tct/2_1/webapi-tizen-download-test-image-lq.png", size : "589", speed : "589", estimatedTime : "1", MIMEType : "image/png"} ]; _data.resources = db.retrieveObject(_data.DB_DOWNLOAD_KEY) || _downloads; if (db.retrieveObject(_data.DB_DOWNLOAD_KEY) && db.retrieveObject(_data.DB_DOWNLOAD_KEY).length === 0) { @@ -117853,7 +130909,6 @@ define('ripple/ui/plugins/firstRunCheck', function (require, exports, module) { * limitations under the License. */ var utils = require('ripple/utils'), - constants = require('ripple/constants'), _platform = require('ripple/platform'), db = require('ripple/db'); @@ -118151,6 +131206,8 @@ var constants = require('ripple/constants'), _lineLayer, _drawLineTimeout, _playFrequency = 0, + _originalNavigator = window.navigator, + _locationSharing = false; _playState = {'play': false, 'replay': false}; function _initTimeZone() { @@ -118547,6 +131604,15 @@ module.exports = { if (obj && obj[0].id === 'gps-container' && obj.hasClass('ui-box-open')) { _updateGpsMap(); + // Update the position if user accept location sharing + if (_locationSharing === false) { + _originalNavigator.geolocation.getCurrentPosition(function(geoPosition) { + geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform( + new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel); + _locationSharing = true; + }); + } + // Simulator is loaded with geo panel folded, now it's the first time it's unfolded if (!marker) { // Only when the geo panel is unfolded, getCenter() will go well @@ -118572,6 +131638,7 @@ module.exports = { navigator.geolocation.getCurrentPosition(function (geoPosition) { geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform( new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel); + _locationSharing = true; }); } @@ -118959,6 +132026,7 @@ function _updateInformationView() { device = devices.getCurrentDevice(), tempString = "", widgetInfo = app.getInfo(), + layout = db.retrieve("layout") || "portrait", _systemSettings = db.retrieveObject("tizen2-systemsetting") || {"HOME_SCREEN": "", "LOCK_SCREEN": "", "INCOMING_CALL": "", "NOTIFICATION_EMAIL": ""}; //TODO: refactor this stuff to grab info from API, do this in a loop rather then hardcoded. Better DOM injection approach. This is legacy code @@ -118975,8 +132043,6 @@ function _updateInformationView() { } infoList.push(''); - -// infoList.push(""); if (widgetInfo.version) { infoList.push('
' + widgetInfo.version + '
'); @@ -118986,11 +132052,7 @@ function _updateInformationView() { infoList.push("
" + device.osName + " " + device.osVersion + "
"); infoList.push("
" + device.manufacturer + "
"); infoList.push("
" + device.screen.width + "x" + device.screen.height + "
"); - - if (device.screen.height !== device.viewPort.portrait.height) { - infoList.push("
" + device.viewPort.portrait.width + "x" + device.viewPort.portrait.height + "
"); - } - + infoList.push("
" + device.viewPort[layout].width.toFixed(0) + "x" + device.viewPort[layout].height.toFixed(0) + "
"); infoList.push("
" + device.ppi + " PPI
"); infoList.push("
" + "
" + device.userAgent + "
"); @@ -119075,6 +132137,9 @@ module.exports = { _updateInformationView(); }); + event.on("ScreenChangeDimensions", function() { + _updateInformationView(); + }); _updateInformationView(); } }; @@ -119151,6 +132216,7 @@ var constants = require('ripple/constants'), function _initializeLayout(prev, baton) { var layout = db.retrieve("layout"), + orientation = db.retrieve("deviceOrientation") || "portrait", layoutLandscape = document.getElementById(constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID), layoutPortrait = document.getElementById(constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID), currentDevice = devices.getCurrentDevice(), @@ -119158,17 +132224,17 @@ function _initializeLayout(prev, baton) { layoutTypeChanged = false; jQuery("#" + constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID).bind("click", function () { - resizer.changeLayoutType("landscape"); - event.trigger("LayoutChanged", ["landscape"], true); layoutLandscape.setAttribute("class", "layout-selected"); layoutPortrait.setAttribute("class", "layout-not-selected"); + resizer.rotateDevice("landscape"); + event.trigger("OrientationChanged", ["landscape"], true); }); jQuery("#" + constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID).bind("click", function () { - resizer.changeLayoutType("portrait"); - event.trigger("LayoutChanged", ["portrait"], true); layoutLandscape.setAttribute("class", "layout-not-selected"); layoutPortrait.setAttribute("class", "layout-selected"); + resizer.rotateDevice("portrait"); + event.trigger("OrientationChanged", ["portrait"], true); }); jQuery("#" + constants.COMMON.MENU_BUTTON).bind("click", function () { @@ -119206,6 +132272,15 @@ function _initializeLayout(prev, baton) { if (!layoutTypeChanged) { resizer.resize(currentDevice); } + + if (orientation === "portrait") { + layoutLandscape.setAttribute("class", "layout-not-selected"); + layoutPortrait.setAttribute("class", "layout-selected"); + } else { + layoutLandscape.setAttribute("class", "layout-selected"); + layoutPortrait.setAttribute("class", "layout-not-selected"); + } + resizer.rotateDevice(orientation); } module.exports = { @@ -119425,7 +132500,7 @@ var db = require('ripple/db'), _tagNDEF = { type: "GENERIC_TARGET", isSupportedNDEF: true, - ndefSize: 2, + ndefSize: 3, ndefs: [{ recordCount: 2, records: [{ @@ -119445,12 +132520,26 @@ var db = require('ripple/db'), records: [{ tnf: 1, type: "TypeA", - id: "ID001", + id: "ID003", payload: "This is 1st payload" }, { tnf: 1, type: "TypeA", - id: "ID002", + id: "ID004", + payload: "This is 2nd payload" + }] + }, + { + recordCount: 2, + records: [{ + tnf: 1, + type: "TypeA", + id: "ID005", + payload: "This is 1st payload" + }, { + tnf: 1, + type: "TypeA", + id: "ID006", payload: "This is 2nd payload" }] }] @@ -119484,11 +132573,8 @@ function elementEnableDisableSetting(prop) { jQuery("#nfc-attach-msg").text("\xa0"); jQuery("#nfc-peer-send-msg").text("\xa0"); if (prop && prop.power !== undefined && prop.power !== null) { - if (prop.power) { - $("#nfc-main-container").show(); - } else { + if (!prop.power) { $("#nfc-type").removeAttr("disabled"); - $("#nfc-main-container").hide(); } } if (prop && prop.connectedState !== undefined && prop.connectedState !== null) { @@ -119520,6 +132606,7 @@ function _initializeElements() { // initialize main menus wifiRadio.buttonset(); + $("#cellular-radio").buttonset(); $("#nfc-radio").buttonset(); $("#bluetooth-radio").buttonset(); @@ -119529,9 +132616,13 @@ function _initializeElements() { $("#wifi-radio2").prop('checked', false); if (deviceSettings.retrieve("WIFI_NETWORK.status") === true) { $("#wifi-radio1").prop('checked', true); + $("#wifi-radio1-label").css({'color': '#000000'}); + $("#wifi-radio2-label").css({'color': '#bbbbbb'}); } else { $("#wifi-radio2").prop('checked', true); + $("#wifi-radio1-label").css({'color': '#bbbbbb'}); + $("#wifi-radio2-label").css({'color': '#222222'}); } $("#wifi-radio1").button("refresh"); $("#wifi-radio2").button("refresh"); @@ -119540,10 +132631,26 @@ function _initializeElements() { $("#cellular-radio2").prop('checked', false); if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === true) { $("#cellular-radio1").prop('checked', true); + $("#cellular-radio1-label").css({'color': '#000000'}); + $("#cellular-radio2-label").css({'color': '#bbbbbb'}); } else { $("#cellular-radio2").prop('checked', true); + $("#cellular-radio1-label").css({'color': '#bbbbbb'}); + $("#cellular-radio2-label").css({'color': '#222222'}); + } + + if (deviceSettings.retrieve("CELLULAR_NETWORK.isFlightMode") === true) { + $("#cellular-radio1").prop('disabled', true); + $("#cellular-radio2").prop('disabled', true); + $("#panel_flight_mode_notice").show(); } + else { + $("#cellular-radio1").prop('disabled', false); + $("#cellular-radio2").prop('disabled', false); + $("#panel_flight_mode_notice").hide(); + } + $("#cellular-radio1").button("refresh"); $("#cellular-radio2").button("refresh"); @@ -119551,46 +132658,75 @@ function _initializeElements() { $("#bearer-radio2").button("refresh"); $("#wifi-radio1").click(function () { + $("#wifi-radio1-label").css({'color': '#000000'}); + $("#wifi-radio2-label").css({'color': '#bbbbbb'}); deviceSettings.persist("WIFI_NETWORK.status", true); event.trigger("WiFiNetworkStatusChanged", [true]); }); $("#wifi-radio2").click(function () { + $("#wifi-radio1-label").css({'color': '#bbbbbb'}); + $("#wifi-radio2-label").css({'color': '#222222'}); deviceSettings.persist("WIFI_NETWORK.status", false); event.trigger("WiFiNetworkStatusChanged", [false]); }); $("#cellular-radio1").click(function () { + $("#cellular-radio1-label").css({'color': '#000000'}); + $("#cellular-radio2-label").css({'color': '#bbbbbb'}); deviceSettings.persist("CELLULAR_NETWORK.status", true); event.trigger("CellularNetworkStatusChanged", [true]); }); $("#cellular-radio2").click(function () { + $("#cellular-radio1-label").css({'color': '#bbbbbb'}); + $("#cellular-radio2-label").css({'color': '#222222'}); deviceSettings.persist("CELLULAR_NETWORK.status", false); event.trigger("CellularNetworkStatusChanged", [false]); }); + $("#nfc-radio1-label").css({'color': '#bbbbbb'}); + $("#nfc-radio2-label").css({'color': '#222222'}); + + $("#bluetooth-radio1-label").css({'color': '#bbbbbb'}); + $("#bluetooth-radio2-label").css({'color': '#222222'}); + + $("#bearer-radio1-label").css({'color': '#bbbbbb'}); + $("#bearer-radio2-label").css({'color': '#222222'}); + $("#nfc-radio1").click(function () { + $("#nfc-radio2-label").css({'color': '#bbbbbb'}); + $("#nfc-radio1-label").css({'color': '#222222'}); $("#nfc-main-container").show(); }); $("#nfc-radio2").click(function () { + $("#nfc-radio1-label").css({'color': '#bbbbbb'}); + $("#nfc-radio2-label").css({'color': '#222222'}); $("#nfc-main-container").hide(); }); $("#bluetooth-radio1").click(function () { + $("#bluetooth-radio2-label").css({'color': '#bbbbbb'}); + $("#bluetooth-radio1-label").css({'color': '#222222'}); $("#bluetooth-main-container").show(); }); $("#bluetooth-radio2").click(function () { + $("#bluetooth-radio1-label").css({'color': '#bbbbbb'}); + $("#bluetooth-radio2-label").css({'color': '#222222'}); $("#bluetooth-main-container").hide(); }); $("#bearer-radio1").click(function () { + $("#bearer-radio2-label").css({'color': '#bbbbbb'}); + $("#bearer-radio1-label").css({'color': '#222222'}); $("#bearer-main-container").show(); }); $("#bearer-radio2").click(function () { + $("#bearer-radio1-label").css({'color': '#bbbbbb'}); + $("#bearer-radio2-label").css({'color': '#222222'}); $("#bearer-main-container").hide(); }); @@ -119907,6 +133043,23 @@ module.exports = { _bearerRelease(type, idBearer, evNetworkDisconnected); }); + // Update UI for Flight Mode changing + event.on("FlightModeChanged", function (value) { + if (value === true) { + $("#cellular-radio1").prop('disabled', true); + $("#cellular-radio2").prop('disabled', true); + $("#panel_flight_mode_notice").show(); + } + else { + $("#cellular-radio1").prop('disabled', false); + $("#cellular-radio2").prop('disabled', false); + $("#panel_flight_mode_notice").hide(); + } + + $("#cellular-radio1").button("refresh"); + $("#cellular-radio2").button("refresh"); + }); + $("#bt-adapter-name").text(db.retrieveObject("tizen1-db-bluetooth_adapter-name") || "Tizen BT Adapter"); _btDeviceTemplate = $("#network-bt-template").html(); $("#network-bt-box").empty(); @@ -120477,23 +133630,23 @@ function _showHistory() { function _addHistory(uri) { - var i = 0; - histories = db.retrieveObject(constants.LAUNCHING_HISTORY); - if (histories !== undefined) { - for (i; i < histories.length; i++) { - if (uri === histories[i]) { + var i = 0, thehistories = db.retrieveObject(constants.LAUNCHING_HISTORY); + if (thehistories !== undefined) { + for (i; i < thehistories.length; i++) { + if (uri === thehistories[i]) { return; } } - - if (histories.length >= 20) { - histories.pop(); + if (thehistories.length >= 20) { + thehistories.reverse(); + thehistories.pop(); + thehistories.reverse(); } } else { - histories = []; + thehistories = []; } - histories.push(uri); - db.saveObject(constants.LAUNCHING_HISTORY, histories); + thehistories.push(uri); + db.saveObject(constants.LAUNCHING_HISTORY, thehistories); } _event.on("FrameHistoryChange", function (url) { @@ -120541,7 +133694,7 @@ module.exports = { if (_currentURL().match(/^file:/) && omnibar.value.match(/^file:/)) { // Use ajax to know whether that file exists xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { + if (xhr.readyState === 4) { if (xhr.responseText !== '') { _persist(omnibar.value); _persistRoot(omnibar.value); @@ -120722,13 +133875,40 @@ var db = require('ripple/db'), appIds: ["http://tizen.org/dummy"]}, "/opt/usr/media/sample.wgt": {id: "SAMPLE_ID", name: "Sample Package", iconPath: "sample.png", version: "1.9", totalSize: 8264, dataSize: 50, author: "Tizen.org", description: "This is sample package", - appIds: ["http://tizen.org/dialer", "http://tizen.org/sender"]} + appIds: ["http://tizen.org/dialer", "http://tizen.org/sender"]}, + "/opt/usr/media/api1pack00.wgt": { + id: "api1pack00", name: "tct-package-tizen-tests", + iconPath: "tizen.png", version: "1.9", + totalSize: 8264, dataSize: 50, author: "TizenDev", + description: "This is a description which is used in tests.", + appIds: ["api1pack00.WebAPITizenPackageTests"]}, + "/opt/usr/media/testpack00.wgt": { + id: "testpack00", name: "autoWebapiTizenPackageTestApplication", + iconPath: "tizen.png", version: "5.5.5", + totalSize: 8264, dataSize: 50, author: "TizenDev", + description: "This is a description which is used in tests.", + appIds: ["testpack00.autoWebapiTizenPackageTestApplication"]} }, _installedList = { "SAMPLE_ID": { id: "SAMPLE_ID", name: "Sample Package", iconPath: "sample.png", version: "1.9", totalSize: 8264, dataSize: 50, lastModified: new Date(), author: "Tizen.org", description: "This is sample package", appIds: ["http://tizen.org/dialer", "http://tizen.org/sender"] + }, + "api1pack00": {id: "api1pack00", name: "tct-package-tizen-tests", + iconPath: "tizen.png", version: "1.9", + totalSize: 8264, dataSize: 50, lastModified: new Date(), + author: "TizenDev", + description: "This is a description which is used in tests.", + appIds: ["api1pack00.WebAPITizenPackageTests"] + }, + "testpack00": {id: "testpack00", name: "autoWebapiTizenPackageTestApplication", + iconPath: "tizen.png", version: "5.5.5", + totalSize: 8264, dataSize: 50, lastModified: new Date(), + author: "TizenDev", + description: "This is a description which is used in tests.", + appIds: ["testpack00.autoWebapiTizenPackageTestApplication"] } + }, _packageListTemplate, _packageInstalledTemplate; @@ -121252,6 +134432,10 @@ function _updatePlatformDeviceSelect(platformID, currentDeviceKey) { .sort(function (a, b) { return (a.screen.width * a.screen.height) < (b.screen.width * b.screen.height) ? -1 : ((a.screen.width * a.screen.height) > (b.screen.width * b.screen.height) ? 1 : 0); }); + db.remove("viewport_width"); + db.remove("viewport_height"); + db.remove("viewportTag"); + devicesSelect.innerHTML = ""; listOfSortedDevices.forEach(function (dev) { var deviceNode = utils.createElement("option", { @@ -121304,7 +134488,6 @@ module.exports = { } }); }); - _updatePlatformDeviceSelect(newPlatform, newDevice); }); @@ -121343,12 +134526,10 @@ module.exports = { versionSelect.appendChild(versionNode); } }); - platformSelect.appendChild(platformNode); }); _updatePlatformDeviceSelect(currentPlatform, currentDeviceKey); - } }; @@ -122285,6 +135466,7 @@ function _resetAccelerometer() { orientation: new Rotation(0, 0, 0), timestamp: new Date().getTime() }); + accelerometer.triggerEvent(); } function _resetMagneticField() { @@ -122550,6 +135732,7 @@ module.exports = { _flag = gl ? true : false; + accelerometer.init(); _createThreeDModel(); _initializeSensorSettings(); //_initializeLightSettings(); @@ -122599,7 +135782,6 @@ var db = require('ripple/db'), utils = require('ripple/utils'), platform = require('ripple/platform'), notifications = require('ripple/notifications'), - transport = require('ripple/platform/webworks.core/2.0.0/client/transport'), tooltip = require('ripple/ui/plugins/tooltip'), bus = require('ripple/bus'), required = { @@ -122885,9 +136067,9 @@ function getSimulators() { } bus.ajax( - "POST", + "POST", host + "/simulators", - _settings.get(), + _settings.get(), function (resp) { var sims = resp.data.simulators; @@ -123279,7 +136461,7 @@ function _initialize(prev, baton) { }, false); $("#options-menu-about").click(function () { - about.show(); + about.show(); }); // TODO: reload here? } @@ -124090,7 +137272,8 @@ var _self, "notifications", "themeSwitcher", "settings-menu", - "configWindow" + "configWindow", + "HWKeys" //"launchingHistory" ], _overlay = { -- 2.7.4
" + platform.current().name + "