--- /dev/null
+// Download
+
+var validator_ = xwalk.utils.validator;
+var types_ = validator_.Types;
+var check_ = xwalk.utils.type;
+
+
+var callbackId = 0;
+var callbacks = {};
+var requests = {};
+
+
+extension.setMessageListener(function(json) {
+
+ var result = JSON.parse(json);
+ var callback = callbacks[result['callbackId']];
+ //console.log("PostMessage received: " + result.status);
+
+ if (result.status == 'progress') {
+ var receivedSize = result.receivedSize;
+ var totalSize = result.totalSize;
+ callback.onprogress(result.callbackId, receivedSize, totalSize);
+ }
+ else if (result.status == 'paused') {
+ callback.onpaused(result.callbackId);
+ }
+ else if (result.status == 'canceled') {
+ callback.oncanceled(result.callbackId);
+ }
+ else if (result.status == 'completed') {
+ var fullPath = result.fullPath;
+ callback.oncompleted(result.callbackId, fullPath);
+ }
+ else if (result.status == 'error') {
+ callback.onfailed(
+ result.callbackId, new tizen.WebAPIError(result['error'].name, result['error'].message));
+ }
+});
+
+function nextCallbackId() {
+ return callbackId++;
+}
+
+function callNative(cmd, args) {
+ var json = {'cmd': cmd, 'args': args};
+ var argjson = JSON.stringify(json);
+ var resultString = extension.internal.sendSyncMessage(argjson);
+ var result = JSON.parse(resultString);
+
+ if (typeof result !== 'object') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+ }
+
+ if (result['status'] == 'success') {
+ if (result['result']) {
+ return result['result'];
+ }
+ return true;
+ } else if (result['status'] == 'error') {
+ var err = result['error'];
+ if (err) {
+ throw new tizen.WebAPIException(err.name, err.message);
+ }
+ return false;
+ }
+}
+
+
+function callNativeWithCallback(cmd, args, callback) {
+ if (callback) {
+ var id = nextCallbackId();
+ args['callbackId'] = id;
+ callbacks[id] = callback;
+ }
+
+ return callNative(cmd, args);
+}
+
+function SetReadOnlyProperty(obj, n, v) {
+ Object.defineProperty(obj, n, {value: v, writable: false});
+}
+
+var DownloadState = {
+ 'QUEUED': 'QUEUED',
+ 'DOWNLOADING': 'DOWNLOADING',
+ 'PAUSED': 'PAUSED',
+ 'CANCELED': 'CANCELED',
+ 'COMPLETED': 'COMPLETED',
+ 'FAILED': 'FAILED'
+};
+
+var DownloadNetworkType = {
+ 'CELLULAR': 'CELLULAR',
+ 'WIFI': 'WIFI',
+ 'ALL': 'ALL'
+};
+
+tizen.DownloadRequest = function(url, destination, fileName, networkType, httpHeader) {
+ validator_.isConstructorCall(this, tizen.DownloadRequest);
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'url', 'type': types_.STRING, 'nullable': false, 'optional': false},
+ {'name' : 'destination', 'type': types_.STRING, 'nullable': true, 'optional': true},
+ {'name' : 'fileName', 'type': types_.STRING, 'nullable': true, 'optional': true},
+ {'name' : 'networkType', 'type': types_.ENUM, 'values': ['CELLULAR', 'WIFI', 'ALL'],
+ 'nullable' : true, 'optional': true},
+ {'name' : 'httpHeader', 'type': types_.Dictionary, 'nullable': true, 'optional': true}
+ ]);
+
+ var url_ = url;
+ var networkType_;
+
+ if (networkType === undefined) networkType_ = 'ALL';
+ else if (networkType in DownloadNetworkType) networkType_ = networkType;
+
+ Object.defineProperties(this, {
+ 'url': { enumerable: true,
+ get: function() { return url_;},
+ set: function(value) { if (value != null) { url_ = value; }} },
+ 'destination': { writable: true, enumerable: true,
+ value: destination === undefined ? '' : destination },
+ 'fileName': { writable: true, enumerable: true,
+ value: fileName === undefined ? '' : fileName },
+ 'networkType': { enumerable: true,
+ get: function() { return networkType_;},
+ set: function(value) {
+ if (value === null || value in DownloadNetworkType) { networkType_ = value; }} },
+ 'httpHeader': { writable: true, enumerable: true,
+ value: httpHeader === undefined ? {} : httpHeader }
+ });
+};
+
+
+function DownloadManager() {
+ // constructor of DownloadManager
+}
+
+DownloadManager.prototype.start = function(downloadRequest) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'downloadRequest', 'type': types_.PLATFORM_OBJECT, 'values': tizen.DownloadRequest},
+ {'name' : 'downloadCallback', 'type': types_.LISTENER,
+ 'values' : ['onprogress', 'onpaused', 'oncanceled', 'oncompleted', 'onfailed'],
+ optional: true, nullable: true}
+ ]);
+
+ var nativeParam = {
+ 'url': args.downloadRequest.url,
+ 'destination': args.downloadRequest.destination,
+ 'fileName': args.downloadRequest.fileName,
+ 'networkType': args.downloadRequest.networkType,
+ 'httpHeader': args.downloadRequest.httpHeader,
+ 'callbackId': nextCallbackId()
+ };
+
+ if (args.downloadCallback) {
+ this.setListener(nativeParam.callbackId, args.downloadCallback);
+ }
+
+ try {
+ var syncResult = callNative('DownloadManager_start', nativeParam);
+ } catch (e) {
+ throw e;
+ }
+
+ requests[nativeParam.callbackId] = args.downloadRequest;
+
+ return nativeParam.callbackId;
+};
+
+DownloadManager.prototype.cancel = function(downloadId) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'downloadId', type: types_.LONG, 'nullable': false, 'optional': false}
+ ]);
+
+ var nativeParam = {
+ 'downloadId': args.downloadId
+ };
+
+ if (typeof requests[downloadId] === 'undefined')
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'the identifier does not match any download operation in progress');
+
+ try {
+ var syncResult = callNative('DownloadManager_cancel', nativeParam);
+ } catch (e) {
+ throw e;
+ }
+};
+
+DownloadManager.prototype.pause = function(downloadId) {
+ var args = validator_.validateArgs(arguments, [
+ {'name': 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
+ ]);
+
+ var nativeParam = {
+ 'downloadId': args.downloadId
+ };
+
+ if (typeof requests[downloadId] === 'undefined')
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'the identifier does not match any download operation in progress');
+
+ try {
+ var syncResult = callNative('DownloadManager_pause', nativeParam);
+ } catch (e) {
+ throw e;
+ }
+};
+
+DownloadManager.prototype.resume = function(downloadId) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
+ ]);
+
+ var nativeParam = {
+ 'downloadId': args.downloadId
+ };
+
+ if (typeof requests[downloadId] === 'undefined')
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'the identifier does not match any download operation in progress');
+
+ try {
+ var syncResult = callNative('DownloadManager_resume', nativeParam);
+ } catch (e) {
+ throw e;
+ }
+};
+
+DownloadManager.prototype.getState = function(downloadId) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
+ ]);
+
+ var nativeParam = {
+ 'downloadId': args.downloadId
+ };
+
+ if (typeof requests[downloadId] === 'undefined')
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'the identifier does not match any download operation in progress');
+
+ try {
+ var syncResult = callNative('DownloadManager_getState', nativeParam);
+ } catch (e) {
+ throw e;
+ }
+
+ return syncResult;
+};
+
+DownloadManager.prototype.getDownloadRequest = function(downloadId) {
+ var args = validator_.validateArgs(arguments, [
+ {'name': 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
+ ]);
+
+ if (typeof requests[downloadId] === 'undefined')
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'the identifier does not match any download operation in progress');
+
+ return requests[args.downloadId];
+};
+
+DownloadManager.prototype.getMIMEType = function(downloadId) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'downloadId', 'type': types_.LONG, 'nullable': false, 'optional': false}
+ ]);
+
+ var nativeParam = {
+ 'downloadId': args.downloadId
+ };
+
+ if (typeof requests[downloadId] === 'undefined')
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+ 'the identifier does not match any download operation in progress');
+
+ try {
+ var syncResult = callNative('DownloadManager_getMIMEType', nativeParam);
+ } catch (e) {
+ throw e;
+ }
+
+ return syncResult;
+};
+
+DownloadManager.prototype.setListener = function(downloadId, downloadCallback) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'downloadId', 'type': types_.LONG},
+ {'name' : 'downloadCallback', 'type': types_.LISTENER,
+ 'values' : ['onprogress', 'onpaused', 'oncanceled', 'oncompleted', 'onfailed']}
+ ]);
+
+ callbacks[args.downloadId] = args.downloadCallback;
+};
+
+
+
+exports = new DownloadManager();
+
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "download/download_instance.h"
+#include <functional>
+
+#include "common/picojson.h"
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "common/typeutil.h"
+
+
+namespace extension {
+namespace download {
+
+namespace {
+// The privileges that required in Download API
+const std::string kPrivilegeDownload = "";
+
+} // namespace
+
+using common::NotFoundException;
+using common::UnknownException;
+using common::NetworkException;
+using common::SecurityException;
+using common::QuotaExceededException;
+using common::NotSupportedException;
+using common::InvalidStateException;
+using common::IOException;
+using common::InvalidValuesException;
+using common::ServiceNotAvailableException;
+using common::TypeMismatchException;
+
+DownloadInstance::DownloadInstance() {
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+ #define REGISTER_SYNC(c, x) \
+ RegisterSyncHandler(c, std::bind(&DownloadInstance::x, this, _1, _2));
+ REGISTER_SYNC("DownloadManager_pause", DownloadManagerPause);
+ REGISTER_SYNC
+ ("DownloadManager_getDownloadRequest", DownloadManagerGetdownloadrequest);
+ REGISTER_SYNC("DownloadManager_setListener", DownloadManagerSetlistener);
+ REGISTER_SYNC("DownloadManager_getMIMEType", DownloadManagerGetmimetype);
+ REGISTER_SYNC("DownloadManager_start", DownloadManagerStart);
+ REGISTER_SYNC("DownloadManager_cancel", DownloadManagerCancel);
+ REGISTER_SYNC("DownloadManager_resume", DownloadManagerResume);
+ REGISTER_SYNC("DownloadManager_getState", DownloadManagerGetstate);
+ #undef REGISTER_SYNC
+}
+
+DownloadInstance::~DownloadInstance() {
+ for (DownloadCallbackVector::iterator it = downCbVector.begin();
+ it != downCbVector.end(); it++) {
+ delete (*it);
+ }
+}
+
+#define CHECK_EXIST(args, name, out) \
+ if (!args.contains(name)) {\
+ ReportError(TypeMismatchException(name" is required argument"), out);\
+ return;\
+ }
+
+void DownloadInstance::OnStateChanged(int download_id,
+ download_state_e state, void* user_data) {
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+
+ downCbPtr->state = state;
+ downCbPtr->downloadId = download_id;
+
+ LoggerD("State for callbackId %d changed to %d",
+ downCbPtr->callbackId, static_cast<int>(state));
+
+ switch (state) {
+ case DOWNLOAD_STATE_DOWNLOADING:
+ OnStart(download_id, user_data);
+ break;
+ case DOWNLOAD_STATE_PAUSED:
+ g_idle_add(OnPaused, downCbPtr);
+ break;
+ case DOWNLOAD_STATE_COMPLETED:
+ g_idle_add(OnFinished, downCbPtr);
+ break;
+ case DOWNLOAD_STATE_CANCELED:
+ g_idle_add(OnCanceled, downCbPtr);
+ break;
+ case DOWNLOAD_STATE_FAILED:
+ g_idle_add(OnFailed, downCbPtr);
+ break;
+ }
+}
+
+gboolean DownloadInstance::OnProgressChanged(void* user_data) {
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+ DownloadInfoPtr diPtr = downCbPtr->instance->diMap[downCbPtr->callbackId];
+
+ picojson::value::object out;
+ out["status"] = picojson::value("progress");
+ out["callbackId"] =
+ picojson::value(static_cast<double>(downCbPtr->callbackId));
+ out["receivedSize"] =
+ picojson::value(static_cast<double>(downCbPtr->received));
+ out["totalSize"] = picojson::value(static_cast<double>(diPtr->file_size));
+
+ LoggerD("OnProgressChanged for callbackId %d Called: Received: %ld",
+ downCbPtr->callbackId, downCbPtr->received);
+
+ picojson::value v = picojson::value(out);
+ downCbPtr->instance->PostMessage(v.serialize().c_str());
+
+ return FALSE;
+}
+
+void DownloadInstance::OnStart(int download_id, void* user_data) {
+ unsigned long long totalSize;
+ int ret;
+
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+
+ LoggerD("OnStart for callbackId %d Called", downCbPtr->callbackId);
+
+ DownloadInfoPtr diPtr = downCbPtr->instance->diMap[downCbPtr->callbackId];
+
+ download_get_content_size(download_id, &totalSize);
+
+ diPtr->file_size = totalSize;
+}
+
+gboolean DownloadInstance::OnFinished(void* user_data) {
+ char* fullPath = NULL;
+
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+ DownloadInfoPtr diPtr = downCbPtr->instance->diMap[downCbPtr->callbackId];
+
+ LoggerD("OnFinished for callbackID %d Called", downCbPtr->callbackId);
+
+ download_get_downloaded_file_path(downCbPtr->downloadId, &fullPath);
+
+ download_unset_state_changed_cb(diPtr->download_id);
+ download_unset_progress_cb(diPtr->download_id);
+ download_destroy(diPtr->download_id);
+
+ picojson::value::object out;
+ out["status"] = picojson::value("completed");
+ out["callbackId"] =
+ picojson::value(static_cast<double>(downCbPtr->callbackId));
+ out["fullPath"] = picojson::value(fullPath);
+
+ downCbPtr->instance->PostMessage(picojson::value(out).serialize().c_str());
+ return FALSE;
+}
+
+gboolean DownloadInstance::OnPaused(void* user_data) {
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+ DownloadInfoPtr diPtr = downCbPtr->instance->diMap[downCbPtr->callbackId];
+
+ LoggerD("OnPaused for callbackID %d Called", downCbPtr->callbackId);
+
+ picojson::value::object out;
+ out["status"] = picojson::value("paused");
+ out["callbackId"] =
+ picojson::value(static_cast<double>(downCbPtr->callbackId));
+
+ downCbPtr->instance->PostMessage(picojson::value(out).serialize().c_str());
+ return FALSE;
+}
+
+gboolean DownloadInstance::OnCanceled(void* user_data) {
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+ DownloadInfoPtr diPtr = downCbPtr->instance->diMap[downCbPtr->callbackId];
+
+ LoggerD("OnCanceled for callbackID %d Called", downCbPtr->callbackId);
+
+ download_unset_state_changed_cb(diPtr->download_id);
+ download_unset_progress_cb(diPtr->download_id);
+ download_destroy(diPtr->download_id);
+
+ picojson::value::object out;
+ out["status"] = picojson::value("canceled");
+ out["callbackId"] =
+ picojson::value(static_cast<double>(downCbPtr->callbackId));
+
+ downCbPtr->instance->PostMessage(picojson::value(out).serialize().c_str());
+ return FALSE;
+}
+
+gboolean DownloadInstance::OnFailed(void* user_data) {
+ download_error_e error;
+ picojson::object out;
+
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+ DownloadInstance* instance = downCbPtr->instance;
+
+ download_get_error(downCbPtr->downloadId, &error);
+
+ switch (error) {
+ case DOWNLOAD_ERROR_INVALID_PARAMETER:
+ instance->ReportError(NotFoundException("not found"), out);
+ break;
+ case DOWNLOAD_ERROR_OUT_OF_MEMORY:
+ instance->ReportError(UnknownException("Out of memory"), out);
+ break;
+ case DOWNLOAD_ERROR_NETWORK_UNREACHABLE:
+ instance->ReportError(NetworkException("Network is unreachable"), out);
+ break;
+ case DOWNLOAD_ERROR_CONNECTION_TIMED_OUT:
+ instance->ReportError(NetworkException("HTTP session timeout"), out);
+ break;
+ case DOWNLOAD_ERROR_NO_SPACE:
+ instance->ReportError(QuotaExceededException(
+ "No space left on device"), out);
+ break;
+ case DOWNLOAD_ERROR_PERMISSION_DENIED:
+ instance->ReportError(SecurityException(
+ "The application does not have the privilege to call this method."),
+ out);
+ break;
+ case DOWNLOAD_ERROR_NOT_SUPPORTED:
+ instance->ReportError(NotSupportedException("Not supported"), out);
+ break;
+ case DOWNLOAD_ERROR_INVALID_STATE:
+ instance->ReportError(InvalidStateException("Invalid state"), out);
+ break;
+ case DOWNLOAD_ERROR_CONNECTION_FAILED:
+ instance->ReportError(NetworkException("Connection failed"), out);
+ break;
+ case DOWNLOAD_ERROR_INVALID_URL:
+ instance->ReportError(InvalidValuesException("Invalid URL"), out);
+ break;
+ case DOWNLOAD_ERROR_INVALID_DESTINATION:
+ instance->ReportError(InvalidValuesException(
+ "Invalid destination"), out);
+ break;
+ case DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS:
+ instance->ReportError(QuotaExceededException(
+ "Too many simultaneous downloads"), out);
+ break;
+ case DOWNLOAD_ERROR_QUEUE_FULL:
+ instance->ReportError(QuotaExceededException(
+ "Download server queue is full"), out);
+ break;
+ case DOWNLOAD_ERROR_ALREADY_COMPLETED:
+ instance->ReportError(InvalidStateException(
+ "The download is already completed"), out);
+ break;
+ case DOWNLOAD_ERROR_FILE_ALREADY_EXISTS:
+ instance->ReportError(IOException(
+ "Failed to rename the downloaded file"), out);
+ break;
+ case DOWNLOAD_ERROR_CANNOT_RESUME:
+ instance->ReportError(NotSupportedException("Cannot resume"), out);
+ break;
+ case DOWNLOAD_ERROR_FIELD_NOT_FOUND:
+ instance->ReportError(NotFoundException(
+ "Specified field not found"), out);
+ break;
+ case DOWNLOAD_ERROR_TOO_MANY_REDIRECTS:
+ instance->ReportError(NetworkException(
+ "Too many redirects from HTTP response header"), out);
+ break;
+ case DOWNLOAD_ERROR_UNHANDLED_HTTP_CODE:
+ instance->ReportError(NetworkException(
+ "The download cannot handle the HTTP status value"), out);
+ break;
+ case DOWNLOAD_ERROR_REQUEST_TIMEOUT:
+ instance->ReportError(NetworkException(
+ "No action after client creates a download ID"), out);
+ break;
+ case DOWNLOAD_ERROR_RESPONSE_TIMEOUT:
+ instance->ReportError(NetworkException(
+ "No call to start API for some time although the download is created"),
+ out);
+ break;
+ case DOWNLOAD_ERROR_SYSTEM_DOWN:
+ instance->ReportError(ServiceNotAvailableException(
+ "No response from client after rebooting download daemon"), out);
+ break;
+ case DOWNLOAD_ERROR_ID_NOT_FOUND:
+ instance->ReportError(NotFoundException(
+ "Download ID does not exist in download service module"), out);
+ break;
+ case DOWNLOAD_ERROR_INVALID_NETWORK_TYPE:
+ instance->ReportError(InvalidValuesException(
+ "Network bonding is set but network type is not set as ALL"), out);
+ break;
+ case DOWNLOAD_ERROR_NO_DATA:
+ instance->ReportError(NotFoundException(
+ "No data because the set API is not called"), out);
+ break;
+ case DOWNLOAD_ERROR_IO_ERROR:
+ instance->ReportError(IOException("Internal I/O error"), out);
+ break;
+ }
+
+ out["callbackId"] =
+ picojson::value(static_cast<double>(downCbPtr->callbackId));
+
+ downCbPtr->instance->PostMessage(picojson::value(out).serialize().c_str());
+ return FALSE;
+}
+
+void DownloadInstance::progress_changed_cb
+ (int download_id, long long unsigned received, void* user_data) {
+ DownloadCallback* downCbPtr = static_cast<DownloadCallback*>(user_data);
+ downCbPtr->received = received;
+ downCbPtr->downloadId = download_id;
+
+ g_idle_add(OnProgressChanged, downCbPtr);
+}
+
+void DownloadInstance::DownloadManagerStart
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "callbackId", out)
+
+ int ret, downlodId;
+ std::string networkType;
+
+ DownloadInfoPtr diPtr(new DownloadInfo);
+
+ diPtr->callbackId = static_cast<int>(args.get("callbackId").get<double>());
+ diPtr->url = args.get("url").get<std::string>();
+
+ if (!args.get("destination").is<picojson::null>()) {
+ if (args.get("destination").get<std::string>() != "") {
+ diPtr->destination = args.get("destination").get<std::string>();
+ // need to use filesystem API
+ }
+ }
+
+ LoggerD("destination: %s", diPtr->destination.c_str());
+
+ if (!args.get("fileName").is<picojson::null>()) {
+ if (args.get("fileName").get<std::string>() != "") {
+ diPtr->file_name = args.get("fileName").get<std::string>();
+ }
+ }
+
+ if (!args.get("networkType").is<picojson::null>()) {
+ networkType = args.get("networkType").get<std::string>();
+ }
+
+ bool networkSupport;
+
+ if (networkType == "CELLULAR") {
+ system_info_get_platform_bool(
+ "http://tizen.org/feature/network.telephony", &networkSupport);
+ if (!networkSupport) {
+ ReportError(NotSupportedException(
+ "The networkType of the given DownloadRequest" \
+ "is not supported on a device."), out);
+ return;
+ }
+ diPtr->network_type = DOWNLOAD_NETWORK_DATA_NETWORK;
+ } else if (networkType == "WIFI") {
+ system_info_get_platform_bool(
+ "http://tizen.org/feature/network.wifi", &networkSupport);
+ if (!networkSupport) {
+ ReportError(NotSupportedException(
+ "The networkType of the given DownloadRequest" \
+ "is not supported on a device."), out);
+ return;
+ }
+ diPtr->network_type = DOWNLOAD_NETWORK_WIFI;
+ } else if (networkType == "ALL") {
+ diPtr->network_type = DOWNLOAD_NETWORK_ALL;
+ } else {
+ ReportError(
+ InvalidValuesException(
+ "The input parameter contains an invalid network type."), out);
+ return;
+ }
+
+ DownloadCallback* downCbPtr(new DownloadCallback);
+
+ downCbPtr->callbackId = diPtr->callbackId;
+ downCbPtr->instance = this;
+
+ downCbVector.push_back(downCbPtr);
+ LoggerD("Checking callback ID: %d", downCbPtr->callbackId);
+
+ ret = download_create(&diPtr->download_id);
+ ret =
+ download_set_state_changed_cb
+ (diPtr->download_id, OnStateChanged, static_cast<void*>(downCbPtr));
+ ret =
+ download_set_progress_cb
+ (diPtr->download_id, progress_changed_cb, static_cast<void*>(downCbPtr));
+ ret =
+ download_set_url(diPtr->download_id, diPtr->url.c_str());
+
+ const char* dest;
+
+ if (diPtr->destination == "Downloads") {
+ dest = "/opt/usr/media/Downloads"; // ret = download_set_destination(diPtr->download_id, diPtr->destination.c_str());
+ ret = download_set_destination(diPtr->download_id, dest);
+ }
+
+ if (!diPtr->file_name.empty()) {
+ ret = download_set_file_name(diPtr->download_id, diPtr->file_name.c_str());
+ }
+
+ ret = download_set_network_type(diPtr->download_id, diPtr->network_type);
+
+ if (args.get("httpHeader").is<picojson::object>()) {
+ picojson::object obj = args.get("httpHeader").get<picojson::object>();
+ for (picojson::object::const_iterator it = obj.begin();
+ it != obj.end(); ++it) {
+ download_add_http_header_field
+ (diPtr->download_id, it->first.c_str(), it->second.to_str().c_str());
+ }
+ }
+
+ char* gUrl = NULL;
+ char* gDest = NULL;
+ char* gFilename = NULL;
+ download_network_type_e gNetType;
+ char** fields;
+ char* header_value;
+ int header_length;
+
+ download_get_url(diPtr->download_id, &gUrl);
+ download_get_destination(diPtr->download_id, &gDest);
+ download_get_file_name(diPtr->download_id, &gFilename);
+ download_get_network_type(diPtr->download_id, &gNetType);
+ download_get_http_header_field_list
+ (diPtr->download_id, &fields, &header_length);
+
+ for (int i = 0; i < header_length; i++) {
+ download_get_http_header_field
+ (diPtr->download_id, fields[i], &header_value);
+ LoggerD("HTTP HEADER %d: %s - %s", i, fields[i], header_value);
+ }
+
+ LoggerD("Download Request Received" \
+ "(URL: %s, Destination: %s, File name: %s, Network type: %d ",
+ gUrl, gDest, gFilename, static_cast<int>(gNetType));
+
+ diMap[downCbPtr->callbackId] = diPtr;
+
+ ret = download_start(diPtr->download_id);
+
+ if (ret == DOWNLOAD_ERROR_NONE)
+ ReportSuccess(out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER)
+ ReportError(InvalidValuesException
+ ("The input parameter contains an invalid value."), out);
+ else if (ret == DOWNLOAD_ERROR_OUT_OF_MEMORY)
+ ReportError(UnknownException("Out of memory"), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_STATE)
+ ReportError(InvalidValuesException("Invalid state"), out);
+ else if (ret == DOWNLOAD_ERROR_IO_ERROR)
+ ReportError(UnknownException("Internal I/O error"), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_URL)
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid url."), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_DESTINATION)
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid destination."), out);
+ else if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND)
+ ReportError(InvalidValuesException("No such a download ID found"), out);
+ else if (ret == DOWNLOAD_ERROR_QUEUE_FULL)
+ ReportError(UnknownException("Download server queue is full"), out);
+ else if (ret == DOWNLOAD_ERROR_PERMISSION_DENIED)
+ ReportError(SecurityException(
+ "The application does not have the privilege to call this method."), out);
+ else
+ ReportError(UnknownException("Unknown Error"), out);
+}
+
+void DownloadInstance::DownloadManagerCancel
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "downloadId", out)
+ int downloadId, ret;
+
+ int callbackId = static_cast<int>(args.get("downloadId").get<double>());
+
+ if (!GetDownloadID(callbackId, downloadId)) {
+ ReportError(NotFoundException
+ ("The identifier does not match any download operation in progress"),
+ out);
+ return;
+ }
+
+ LoggerD("Download cancel for download ID: %d", downloadId);
+
+ ret = download_cancel(downloadId);
+
+ if (ret == DOWNLOAD_ERROR_NONE)
+ ReportSuccess(out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER)
+ ReportError(InvalidValuesException
+ ("The input parameter contains an invalid value."), out);
+ else if (ret == DOWNLOAD_ERROR_OUT_OF_MEMORY)
+ ReportError(UnknownException("Out of memory"), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_STATE)
+ ReportError(InvalidValuesException("Invalid state"), out);
+ else if (ret == DOWNLOAD_ERROR_IO_ERROR)
+ ReportError(UnknownException("Internal I/O error"), out);
+ else if (ret == DOWNLOAD_ERROR_PERMISSION_DENIED)
+ ReportError(UnknownException("Permission denied"), out);
+ else
+ ReportError(UnknownException("Unknown Error"), out);
+}
+
+void DownloadInstance::DownloadManagerPause
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "downloadId", out)
+ int downloadId, ret;
+
+ int callbackId = static_cast<int>(args.get("downloadId").get<double>());
+
+ if (!GetDownloadID(callbackId, downloadId)) {
+ ReportError(NotFoundException(
+ "The identifier does not match any download operation in progress"),
+ out);
+ return;
+ }
+
+ LoggerD("Download pause for download ID: %d", downloadId);
+
+ ret = download_pause(downloadId);
+
+ if (ret == DOWNLOAD_ERROR_NONE)
+ ReportSuccess(out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER)
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid value."), out);
+ else if (ret == DOWNLOAD_ERROR_OUT_OF_MEMORY)
+ ReportError(UnknownException("Out of memory"), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_STATE)
+ ReportError(InvalidValuesException("Invalid state"), out);
+ else if (ret == DOWNLOAD_ERROR_IO_ERROR)
+ ReportError(UnknownException("Internal I/O error"), out);
+ else if (ret == DOWNLOAD_ERROR_PERMISSION_DENIED)
+ ReportError(UnknownException("Permission denied"), out);
+ else
+ ReportError(UnknownException("Unknown Error"), out);
+}
+
+void DownloadInstance::DownloadManagerResume
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "downloadId", out)
+ int downloadId, ret;
+
+ int callbackId = static_cast<int>(args.get("downloadId").get<double>());
+
+ if (!GetDownloadID(callbackId, downloadId)) {
+ ReportError(NotFoundException
+ ("The identifier does not match any download operation in progress"),
+ out);
+ return;
+ }
+
+ LoggerD("Download resume for download ID: %d", downloadId);
+
+ ret = download_start(downloadId);
+
+ if (ret == DOWNLOAD_ERROR_NONE)
+ ReportSuccess(out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER)
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid value."), out);
+ else if (ret == DOWNLOAD_ERROR_OUT_OF_MEMORY)
+ ReportError(UnknownException("Out of memory"), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_STATE)
+ ReportError(InvalidValuesException("Invalid state"), out);
+ else if (ret == DOWNLOAD_ERROR_IO_ERROR)
+ ReportError(UnknownException("Internal I/O error"), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_URL)
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid url."), out);
+ else if (ret == DOWNLOAD_ERROR_INVALID_DESTINATION)
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid destination."), out);
+ else if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND)
+ ReportError(InvalidValuesException("No such a download ID found"), out);
+ else if (ret == DOWNLOAD_ERROR_QUEUE_FULL)
+ ReportError(UnknownException("Download server queue is full"), out);
+ else if (ret == DOWNLOAD_ERROR_PERMISSION_DENIED)
+ ReportError(SecurityException(
+ "Application does not have the privilege to call this method."), out);
+ else
+ ReportError(UnknownException("Unknown Error"), out);
+}
+void DownloadInstance::DownloadManagerGetstate
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "downloadId", out)
+ int downloadId, ret;
+ std::string stateValue;
+ download_state_e state;
+
+ int callbackId = static_cast<int>(args.get("downloadId").get<double>());
+
+ if (!GetDownloadID(callbackId, downloadId)) {
+ ReportError(NotFoundException
+ ("The identifier does not match any download operation in progress"),
+ out);
+ return;
+ }
+
+ ret = download_get_state(downloadId, &state);
+
+ if (ret == DOWNLOAD_ERROR_NONE) {
+ switch (state) {
+ case DOWNLOAD_STATE_QUEUED:
+ stateValue = "QUEUED";
+ break;
+ case DOWNLOAD_STATE_DOWNLOADING:
+ stateValue = "DOWNLOADING";
+ break;
+ case DOWNLOAD_STATE_PAUSED:
+ stateValue = "PAUSED";
+ break;
+ case DOWNLOAD_STATE_COMPLETED:
+ stateValue = "COMPLETED";
+ break;
+ case DOWNLOAD_STATE_FAILED:
+ stateValue = "FAILED";
+ break;
+ case DOWNLOAD_STATE_CANCELED:
+ stateValue = "CANCELED";
+ break;
+ }
+
+ ReportSuccess(picojson::value(stateValue), out);
+ } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid value."), out);
+ } else if (ret == DOWNLOAD_ERROR_OUT_OF_MEMORY) {
+ ReportError(UnknownException("Out of memory"), out);
+ } else if (ret == DOWNLOAD_ERROR_INVALID_STATE) {
+ ReportError(InvalidValuesException("Invalid state"), out);
+ } else if (ret == DOWNLOAD_ERROR_IO_ERROR) {
+ ReportError(UnknownException("Internal I/O error"), out);
+ } else if (ret == DOWNLOAD_ERROR_PERMISSION_DENIED) {
+ ReportError(UnknownException("Permission denied"), out);
+ } else {
+ ReportError(UnknownException("Unknown Error"), out);
+ }
+}
+
+void DownloadInstance::DownloadManagerGetmimetype
+ (const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "downloadId", out)
+
+ int downloadId, ret;
+ char* mimetype = NULL;
+
+ int callbackId = static_cast<int>(args.get("downloadId").get<double>());
+
+ if (!GetDownloadID(callbackId, downloadId)) {
+ ReportError(NotFoundException
+ ("The identifier does not match any download operation in progress"),
+ out);
+ return;
+ }
+
+ ret = download_get_mime_type(downloadId, &mimetype);
+
+ if (ret == DOWNLOAD_ERROR_NONE) {
+ LoggerD("MIMEtype for callbackID %d : %s", callbackId, mimetype);
+ ReportSuccess(picojson::value(mimetype), out);
+ } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
+ ReportError(InvalidValuesException(
+ "The input parameter contains an invalid value."), out);
+ } else if (ret == DOWNLOAD_ERROR_OUT_OF_MEMORY) {
+ ReportError(UnknownException("Out of memory"), out);
+ } else if (ret == DOWNLOAD_ERROR_INVALID_STATE) {
+ ReportError(InvalidValuesException("Invalid state"), out);
+ } else if (ret == DOWNLOAD_ERROR_IO_ERROR) {
+ ReportError(UnknownException("Internal I/O error"), out);
+ } else if (ret == DOWNLOAD_ERROR_PERMISSION_DENIED) {
+ ReportError(UnknownException("Permission denied"), out);
+ } else {
+ ReportError(UnknownException("Unknown Error"), out);
+ }
+}
+
+bool DownloadInstance::GetDownloadID
+ (const int callback_id, int& download_id) {
+
+ if (diMap.find(callback_id) != diMap.end()) {
+ download_id = diMap.find(callback_id)->second->download_id;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+void DownloadInstance::DownloadManagerGetdownloadrequest
+ (const picojson::value& args, picojson::object& out) {
+ // Nothing to do
+}
+
+void DownloadInstance::DownloadManagerSetlistener
+ (const picojson::value& args, picojson::object& out) {
+ // Nothing to do
+}
+
+
+#undef CHECK_EXIST
+
+} // namespace download
+} // namespace extension