Merge "[Spec] fix for common profile" into tizen
[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 var converter_ = xwalk.utils.converter;
23
24
25 var callbackId = 0;
26 var callbacks = {};
27 var requests = {};
28
29
30 extension.setMessageListener(function(json) {
31
32   var result = JSON_.parse(json);
33   var callback = callbacks[result.callbackId];
34   //privUtils_.log("PostMessage received: " + result.status);
35
36   if (!callback) {
37     privUtils_.log('Ignoring unknown callback: ' + result.callbackId);
38     return;
39   }
40   setTimeout(function() {
41     if (result.status == 'progress') {
42       if (callback.onprogress) {
43         var receivedSize = result.receivedSize;
44         var totalSize = result.totalSize;
45         callback.onprogress(result.callbackId, receivedSize, totalSize);
46       }
47     } else if (result.status == 'paused') {
48       if (callback.onpaused) {
49         callback.onpaused(result.callbackId);
50       }
51     } else if (result.status == 'canceled') {
52       if (callback.oncanceled) {
53         callback.oncanceled(result.callbackId);
54       }
55     } else if (result.status == 'completed') {
56       if (callback.oncompleted) {
57         var fullPath = result.fullPath;
58         callback.oncompleted(result.callbackId, fullPath);
59       }
60     } else if (result.status == 'error') {
61       if (callback.onfailed) {
62         callback.onfailed(result.callbackId,
63             new WebAPIException(result.error));
64       }
65     }
66   }, 0);
67 });
68
69 function nextCallbackId() {
70   return ++callbackId;
71 }
72
73 function callNative(cmd, args) {
74   var json = {'cmd': cmd, 'args': args};
75   var argjson = JSON_.stringify(json);
76   var resultString = extension.internal.sendSyncMessage(argjson);
77   var result = JSON_.parse(resultString);
78
79   if (typeof result !== 'object') {
80     throw new WebAPIException(WebAPIException.UNKNOWN_ERR);
81   }
82
83   if (result.status == 'success') {
84     if (result.result) {
85       return result.result;
86     }
87     return true;
88   } else if (result.status == 'error') {
89     var err = result.error;
90     if (err) {
91       throw new WebAPIException(err);
92     }
93     return false;
94   }
95 }
96
97
98 function callNativeWithCallback(cmd, args, callback) {
99   if (callback) {
100     var id = nextCallbackId();
101     args.callbackId = id;
102     callbacks[id] = callback;
103   }
104
105   return callNative(cmd, args);
106 }
107
108 function SetReadOnlyProperty(obj, n, v) {
109   Object.defineProperty(obj, n, {value: v, writable: false});
110 }
111
112 var DownloadState = {
113   'QUEUED': 'QUEUED',
114   'DOWNLOADING': 'DOWNLOADING',
115   'PAUSED': 'PAUSED',
116   'CANCELED': 'CANCELED',
117   'COMPLETED': 'COMPLETED',
118   'FAILED': 'FAILED'
119 };
120
121 var DownloadNetworkType = {
122   'CELLULAR': 'CELLULAR',
123   'WIFI': 'WIFI',
124   'ALL': 'ALL'
125 };
126
127 tizen.DownloadRequest = function(url, destination, fileName, networkType, httpHeader) {
128   validator_.isConstructorCall(this, tizen.DownloadRequest);
129
130   var url_ = converter_.toString(url);
131   var destination_ = destination === undefined ? '' : converter_.toString(destination);
132   var fileName_ = fileName === undefined ? '' : converter_.toString(fileName);
133
134   var networkType_;
135
136   if (networkType === undefined || !(networkType in DownloadNetworkType)) {
137     networkType_ = 'ALL';
138   } else {
139     networkType_ = networkType;
140   }
141
142   Object.defineProperties(this, {
143     'url': {
144       enumerable: true,
145       get: function() {
146         return url_;
147       },
148       set: function(value) {
149         if (value !== null) {
150           url_ = converter_.toString(value);
151         }
152       },
153     },
154     'destination': {
155       enumerable: true,
156       get: function() {
157         return destination_;
158       },
159       set: function(value) {
160         if (value !== null) {
161           destination_ = converter_.toString(value);
162         }
163       },
164     },
165     'fileName': {
166       enumerable: true,
167       get: function() {
168         return fileName_;
169       },
170       set: function(value) {
171         if (value !== null) {
172           fileName_ = converter_.toString(value);
173         }
174       },
175     },
176     'networkType': {
177       enumerable: true,
178       get: function() {
179         return networkType_;
180       },
181       set: function(value) {
182         if (value === null || value in DownloadNetworkType) {
183           networkType_ = value;
184         }
185       },
186     },
187     'httpHeader': {
188       writable: true,
189       enumerable: true,
190       value: httpHeader === undefined ? {} : httpHeader,
191     }
192   });
193 };
194
195
196 function DownloadManager() {
197   // constructor of DownloadManager
198 }
199
200 DownloadManager.prototype.start = function() {
201   var args = validator_.validateArgs(arguments, [
202     {'name' : 'downloadRequest', 'type': types_.PLATFORM_OBJECT, 'values': tizen.DownloadRequest},
203     {'name' : 'downloadCallback', 'type': types_.LISTENER,
204       'values' : ['onprogress', 'onpaused', 'oncanceled', 'oncompleted', 'onfailed'],
205       optional: true, nullable: true}
206   ]);
207
208   var nativeParam = {
209     'url': args.downloadRequest.url,
210     'destination': args.downloadRequest.destination,
211     'fileName': args.downloadRequest.fileName,
212     'networkType': args.downloadRequest.networkType,
213     'httpHeader': args.downloadRequest.httpHeader,
214     'callbackId': nextCallbackId()
215   };
216
217   if (args.downloadCallback) {
218     this.setListener(nativeParam.callbackId, args.downloadCallback);
219   }
220
221   try {
222     callNative('DownloadManager_start', nativeParam);
223   } catch (e) {
224     if ('NetworkError' === e.name) {
225       return -1;
226     }
227     throw e;
228   }
229
230   requests[nativeParam.callbackId] = args.downloadRequest;
231
232   return nativeParam.callbackId;
233 };
234
235 DownloadManager.prototype.cancel = function() {
236   var args = validator_.validateArgs(arguments, [
237     {name: 'downloadId', type: types_.LONG, 'nullable': false, 'optional': false}
238   ]);
239
240   var nativeParam = {
241     'downloadId': args.downloadId
242   };
243
244   if (typeof requests[args.downloadId] === 'undefined')
245     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
246         'the identifier does not match any download operation in progress');
247
248   try {
249     callNative('DownloadManager_cancel', nativeParam);
250   } catch (e) {
251     throw e;
252   }
253 };
254
255 DownloadManager.prototype.pause = function() {
256   var args = validator_.validateArgs(arguments, [
257     {'name': 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
258   ]);
259
260   var nativeParam = {
261     'downloadId': args.downloadId
262   };
263
264   if (typeof requests[args.downloadId] === 'undefined')
265     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
266         'the identifier does not match any download operation in progress');
267
268   try {
269     callNative('DownloadManager_pause', nativeParam);
270   } catch (e) {
271     throw e;
272   }
273 };
274
275 DownloadManager.prototype.resume = function() {
276   var args = validator_.validateArgs(arguments, [
277     {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
278   ]);
279
280   var nativeParam = {
281     'downloadId': args.downloadId
282   };
283
284   if (typeof requests[args.downloadId] === 'undefined')
285     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
286         'the identifier does not match any download operation in progress');
287
288   try {
289     callNative('DownloadManager_resume', nativeParam);
290   } catch (e) {
291     throw e;
292   }
293 };
294
295 DownloadManager.prototype.getState = function() {
296   var args = validator_.validateArgs(arguments, [
297     {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
298   ]);
299
300   var nativeParam = {
301     'downloadId': args.downloadId
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   try {
309     return callNative('DownloadManager_getState', nativeParam);
310   } catch (e) {
311     throw e;
312   }
313 };
314
315 DownloadManager.prototype.getDownloadRequest = function() {
316   var args = validator_.validateArgs(arguments, [
317     {'name': 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
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   return requests[args.downloadId];
325 };
326
327 DownloadManager.prototype.getMIMEType = function() {
328   var args = validator_.validateArgs(arguments, [
329     {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
330   ]);
331
332   var nativeParam = {
333     'downloadId': args.downloadId
334   };
335
336   if (typeof requests[args.downloadId] === 'undefined')
337     throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
338         'the identifier does not match any download operation in progress');
339
340   try {
341     return callNative('DownloadManager_getMIMEType', nativeParam);
342   } catch (e) {
343     throw e;
344   }
345 };
346
347 DownloadManager.prototype.setListener = function() {
348   var args = validator_.validateArgs(arguments, [
349     {'name' : 'downloadId', 'type': types_.LONG},
350     {'name' : 'downloadCallback', 'type': types_.LISTENER,
351       'values' : ['onprogress', 'onpaused', 'oncanceled', 'oncompleted', 'onfailed']}
352   ]);
353
354   callbacks[args.downloadId] = args.downloadCallback;
355 };
356
357
358
359 exports = new DownloadManager();
360