From: Arkadiusz Pietraszek Date: Wed, 22 May 2019 13:00:41 +0000 (+0200) Subject: [download] Download module exception correction X-Git-Tag: accepted/tizen/unified/20190920.065316~8^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=678c7e4e5e0a360adb2f1db09a10ad2fb98e94fd;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [download] Download module exception correction NotFoundError and TypeMismatchError exceptions removed from methods: void cancel(long); void pause(long); void resume(long); Change that enables resuming canceled or failed download job. abandon() method added, to destroy download job, abandoned download can not be resumed. ABANDONED state added to differentiate from CANCELED, which can be resumed. [Verification] Download TCT pass rate is 100%. New behaviour was tested manually from console. ACR: http://suprem.sec.samsung.net/jira/browse/TWDAPI-222 Change-Id: I52f5e7fa1875f49354178b8979c92e0d20011bc2 Signed-off-by: Arkadiusz Pietraszek --- diff --git a/src/download/download_api.js b/src/download/download_api.js index 20536ea..2abd9a8 100755 --- a/src/download/download_api.js +++ b/src/download/download_api.js @@ -47,7 +47,6 @@ function DownloadManagerChangeCallback(result) { } else if (result.status == 'canceled') { if (callback.oncanceled) { callback.oncanceled(result.downloadId); - delete callbacks[result.downloadId]; } } else if (result.status == 'completed') { if (callback.oncompleted) { @@ -58,7 +57,6 @@ function DownloadManagerChangeCallback(result) { } else if (result.status == 'error') { if (callback.onfailed) { callback.onfailed(result.downloadId, new WebAPIException(result.error)); - delete callbacks[result.downloadId]; } } }, 0); @@ -78,7 +76,8 @@ var DownloadState = { PAUSED: 'PAUSED', CANCELED: 'CANCELED', COMPLETED: 'COMPLETED', - FAILED: 'FAILED' + FAILED: 'FAILED', + ABANDONED: 'ABANDONED' }; var DownloadNetworkType = { @@ -246,6 +245,30 @@ DownloadManager.prototype.pause = function() { } }; +DownloadManager.prototype.abandon = function() { + var args = validator_.validateArgs(arguments, [ + { name: 'downloadId', type: types_.LONG, nullable: false, optional: false } + ]); + + var nativeParam = { + downloadId: args.downloadId + }; + + if (typeof requests[args.downloadId] === 'undefined') + throw new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, + 'the identifier does not match any download operation in progress' + ); + + var result = native_.callSync('DownloadManager_abandon', nativeParam); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + delete callbacks[args.downloadId]; +}; + DownloadManager.prototype.resume = function() { var args = validator_.validateArgs(arguments, [ { name: 'downloadId', type: types_.LONG, nullable: false, optional: false } diff --git a/src/download/download_instance.cc b/src/download/download_instance.cc index 56ca85e..02bd21b 100644 --- a/src/download/download_instance.cc +++ b/src/download/download_instance.cc @@ -45,10 +45,11 @@ 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_getMIMEType", DownloadManagerGetmimetype); REGISTER_SYNC("DownloadManager_start", DownloadManagerStart); REGISTER_SYNC("DownloadManager_cancel", DownloadManagerCancel); + REGISTER_SYNC("DownloadManager_pause", DownloadManagerPause); + REGISTER_SYNC("DownloadManager_abandon", DownloadManagerAbandon); REGISTER_SYNC("DownloadManager_resume", DownloadManagerResume); REGISTER_SYNC("DownloadManager_getState", DownloadManagerGetstate); #undef REGISTER_SYNC @@ -393,11 +394,6 @@ gboolean DownloadInstance::OnCanceled(void* user_data) { LoggerE("%s", get_error_message(ret)); } - ret = download_destroy(di_ptr->native_download_id); - if (ret != DOWNLOAD_ERROR_NONE) { - LoggerE("%s", get_error_message(ret)); - } - picojson::value::object out; out["status"] = picojson::value("canceled"); out["downloadId"] = picojson::value(static_cast(download_id)); @@ -454,11 +450,6 @@ gboolean DownloadInstance::OnFailed(void* user_data) { LoggerE("%s", get_error_message(ret)); } - ret = download_destroy(di_ptr->native_download_id); - if (DOWNLOAD_ERROR_NONE != ret) { - LoggerE("%s", get_error_message(ret)); - } - out["downloadId"] = picojson::value(static_cast(down_cb_ptr->download_id)); out["listenerId"] = picojson::value(kDownloadManagerListenerId); @@ -715,9 +706,9 @@ void DownloadInstance::DownloadManagerCancel(const picojson::value& args, picojs if (!GetDownloadID(callbackId, downloadId)) { LogAndReportError( - common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR, + common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "The identifier does not match any download operation in progress"), - &out, ("The identifier %d does not match any download operation in progress", downloadId)); + &out, ("downloadId: %d, found in WEB Api but missing in native API", callbackId)); return; } @@ -740,9 +731,9 @@ void DownloadInstance::DownloadManagerPause(const picojson::value& args, picojso if (!GetDownloadID(callbackId, downloadId)) { LogAndReportError( - common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR, + common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "The identifier does not match any download operation in progress"), - &out, ("The identifier %d does not match any download operation in progress", downloadId)); + &out, ("downloadId: %d, found in WEB Api but missing in native API", downloadId)); return; } @@ -756,22 +747,90 @@ void DownloadInstance::DownloadManagerPause(const picojson::value& args, picojso } } +void DownloadInstance::DownloadManagerAbandon(const picojson::value& args, picojson::object& out) { + ScopeLogger(); + CHECK_EXIST(args, "downloadId", out) + int callbackId, nativeDownloadId, ret; + callbackId = static_cast(args.get("downloadId").get()); + + if (!GetDownloadID(callbackId, nativeDownloadId)) { + LogAndReportError( + common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, + "The identifier does not match any download operation in progress"), + &out, ("downloadId: %d, found in WEB Api but missing in native API", callbackId)); + return; + } + + ret = download_destroy(nativeDownloadId); + if (ret == DOWNLOAD_ERROR_NONE) { + if (di_map.find(callbackId) != di_map.end()) { + di_map.find(callbackId)->second->abandoned = true; + } + ReportSuccess(out); + } else { + LogAndReportError(convertError(ret), &out, + ("download_destroy error: %d (%s)", ret, get_error_message(ret))); + } +} + void DownloadInstance::DownloadManagerResume(const picojson::value& args, picojson::object& out) { ScopeLogger(); CHECK_EXIST(args, "downloadId", out) - int downloadId, ret; + int nativeDownloadId, ret; int callbackId = static_cast(args.get("downloadId").get()); - if (!GetDownloadID(callbackId, downloadId)) { + if ((di_map.end() != di_map.find(callbackId)) && (di_map.find(callbackId)->second->abandoned)) { LogAndReportError( - common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR, + common::PlatformResult(common::ErrorCode::INVALID_VALUES_ERR, + "The download operation with given identifier has been abandoned " + "and can not be resumed"), + &out, + ("The download operation with identifier: %d has been abandoned and can not be resumed", + callbackId)); + return; + } + + if (!GetDownloadID(callbackId, nativeDownloadId)) { + LogAndReportError( + common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "The identifier does not match any download operation in progress"), - &out, ("The identifier %d does not match any download operation in progress", downloadId)); + &out, ("downloadId: %d, found in WEB Api but missing in native API", callbackId)); + return; + } + + download_state_e state; + ret = download_get_state(nativeDownloadId, &state); + + if (ret == DOWNLOAD_ERROR_NONE) { + switch (state) { + case DOWNLOAD_STATE_QUEUED: + case DOWNLOAD_STATE_DOWNLOADING: + case DOWNLOAD_STATE_COMPLETED: + ReportSuccess(out); + return; + default: + LoggerD("Download state: %d", state); + } + } + + ret = download_set_state_changed_cb(nativeDownloadId, OnStateChanged, + static_cast(download_callbacks[callbackId])); + if (ret != DOWNLOAD_ERROR_NONE) { + LogAndReportError(convertError(ret), &out, ("download_set_state_changed_cb error: %d (%s)", ret, + get_error_message(ret))); + return; + } + + ret = download_set_progress_cb(nativeDownloadId, progress_changed_cb, + static_cast(download_callbacks[callbackId])); + if (ret != DOWNLOAD_ERROR_NONE) { + LogAndReportError(convertError(ret), &out, + ("download_set_progress_cb error: %d (%s)", ret, get_error_message(ret))); return; } - ret = download_start(downloadId); + ret = download_start(nativeDownloadId); if (ret == DOWNLOAD_ERROR_NONE) { ReportSuccess(out); @@ -790,6 +849,12 @@ void DownloadInstance::DownloadManagerGetstate(const picojson::value& args, pico int callbackId = static_cast(args.get("downloadId").get()); + if (di_map.find(callbackId)->second->abandoned) { + stateValue = "ABANDONED"; + ReportSuccess(picojson::value(stateValue), out); + return; + } + if (!GetDownloadID(callbackId, downloadId)) { LogAndReportError( common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR, diff --git a/src/download/download_instance.h b/src/download/download_instance.h index 947e2ad..7b4d772 100644 --- a/src/download/download_instance.h +++ b/src/download/download_instance.h @@ -55,6 +55,7 @@ class DownloadInstance : public common::ParsedInstance { int native_download_id; long long unsigned file_size; + bool abandoned = false; }; struct DownloadCallback { @@ -76,6 +77,7 @@ class DownloadInstance : public common::ParsedInstance { void DownloadManagerStart(const picojson::value& args, picojson::object& out); void DownloadManagerCancel(const picojson::value& args, picojson::object& out); void DownloadManagerPause(const picojson::value& args, picojson::object& out); + void DownloadManagerAbandon(const picojson::value& args, picojson::object& out); void DownloadManagerResume(const picojson::value& args, picojson::object& out); void DownloadManagerGetstate(const picojson::value& args, picojson::object& out); void DownloadManagerGetmimetype(const picojson::value& args, picojson::object& out);