[Utils] Allow global JSON object redefinition
[platform/core/api/webapi-plugins.git] / src / download / download_api.js
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 var JSON_ = xwalk.JSON;
18 var privUtils_ = xwalk.utils;
19 var validator_ = xwalk.utils.validator;
20 var types_ = validator_.Types;
21 var check_ = xwalk.utils.type;
22
23
24 var callbackId = 0;
25 var callbacks = {};
26 var requests = {};
27
28
29 extension.setMessageListener(function(json) {
30
31   var result = JSON_.parse(json);
32   var callback = callbacks[result.callbackId];
33   //privUtils_.log("PostMessage received: " + result.status);
34
35   if (!callback) {
36     privUtils_.log('Ignoring unknown callback: ' + result.callbackId);
37     return;
38   }
39   setTimeout(function() {
40     if (result.status == 'progress') {
41       if (callback.onprogress) {
42         var receivedSize = result.receivedSize;
43         var totalSize = result.totalSize;
44         callback.onprogress(result.callbackId, receivedSize, totalSize);
45       }
46     } else if (result.status == 'paused') {
47       if (callback.onpaused) {
48         callback.onpaused(result.callbackId);
49       }
50     } else if (result.status == 'canceled') {
51       if (callback.oncanceled) {
52         callback.oncanceled(result.callbackId);
53       }
54     } else if (result.status == 'completed') {
55       if (callback.oncompleted) {
56         var fullPath = result.fullPath;
57         callback.oncompleted(result.callbackId, fullPath);
58       }
59     } else if (result.status == 'error') {
60       if (callback.onfailed) {
61         callback.onfailed(result.callbackId,
62             new WebAPIException(result.error));
63       }
64     }
65   }, 0);
66 });
67
68 function nextCallbackId() {
69   return ++callbackId;
70 }
71
72 function callNative(cmd, args) {
73   var json = {'cmd': cmd, 'args': args};
74   var argjson = JSON_.stringify(json);
75   var resultString = extension.internal.sendSyncMessage(argjson);
76   var result = JSON_.parse(resultString);
77
78   if (typeof result !== 'object') {
79     throw new WebAPIException(WebAPIException.UNKNOWN_ERR);
80   }
81
82   if (result.status == 'success') {
83     if (result.result) {
84       return result.result;
85     }
86     return true;
87   } else if (result.status == 'error') {
88     var err = result.error;
89     if (err) {
90       throw new WebAPIException(err);
91     }
92     return false;
93   }
94 }
95
96
97 function callNativeWithCallback(cmd, args, callback) {
98   if (callback) {
99     var id = nextCallbackId();
100     args.callbackId = id;
101     callbacks[id] = callback;
102   }
103
104   return callNative(cmd, args);
105 }
106
107 function SetReadOnlyProperty(obj, n, v) {
108   Object.defineProperty(obj, n, {value: v, writable: false});
109 }
110
111 var DownloadState = {
112   'QUEUED': 'QUEUED',
113   'DOWNLOADING': 'DOWNLOADING',
114   'PAUSED': 'PAUSED',
115   'CANCELED': 'CANCELED',
116   'COMPLETED': 'COMPLETED',
117   'FAILED': 'FAILED'
118 };
119
120 var DownloadNetworkType = {
121   'CELLULAR': 'CELLULAR',
122   'WIFI': 'WIFI',
123   'ALL': 'ALL'
124 };
125
126 tizen.DownloadRequest = function(url, destination, fileName, networkType, httpHeader) {
127   validator_.isConstructorCall(this, tizen.DownloadRequest);
128
129   var url_ = url;
130   var networkType_;
131
132   if (networkType === undefined || !(networkType in DownloadNetworkType)) {
133     networkType_ = 'ALL';
134   } else {
135     networkType_ = networkType;
136   }
137
138   Object.defineProperties(this, {
139     'url': {
140       enumerable: true,
141       get: function() {
142         return url_;
143       },
144       set: function(value) {
145         if (value !== null) {
146           url_ = value;
147         }
148       },
149     },
150     'destination': {
151       writable: true,
152       enumerable: true,
153       value: destination === undefined ? '' : destination,
154     },
155     'fileName': {
156       writable: true,
157       enumerable: true,
158       value: fileName === undefined ? '' : fileName,
159     },
160     'networkType': {
161       enumerable: true,
162       get: function() {
163         return networkType_;
164       },
165       set: function(value) {
166         if (value === null || value in DownloadNetworkType) {
167           networkType_ = value;
168         }
169       },
170     },
171     'httpHeader': {
172       writable: true,
173       enumerable: true,
174       value: httpHeader === undefined ? {} : httpHeader,
175     }
176   });
177 };
178
179
180 function DownloadManager() {
181   // constructor of DownloadManager
182 }
183
184 DownloadManager.prototype.start = function() {
185   var args = validator_.validateArgs(arguments, [
186     {'name' : 'downloadRequest', 'type': types_.PLATFORM_OBJECT, 'values': tizen.DownloadRequest},
187     {'name' : 'downloadCallback', 'type': types_.LISTENER,
188       'values' : ['onprogress', 'onpaused', 'oncanceled', 'oncompleted', 'onfailed'],
189       optional: true, nullable: true}
190   ]);
191
192   var nativeParam = {
193     'url': args.downloadRequest.url,
194     'destination': args.downloadRequest.destination,
195     'fileName': args.downloadRequest.fileName,
196     'networkType': args.downloadRequest.networkType,
197     'httpHeader': args.downloadRequest.httpHeader,
198     'callbackId': nextCallbackId()
199   };
200
201   if (args.downloadCallback) {
202     this.setListener(nativeParam.callbackId, args.downloadCallback);
203   }
204
205   try {
206     callNative('DownloadManager_start', nativeParam);
207   } catch (e) {
208     if ('NetworkError' === e.name) {
209       return -1;
210     }
211     throw e;
212   }
213
214   requests[nativeParam.callbackId] = args.downloadRequest;
215
216   return nativeParam.callbackId;
217 };
218
219 DownloadManager.prototype.cancel = function() {
220   var args = validator_.validateArgs(arguments, [
221     {name: 'downloadId', type: types_.LONG, 'nullable': false, 'optional': false}
222   ]);
223
224   var nativeParam = {
225     'downloadId': args.downloadId
226   };
227
228   if (typeof requests[args.downloadId] === 'undefined')
229     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
230         'the identifier does not match any download operation in progress');
231
232   try {
233     callNative('DownloadManager_cancel', nativeParam);
234   } catch (e) {
235     throw e;
236   }
237 };
238
239 DownloadManager.prototype.pause = function() {
240   var args = validator_.validateArgs(arguments, [
241     {'name': 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
242   ]);
243
244   var nativeParam = {
245     'downloadId': args.downloadId
246   };
247
248   if (typeof requests[args.downloadId] === 'undefined')
249     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
250         'the identifier does not match any download operation in progress');
251
252   try {
253     callNative('DownloadManager_pause', nativeParam);
254   } catch (e) {
255     throw e;
256   }
257 };
258
259 DownloadManager.prototype.resume = function() {
260   var args = validator_.validateArgs(arguments, [
261     {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
262   ]);
263
264   var nativeParam = {
265     'downloadId': args.downloadId
266   };
267
268   if (typeof requests[args.downloadId] === 'undefined')
269     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
270         'the identifier does not match any download operation in progress');
271
272   try {
273     callNative('DownloadManager_resume', nativeParam);
274   } catch (e) {
275     throw e;
276   }
277 };
278
279 DownloadManager.prototype.getState = function() {
280   var args = validator_.validateArgs(arguments, [
281     {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
282   ]);
283
284   var nativeParam = {
285     'downloadId': args.downloadId
286   };
287
288   if (typeof requests[args.downloadId] === 'undefined')
289     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
290         'the identifier does not match any download operation in progress');
291
292   try {
293     return callNative('DownloadManager_getState', nativeParam);
294   } catch (e) {
295     throw e;
296   }
297 };
298
299 DownloadManager.prototype.getDownloadRequest = function() {
300   var args = validator_.validateArgs(arguments, [
301     {'name': 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
302   ]);
303
304   if (typeof requests[args.downloadId] === 'undefined')
305     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
306         'the identifier does not match any download operation in progress');
307
308   return requests[args.downloadId];
309 };
310
311 DownloadManager.prototype.getMIMEType = function() {
312   var args = validator_.validateArgs(arguments, [
313     {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
314   ]);
315
316   var nativeParam = {
317     'downloadId': args.downloadId
318   };
319
320   if (typeof requests[args.downloadId] === 'undefined')
321     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
322         'the identifier does not match any download operation in progress');
323
324   try {
325     return callNative('DownloadManager_getMIMEType', nativeParam);
326   } catch (e) {
327     throw e;
328   }
329 };
330
331 DownloadManager.prototype.setListener = function() {
332   var args = validator_.validateArgs(arguments, [
333     {'name' : 'downloadId', 'type': types_.LONG},
334     {'name' : 'downloadCallback', 'type': types_.LISTENER,
335       'values' : ['onprogress', 'onpaused', 'oncanceled', 'oncompleted', 'onfailed']}
336   ]);
337
338   callbacks[args.downloadId] = args.downloadCallback;
339 };
340
341
342
343 exports = new DownloadManager();
344