diff options
Diffstat (limited to 'src')
25 files changed, 5797 insertions, 0 deletions
diff --git a/src/download-provider-dateTime.cpp b/src/download-provider-dateTime.cpp new file mode 100644 index 0000000..8f6edd3 --- /dev/null +++ b/src/download-provider-dateTime.cpp @@ -0,0 +1,218 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-dateTime.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief data and utility APIs for Date and Time + */ + +#include "runtime_info.h" +#include "download-provider-dateTime.h" + +#define MAX_SKELETON_BUFFER_LEN 8 +#define MAX_PATTERN_BUFFER_LEN 128 + +DateGroup::DateGroup() + : count(0) + , type(DATETIME::DATE_TYPE_NONE) + , m_glGroupItem(NULL) +{ +} + +DateGroup::~DateGroup() +{ +} + +void DateGroup::initData() +{ + count = 0; + m_glGroupItem = NULL; +} + +DateUtil::DateUtil() + : m_todayStandardTime(0) + , dateShortFormat(NULL) + , dateMediumFormat(NULL) + , dateFullFormat(NULL) + , timeFormat12H(NULL) + , timeFormat24H(NULL) +{ +} + +DateUtil::~DateUtil() +{ + deinitLocaleData(); +} + +void DateUtil::deinitLocaleData() +{ + if (dateShortFormat) + udat_close(dateShortFormat); + if (dateMediumFormat) + udat_close(dateMediumFormat); + if (dateFullFormat) + udat_close(dateFullFormat); + if (timeFormat12H) + udat_close(timeFormat12H); + if (timeFormat24H) + udat_close(timeFormat24H); + dateShortFormat = NULL; + dateMediumFormat = NULL; + dateFullFormat = NULL; + timeFormat12H = NULL; + timeFormat24H = NULL; +} + +int DateUtil::getDiffDaysFromToday() +{ + time_t now = time(NULL); + DP_LOGD("todayStandardTime[%ld]", m_todayStandardTime); + if (m_todayStandardTime == 0) + return 0; + else + return getDiffDays(now, m_todayStandardTime); +} + +int DateUtil::getDiffDays(time_t nowTime,time_t refTime) +{ + int diffDays = 0; + int nowYear = 0; + int nowYday = 0; + int refYday = 0; + int refYear = 0; + struct tm *nowDate = localtime(&nowTime); + nowYday = nowDate->tm_yday; + nowYear = nowDate->tm_year; + struct tm *finishedDate = localtime(&refTime); + refYday = finishedDate->tm_yday; + refYear = finishedDate->tm_year; + diffDays = nowYday - refYday; + /*DP_LOGD("refDate[%d/%d/%d]refTime[%ld]yday[%d]", + (finishedDate->tm_year + 1900), (finishedDate->tm_mon + 1), + finishedDate->tm_mday, refTime, refYday);*/ + if ((nowYear-refYear)>0 && diffDays < 0) { + int year = nowDate->tm_year; + diffDays = diffDays + 365; + /* leap year */ + if ((year%4 == 0 && year%100 != 0) || year%400 == 0) + diffDays++; + } + DP_LOGD("diffDays[%d]",diffDays); + return diffDays; +} + +UDateFormat *DateUtil::getBestPattern(const char *patternStr, + UDateTimePatternGenerator *generator, const char *locale) +{ + UDateFormat *format = NULL; + UChar customSkeleton[MAX_SKELETON_BUFFER_LEN] = {0,}; + UChar bestPattern[MAX_PATTERN_BUFFER_LEN] = {0,}; + UErrorCode status = U_ZERO_ERROR; + int32_t patternLen = 0; + + if (patternStr) { + u_uastrncpy(customSkeleton, patternStr, strlen(patternStr)); + patternLen = udatpg_getBestPattern(generator, customSkeleton, + u_strlen(customSkeleton), bestPattern, MAX_PATTERN_BUFFER_LEN, + &status); + DP_LOGD("udatpg_getBestPattern status[%d] bestPattern[%s]", status, + bestPattern); + if (patternLen < 1) { + format = udat_open(UDAT_SHORT, UDAT_NONE, locale, NULL, -1, + NULL, -1, &status); + return format; + } + } + format = udat_open(UDAT_IGNORE, UDAT_NONE, locale, NULL, -1, + bestPattern, -1, &status); + return format; +} + +void DateUtil::updateLocale() +{ + UDateTimePatternGenerator *generator = NULL; + UErrorCode status = U_ZERO_ERROR; + const char *locale = NULL; + + DP_LOGD_FUNC(); + + deinitLocaleData(); + + uloc_setDefault(getenv("LC_TIME"), &status); + DP_LOGD("uloc_setDefault status[%d]",status); + + locale = uloc_getDefault(); + generator = udatpg_open(locale,&status); + DP_LOGD("udatpg_open status[%d]",status); + + timeFormat12H = getBestPattern("hm", generator, locale); + timeFormat24H = getBestPattern("Hm", generator, locale); + + dateShortFormat = udat_open(UDAT_NONE, UDAT_SHORT, locale, NULL, -1, NULL, + -1, &status); + dateMediumFormat = udat_open(UDAT_NONE, UDAT_MEDIUM, locale, NULL, -1, NULL, + -1, &status); + dateFullFormat = getBestPattern("yMMMEEEd", generator, locale); + udatpg_close(generator); +} + +void DateUtil::getDateStr(int style, double time, string &outBuf) +{ + UDateFormat *format = NULL; + UErrorCode status = U_ZERO_ERROR; + UChar str[MAX_BUF_LEN] = {0,}; + bool value = false; + + DP_LOGD_FUNC(); + switch (style) { + case LOCALE_STYLE::TIME: + if (runtime_info_get_value_bool( + RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED,&value) != 0) { + DP_LOGE("runtime_info_get_value_bool is failed"); + format = timeFormat12H; + } else { + if (value) + format = timeFormat24H; + else + format = timeFormat12H; + } + break; + case LOCALE_STYLE::SHORT_DATE: + format = dateShortFormat; + break; + case LOCALE_STYLE::MEDIUM_DATE: + format = dateMediumFormat; + break; + case LOCALE_STYLE::FULL_DATE: + format = dateFullFormat; + break; + default : + DP_LOGE("Critical: cannot enter here"); + format = timeFormat12H; + } + if (format) { + char tempBuf[MAX_BUF_LEN] = {0,}; + udat_format(format, time, str, MAX_BUF_LEN - 1, NULL, &status); + DP_LOGD("udat_format : status[%d]", status); + u_austrncpy(tempBuf, str, MAX_BUF_LEN-1); + outBuf = string(tempBuf); + } else { + DP_LOGE("Critical: fail to get time value"); + outBuf = string(S_("IDS_COM_POP_ERROR")); + } +} + diff --git a/src/download-provider-downloadItem.cpp b/src/download-provider-downloadItem.cpp new file mode 100644 index 0000000..de3df50 --- /dev/null +++ b/src/download-provider-downloadItem.cpp @@ -0,0 +1,493 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-downloadItem.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief download item class for interface of download agent + */ + +#include "download-provider-downloadItem.h" + +#include "download-provider-common.h" +#include <Ecore.h> +#include <iostream> + +/* Download Agent CallBacks */ +static void __notify_cb(user_notify_info_t *notify_info, void *user_data); +static void __update_download_info_cb(user_download_info_t *download_info, void *user_data); +static void __get_dd_info_cb(user_dd_info_t *dd_info, void *user_data); + +static Ecore_Pipe *ecore_pipe = NULL; +static void __ecore_cb_pipe_update(void *data, void *buffer, unsigned int nbyte); + +namespace DA_CB { +enum TYPE { + NOTIFY = 1, + UPDATE, + DD_INFO +}; +} + +class CbData { +public: + CbData() {} + ~CbData() {} + + void updateDownloadItem(); + + inline void setType(DA_CB::TYPE type) { m_type = type; } + inline void setUserData(void *userData) { m_userData = userData; } + inline void setDownloadId(int id) { m_da_req_id = id; } + inline void setReceivedFileSize(unsigned long int size) { m_receivedFileSize = size; } + inline void setFileSize(unsigned long int size) { m_fileSize = size; } + inline void setFilePath(const char *path) { if (path) m_filePath = path; } + inline void setRegisteredFilePath(const char *path) { if (path) m_registeredFilePath = path; } + inline void setMimeType(const char *mime) { m_mimeType = mime; } + inline void setState(da_state state) { m_da_state = state; } + inline void setErrorCode(int err) { m_da_error = err; } + inline void setIsMidletInstalled(bool b) { m_isMidletInstalled = b; } + inline void setIsJad(bool b) { m_isJad = b;} + inline void setContentName(const char *name) { m_contentName = name; } + inline void setVendorName(const char *name) { m_vendorName = name; } + +private: + DA_CB::TYPE m_type; + void *m_userData; + da_handle_t m_da_req_id; + da_state m_da_state; + int m_da_error; + unsigned long int m_receivedFileSize; + unsigned long int m_fileSize; + string m_filePath; + string m_registeredFilePath; + string m_mimeType; + bool m_isMidletInstalled; + bool m_isJad; + string m_contentName; + string m_vendorName; +}; + +struct pipe_data_t { + CbData *cbData; +}; + +DownloadEngine::DownloadEngine() +{ +} + +DownloadEngine::~DownloadEngine() +{ + DP_LOG_FUNC(); +} + +void DownloadEngine::initEngine(void) +{ + da_client_cb_t da_cb = { + __notify_cb, /* da_notify_cb */ + __get_dd_info_cb, /* da_send_dd_info_cb */ + __update_download_info_cb, /* da_update_download_info_cb */ + NULL /* da_go_to_next_url_cb */ + }; + + int da_ret = da_init(&da_cb, DA_DOWNLOAD_MANAGING_METHOD_AUTO); + if (DA_RESULT_OK == da_ret) { + ecore_pipe = ecore_pipe_add(__ecore_cb_pipe_update, NULL); + } +} + +void DownloadEngine::deinitEngine(void) +{ + da_deinit(); + if (ecore_pipe) { + ecore_pipe_del(ecore_pipe); + ecore_pipe = NULL; + } +} + +void CbData::updateDownloadItem() +{ +// DP_LOGD_FUNC(); + + if (!m_userData) { + DP_LOGE("download item is NULL"); + return; + } + + + DownloadItem *downloadItem = static_cast<DownloadItem*>(m_userData); + if (downloadItem->state() == DL_ITEM::FAILED) { + DP_LOGE("download item is already failed"); + return; + } + + switch(m_type) { + case DA_CB::NOTIFY: + { + DP_LOGD("DA_CB::NOTIFY"); + downloadItem->setDownloadId(m_da_req_id); + DL_ITEM::STATE dl_state = downloadItem->_convert_da_state_to_download_state(m_da_state); + DP_LOG("DL_ITEM::STATE [%d]", dl_state); + //if (dl_state != DL_ITEM::IGNORE) + if (dl_state == DL_ITEM::IGNORE) + return; + downloadItem->setState(dl_state); + + if (dl_state == DL_ITEM::FAILED) + downloadItem->setErrorCode(downloadItem->_convert_da_error(m_da_error)); + } + break; + + case DA_CB::UPDATE: + DP_LOGD("DA_CB::UPDATE"); + DP_LOGD("DA_CB::UPDATE state[%d] receivedFileSize[%d]", downloadItem->state(), m_receivedFileSize); +// downloadItem->setDownloadId(m_da_req_id); + downloadItem->setState(DL_ITEM::UPDATING); + downloadItem->setReceivedFileSize(m_receivedFileSize); + downloadItem->setFileSize(m_fileSize); + + if (!m_mimeType.empty()) + downloadItem->setMimeType(m_mimeType); + + if (!m_filePath.empty()) + downloadItem->setFilePath(m_filePath); + + if (!m_registeredFilePath.empty()) { + DP_LOGD("registeredFilePath[%s]", m_registeredFilePath.c_str()); + downloadItem->setRegisteredFilePath(m_registeredFilePath); + } + break; + + case DA_CB::DD_INFO: + DP_LOG("DA_CB::DD_INFO"); + downloadItem->setDownloadId(m_da_req_id); + downloadItem->setFileSize(m_fileSize); + downloadItem->setIsMidletInstalled(m_isMidletInstalled); + if (m_isJad) + downloadItem->setDownloadType(DL_TYPE::MIDP_DOWNLOAD); + else + downloadItem->setDownloadType(DL_TYPE::OMA_DOWNLOAD); + downloadItem->setContentName(m_contentName); + downloadItem->setVendorName(m_vendorName); + downloadItem->setState(DL_ITEM::WAITING_CONFIRM); + break; + + default: + break; + } + + downloadItem->notify(); +} + +void __ecore_cb_pipe_update(void *data, void *buffer, unsigned int nbyte) +{ +// DP_LOGD_FUNC(); + + if (!buffer) + return; + pipe_data_t *pipe_data = static_cast<pipe_data_t *>(buffer); + CbData *cbData = pipe_data->cbData; + if (!cbData) + return; + + cbData->updateDownloadItem(); + delete cbData; +} + +void __notify_cb(user_notify_info_t *notify_info, void* user_data) +{ + DP_LOGD_FUNC(); + + if (!notify_info || !user_data) + return; + + DP_LOGD("__notify_cb: id[%d] state[%d] err[%d]", notify_info->da_dl_req_id, notify_info->state, notify_info->err); + + CbData *cbData = new CbData(); + cbData->setType(DA_CB::NOTIFY); + cbData->setDownloadId(notify_info->da_dl_req_id); + cbData->setUserData(user_data); + cbData->setState(notify_info->state); + cbData->setErrorCode(notify_info->err); + + pipe_data_t pipe_data; + pipe_data.cbData = cbData; + ecore_pipe_write(ecore_pipe, &pipe_data, sizeof(pipe_data_t)); +} + +void __update_download_info_cb(user_download_info_t *download_info, void *user_data) +{ +// DP_LOGD_FUNC(); + + if (!download_info || !user_data) + return; + + CbData *cbData = new CbData(); + cbData->setType(DA_CB::UPDATE); + cbData->setDownloadId(download_info->da_dl_req_id); + cbData->setUserData(user_data); + cbData->setFileSize(download_info->file_size); + cbData->setReceivedFileSize(download_info->total_received_size); + +// DP_LOGD("tmp path [%s] path [%s] type [%s]", download_info->tmp_saved_path, download_info->saved_path, download_info->file_type); + DownloadItem *item = static_cast<DownloadItem*>(user_data); + if(download_info->file_type && item->mimeType().empty()) + cbData->setMimeType(download_info->file_type); + + if(download_info->tmp_saved_path && item->filePath().empty()) + cbData->setFilePath(download_info->tmp_saved_path); + + if(download_info->saved_path && item->registeredFilePath().empty()) + cbData->setRegisteredFilePath(download_info->saved_path); + + pipe_data_t pipe_data; + pipe_data.cbData = cbData; + ecore_pipe_write(ecore_pipe, &pipe_data, sizeof(pipe_data_t)); +} + +void __get_dd_info_cb(user_dd_info_t *dd_info, void *user_data) +{ + DP_LOGD_FUNC(); + + if (!dd_info || !user_data) + return; + + CbData *cbData = new CbData(); + cbData->setType(DA_CB::DD_INFO); + cbData->setDownloadId(dd_info->da_dl_req_id); + cbData->setUserData(user_data); + cbData->setIsMidletInstalled(dd_info->is_installed); + cbData->setIsJad(dd_info->is_jad); + cbData->setFileSize(dd_info->size); + + if (dd_info->name) + cbData->setContentName(dd_info->name); + if (dd_info->vendor) + cbData->setVendorName(dd_info->vendor); + if (dd_info->type) + cbData->setMimeType(dd_info->type); + + pipe_data_t pipe_data; + pipe_data.cbData = cbData; + ecore_pipe_write(ecore_pipe, &pipe_data, sizeof(pipe_data_t)); +} + +DownloadItem::DownloadItem() + : m_da_req_id(DA_INVALID_ID) + , m_state(DL_ITEM::IGNORE) + , m_errorCode(ERROR::NONE) + , m_receivedFileSize(0) + , m_fileSize(0) + , m_downloadType(DL_TYPE::HTTP_DOWNLOAD) + , m_isMidletInstalled(false) +{ +} + +DownloadItem::DownloadItem(auto_ptr<DownloadRequest> request) + : m_aptr_request(request) + , m_da_req_id(DA_INVALID_ID) + , m_state(DL_ITEM::IGNORE) + , m_errorCode(ERROR::NONE) + , m_receivedFileSize(0) + , m_fileSize(0) + , m_downloadType(DL_TYPE::HTTP_DOWNLOAD) + , m_isMidletInstalled(false) +{ +} + +DownloadItem::~DownloadItem() +{ + DP_LOGD_FUNC(); +} + +void DownloadItem::start(void) +{ + int da_ret = 0; + DP_LOGD_FUNC(); + + if (m_aptr_request->getCookie().empty()) { + da_ret = da_start_download_with_extension( + m_aptr_request->getUrl().c_str(), + &m_da_req_id, + DA_FEATURE_USER_DATA, + static_cast<void*>(this), + NULL); + } else { + char *requestHeader[1] = {NULL,}; + int reqHeaderCount = 1; + string reqHeaderStr = string("Cookie:"); + reqHeaderStr.append(m_aptr_request->getCookie().c_str()); + requestHeader[0] = strdup(reqHeaderStr.c_str()); + da_ret = da_start_download_with_extension( + m_aptr_request->getUrl().c_str(), + &m_da_req_id, + DA_FEATURE_REQUEST_HEADER, + requestHeader, + &reqHeaderCount, + DA_FEATURE_USER_DATA, + static_cast<void*>(this), + NULL); + if (requestHeader[0]) { + free(requestHeader[0]); + requestHeader[0] = NULL; + } + } + if (da_ret != DA_RESULT_OK) { + m_state = DL_ITEM::FAILED; + m_errorCode = ERROR::ENGINE_FAIL; + notify(); + } +} + +DL_ITEM::STATE DownloadItem::_convert_da_state_to_download_state(int da_state) +{ + switch (da_state) { + case DA_STATE_DOWNLOAD_STARTED: + return DL_ITEM::STARTED; +// case DA_STATE_DOWNLOADING: +// return DL_ITEM::UPDATING; + case DA_STATE_DOWNLOAD_COMPLETE: + return DL_ITEM::COMPLETE_DOWNLOAD; + case DA_STATE_WAITING_USER_CONFIRM: + return DL_ITEM::WAITING_CONFIRM; + case DA_STATE_START_INSTALL_NOTIFY: + return DL_ITEM::INSTALL_NOTIFY; + case DA_STATE_DRM_JOIN_LEAVE_DOMAIN_START: + return DL_ITEM::START_DRM_DOMAIN; + case DA_STATE_DRM_JOIN_LEAVE_DOMAIN_FINISH: + return DL_ITEM::FINISH_DRM_DOMAIN; + case DA_STATE_WAITING_RO: + return DL_ITEM::WAITING_RO; + case DA_STATE_SUSPENDED: + return DL_ITEM::SUSPENDED; + case DA_STATE_RESUMED: + return DL_ITEM::RESUMED; + case DA_STATE_CANCELED: + return DL_ITEM::CANCELED; + case DA_STATE_FINISHED: + return DL_ITEM::FINISHED; + case DA_STATE_FAILED: + return DL_ITEM::FAILED; + case DA_STATE_DOWNLOADING: + case DA_STATE_DONE_INSTALL_NOTIFY: + case DA_STATE_DRM_ROAP_START: + case DA_STATE_DRM_ROAP_FINISH: + default: + return DL_ITEM::IGNORE; + } +} + +ERROR::CODE DownloadItem::_convert_da_error(int da_err) +{ + DP_LOGD("download agent error[%d]", da_err); + + switch (da_err) { + case DA_ERR_NETWORK_FAIL: + case DA_ERR_HTTP_TIMEOUT: + case DA_ERR_UNREACHABLE_SERVER : + return ERROR::NETWORK_FAIL; + + case DA_ERR_INVALID_URL: + return ERROR::INVALID_URL; + + case DA_ERR_DISK_FULL: + return ERROR::NOT_ENOUGH_MEMORY; + + case DA_ERR_FAIL_TO_INSTALL_FILE: + case DA_ERR_DLOPEN_FAIL: + return ERROR::FAIL_TO_INSTALL; + + case DA_ERR_USER_RESPONSE_WAITING_TIME_OUT: + return ERROR::OMA_POPUP_TIME_OUT; + + case DA_ERR_PARSE_FAIL: + return ERROR::FAIL_TO_PARSE_DESCRIPTOR; + + default : + return ERROR::UNKNOWN; + } + +} + +void DownloadItem::cancel() +{ + DP_LOGD("DownloadItem::cancel"); + if (m_state == DL_ITEM::CANCELED) { + DP_LOGD("It is already canceled"); + notify(); + return; + } + int da_ret = da_cancel_download(m_da_req_id); + if (da_ret != DA_RESULT_OK) { + DP_LOGE("Fail to cancel download : reqId[%d] reason[%d]", + m_da_req_id, da_ret); + m_state = DL_ITEM::FAILED; + m_errorCode = ERROR::ENGINE_FAIL; + notify(); + } + return; +} + +void DownloadItem::retry() +{ + DP_LOGD_FUNC(); + m_da_req_id = DA_INVALID_ID; + m_state = DL_ITEM::IGNORE; + m_errorCode = ERROR::NONE; + m_receivedFileSize = 0; + m_fileSize = 0; + m_downloadType = DL_TYPE::HTTP_DOWNLOAD; + m_isMidletInstalled = false; + start(); +} + +bool DownloadItem::sendUserResponse(bool res) +{ + int da_ret = da_send_back_user_confirm(m_da_req_id, res); + if (da_ret != DA_RESULT_OK) { + DP_LOGE("Fail to send back user confirm : reqId[%d] reason[%d]", + m_da_req_id, da_ret); + m_state = DL_ITEM::FAILED; + m_errorCode = ERROR::ENGINE_FAIL; + notify(); + return false; + } + return true; +} + +void DownloadItem::suspend() +{ + int da_ret = DA_RESULT_OK; + da_ret = da_suspend_download(m_da_req_id); + if (da_ret != DA_RESULT_OK) { + DP_LOGE("Fail to suspend download : reqId[%d] err[%d]", m_da_req_id, da_ret); + m_state = DL_ITEM::FAILED; + m_errorCode = ERROR::ENGINE_FAIL; + notify(); + } +} + +void DownloadItem::resume() +{ + int da_ret = DA_RESULT_OK; + da_ret = da_resume_download(m_da_req_id); + if (da_ret != DA_RESULT_OK) { + DP_LOGE("Fail to resume download : reqId[%d] err[%d]", m_da_req_id, da_ret); + m_state = DL_ITEM::FAILED; + m_errorCode = ERROR::ENGINE_FAIL; + notify(); + } +} diff --git a/src/download-provider-downloadRequest.cpp b/src/download-provider-downloadRequest.cpp new file mode 100644 index 0000000..4c1608c --- /dev/null +++ b/src/download-provider-downloadRequest.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provier-downloadRequest.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief download request data class + */ +#include "download-provider-downloadRequest.h" + +/*DownloadRequest::DownloadRequest() + : m_url(NULL) + , m_cookie(NULL) +{ +}*/ + +DownloadRequest::DownloadRequest(string url, string cookie) + : m_url(url) + , m_cookie(cookie) +{ +} + +DownloadRequest::DownloadRequest(DownloadRequest &rRequest) +{ + m_url.assign(rRequest.getUrl()); + m_cookie.assign(rRequest.getCookie()); +} + +DownloadRequest::~DownloadRequest() +{ +// DP_LOG_FUNC(); +} + +string &DownloadRequest::getUrl() +{ + return m_url; +} + +string &DownloadRequest::getCookie() +{ + return m_cookie; +} + +bool DownloadRequest::isUrlEmpty() +{ + return m_url.empty(); +} + +bool DownloadRequest::isCookieEmpty() +{ + return m_cookie.empty(); +} + +void DownloadRequest::setUrl(string url) +{ + m_url.assign(url); +} + +void DownloadRequest::setCookie(string cookie) +{ + m_cookie.assign(cookie); +} diff --git a/src/download-provider-event.cpp b/src/download-provider-event.cpp new file mode 100644 index 0000000..1484727 --- /dev/null +++ b/src/download-provider-event.cpp @@ -0,0 +1,91 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-event.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief download event class for event flow + */ +#include "download-provider-event.h" +#include "download-provider-common.h" + +#include <iostream> + +void Subject::attach(Observer *o) +{ + _observers.push_back(o); +} + +void Subject::detach(Observer *o) +{ + vector<Observer*>::iterator it; + for(it = _observers.begin() ; it < _observers.end() ; it++) { + if (*it == o) { + _observers.erase(it); + break; + } + } +} + +void Subject::notify(void) +{ + vector<Observer*>::iterator it; + Observer *curObserver; + it = _observers.begin(); + while (it < _observers.end()) { + curObserver = *it; + + DP_LOGD("[%s] Call Update",curObserver->name().c_str()); + (*it)->update(this); + + if (curObserver != *it) + continue; + + it++; + } +} + +void Observer::update(Subject *s) +{ + call(); +} + +//Observer::Observer(updateFunction uf, void *data) +/* For debug */ +Observer::Observer(updateFunction uf, void *data, const char *name) + : m_updateFunction(uf) + , m_userData(data) +{ + observerName = name; +} + +void Observer::set(updateFunction uf, void *data) +{ + m_updateFunction = uf; + m_userData = data; +} + +void Observer::clear(void) +{ + m_updateFunction = 0; + m_userData = 0; +} + +void Observer::call(void) +{ + if (m_updateFunction) + m_updateFunction(m_userData); +} diff --git a/src/download-provider-history-db.cpp b/src/download-provider-history-db.cpp new file mode 100644 index 0000000..7772ac8 --- /dev/null +++ b/src/download-provider-history-db.cpp @@ -0,0 +1,443 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-history-db.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Manager for a download history DB + */ + +#include <sstream> +#include "download-provider-common.h" +#include "download-provider-history-db.h" + +#define FINALIZE_ON_ERROR( stmt ) { \ + DP_LOG("SQL error: %d", ret);\ + if (sqlite3_finalize(stmt) != SQLITE_OK)\ + DP_LOGE("sqlite3_finalize is failed.");\ + close();\ + return false; \ +} + +sqlite3 *DownloadHistoryDB::historyDb = NULL; + +DownloadHistoryDB::DownloadHistoryDB() +{ +} + +DownloadHistoryDB::~DownloadHistoryDB() +{ +} + +bool DownloadHistoryDB::open() +{ + int ret = 0; + + DP_LOGD_FUNC(); + + close(); + + ret = db_util_open(DBDATADIR"/"HISTORYDB, &historyDb, + DB_UTIL_REGISTER_HOOK_METHOD); + + if (ret != SQLITE_OK) { + DP_LOGE("open fail"); + db_util_close(historyDb); + historyDb = NULL; + return false; + } + + return isOpen(); +} + +void DownloadHistoryDB::close() +{ + DP_LOGD_FUNC(); + if (historyDb) { + db_util_close(historyDb); + historyDb = NULL; + } +} + +/* FIXME : Hitory entry limitation ?? */ +bool DownloadHistoryDB::addToHistoryDB(Item *item) +{ + int ret = 0; + sqlite3_stmt *stmt = NULL; + const char *name = NULL; + + DP_LOG_FUNC(); + + if (!item) { + DP_LOGE("Item is NULL"); + return false; + } + + if (item->historyId() < 0) { + DP_LOGE("Cannot add to DB. Because historyId is invaild"); + return false; + } + + if (!open()) { + DP_LOGE("historyDB is NULL"); + return false; + } + + const string statement = "insert into history (historyid, downloadtype,\ + contenttype, state, err, name, vendor, path, url, cookie, date) \ + values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + ret = sqlite3_prepare_v2(historyDb, statement.c_str(), -1, &stmt, NULL); + + if (ret != SQLITE_OK) + FINALIZE_ON_ERROR(stmt); + /* binding values */ + if (sqlite3_bind_int(stmt, 1, item->historyId()) != SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + if (sqlite3_bind_int(stmt, 2, item->downloadType()) != SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + if (sqlite3_bind_int(stmt, 3, item->contentType()) != SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + if (sqlite3_bind_int(stmt, 4, item->state()) != SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + if (sqlite3_bind_int(stmt, 5, item->errorCode()) != SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + if (item->downloadType() == DL_TYPE::MIDP_DOWNLOAD) + name = item->contentName().c_str(); + else + name = item->title().c_str(); + if (sqlite3_bind_text(stmt, 6, name, -1, NULL) != SQLITE_OK) + DP_LOGE("sqlite3_bind_text is failed."); + if (sqlite3_bind_text(stmt, 7, item->vendorName().c_str(), -1, NULL) != + SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + if (sqlite3_bind_text( + stmt, 8, item->registeredFilePath().c_str(), -1, NULL) != SQLITE_OK) + DP_LOGE("sqlite3_bind_text is failed."); + if (sqlite3_bind_text(stmt, 9, item->url().c_str(), -1, NULL) != SQLITE_OK) + DP_LOGE("sqlite3_bind_text is failed."); + if (sqlite3_bind_text(stmt, 10, item->cookie().c_str(), -1, NULL) != SQLITE_OK) + DP_LOGE("sqlite3_bind_text is failed."); + if (sqlite3_bind_double(stmt, 11, item->finishedTime()) != SQLITE_OK) + DP_LOGE("sqlite3_bind_double is failed."); + ret = sqlite3_step(stmt); + + DP_LOGD("SQL return: %s", (ret == SQLITE_ROW || ret == SQLITE_OK)?"Success":"Fail"); + + close(); + + return ret == SQLITE_DONE; +} + +bool DownloadHistoryDB::getCountOfHistory(int *count) +{ + int ret = 0; + sqlite3_stmt *stmt = NULL; + + DP_LOG_FUNC(); + + if (!open()) { + DP_LOGE("historyDB is NULL"); + return false; + } + ret = sqlite3_prepare_v2(historyDb, "select COUNT(*) from history", -1, &stmt, NULL); + if (ret != SQLITE_OK) + FINALIZE_ON_ERROR(stmt); + + ret = sqlite3_step(stmt); + DP_LOGD("SQL return: %s", (ret == SQLITE_ROW || ret == SQLITE_OK)?"Success":"Fail"); + if (ret == SQLITE_ROW) { + *count = sqlite3_column_int(stmt,0); + DP_LOGD("count[%d]",*count); + } else { + DP_LOGE("SQL query error"); + *count = 0; + } + + if (sqlite3_finalize(stmt) != SQLITE_OK) + DP_LOGE("sqlite3_finalize is failed."); + close(); + return true; +} + +bool DownloadHistoryDB::createRemainedItemsFromHistoryDB(int limit, int offset) +{ + int ret = 0; + stringstream limitStr; + stringstream offsetStr; + sqlite3_stmt *stmt = NULL; + string tmp; + + DP_LOG_FUNC(); + + if (!open()) { + DP_LOGE("historyDB is NULL"); + return false; + } + limitStr << limit; + offsetStr << offset; + + tmp.append("select historyid, downloadtype, contenttype, state, err, "); + tmp.append("name, vendor, path, url, cookie, date from history order by "); + tmp.append("date DESC limit "); + tmp.append(limitStr.str()); + tmp.append(" offset "); + tmp.append(offsetStr.str()); + ret = sqlite3_prepare_v2(historyDb, tmp.c_str(), -1, &stmt, NULL); + if (ret != SQLITE_OK) + FINALIZE_ON_ERROR(stmt); + + for (;;) { + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + const char *tempStr = NULL; + string arg; + string url; + string cookie; + Item *item = Item::createHistoryItem(); + if (!item) { + DP_LOGE("Fail to create item"); + break; + } + item->setHistoryId(sqlite3_column_int(stmt,0)); + item->setDownloadType((DL_TYPE::TYPE)sqlite3_column_int(stmt,1)); + item->setContentType(sqlite3_column_int(stmt,2)); + item->setState((ITEM::STATE)sqlite3_column_int(stmt,3)); + item->setErrorCode((ERROR::CODE)sqlite3_column_int(stmt,4)); + tempStr = (const char *)(sqlite3_column_text(stmt,5)); + if (tempStr) { + arg = tempStr; + if (item->downloadType() == DL_TYPE::MIDP_DOWNLOAD) + item->setContentName(arg); + item->setTitle(arg); + } + tempStr = (const char *)(sqlite3_column_text(stmt,6)); + if (tempStr) + arg = tempStr; + else + arg = string(); + item->setVendorName(arg); + tempStr = (const char *)(sqlite3_column_text(stmt,7)); + if (tempStr) + arg = tempStr; + else + arg = string(); + item->setRegisteredFilePath(arg); + tempStr = (const char *)(sqlite3_column_text(stmt,8)); + if (tempStr) + url = tempStr; + else + url = string(); + tempStr = (const char *)(sqlite3_column_text(stmt,9)); + if (tempStr) + cookie = tempStr; + else + cookie = string(); + item->setFinishedTime(sqlite3_column_double(stmt,10)); + item->attachHistoryItem(); + item->setRetryData(url, cookie); + } else + break; + } + DP_LOGD("SQL error: %d", ret); + + if (sqlite3_finalize(stmt) != SQLITE_OK) + DP_LOGE("sqlite3_finalize is failed."); + + close(); + + if (ret == SQLITE_DONE || ret == SQLITE_ROW) + return true; + else + return false; +} + +bool DownloadHistoryDB::createItemsFromHistoryDB() +{ + int ret = 0; + sqlite3_stmt *stmt = NULL; + string tmp; + stringstream limitStr; + + DP_LOG_FUNC(); + + if (!open()) { + DP_LOGE("historyDB is NULL"); + return false; + } + limitStr << LOAD_HISTORY_COUNT; + tmp.append("select historyid, downloadtype, contenttype, state, err, "); + tmp.append("name, vendor, path, url, cookie, date from history order by "); + tmp.append("date DESC limit "); + tmp.append(limitStr.str()); + ret = sqlite3_prepare_v2(historyDb, tmp.c_str(), -1, &stmt, NULL); + if (ret != SQLITE_OK) + FINALIZE_ON_ERROR(stmt); + + for (;;) { + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + const char *tempStr = NULL; + string arg = string(); + string url = string(); + string cookie = string(); + Item *item = Item::createHistoryItem(); + if (!item) { + DP_LOGE("Fail to create item"); + break; + } + item->setHistoryId(sqlite3_column_int(stmt,0)); + item->setDownloadType((DL_TYPE::TYPE)sqlite3_column_int(stmt,1)); + item->setContentType(sqlite3_column_int(stmt,2)); + item->setState((ITEM::STATE)sqlite3_column_int(stmt,3)); + item->setErrorCode((ERROR::CODE)sqlite3_column_int(stmt,4)); + tempStr = (const char *)(sqlite3_column_text(stmt,5)); + if (tempStr) { + arg = tempStr; + if (item->downloadType() == DL_TYPE::MIDP_DOWNLOAD) + item->setContentName(arg); + item->setTitle(arg); + } + tempStr = (const char *)(sqlite3_column_text(stmt,6)); + if (tempStr) + arg = tempStr; + item->setVendorName(arg); + tempStr = (const char *)(sqlite3_column_text(stmt,7)); + if (tempStr) + arg = tempStr; + item->setRegisteredFilePath(arg); + tempStr = (const char *)(sqlite3_column_text(stmt,8)); + if (tempStr) + url = tempStr; + tempStr = (const char *)(sqlite3_column_text(stmt,9)); + if (tempStr) + cookie = tempStr; + item->setFinishedTime(sqlite3_column_double(stmt,10)); + item->attachHistoryItem(); + item->setRetryData(url, cookie); + } else + break; + } + DP_LOGD("SQL error: %d", ret); + + if (sqlite3_finalize(stmt) != SQLITE_OK) + DP_LOGE("sqlite3_finalize is failed."); + close(); + + if (ret == SQLITE_DONE || ret == SQLITE_ROW) + return true; + else + return false; +} + +bool DownloadHistoryDB::deleteItem(unsigned int historyId) +{ + int ret = 0; + sqlite3_stmt *stmt = NULL; + + DP_LOG_FUNC(); + + if (!open()) { + DP_LOGE("historyDB is NULL"); + return false; + } + + ret = sqlite3_prepare_v2(historyDb, "delete from history where historyid=?", + -1, &stmt, NULL); + + if (ret != SQLITE_OK) + FINALIZE_ON_ERROR(stmt); + if (sqlite3_bind_int(stmt, 1, historyId) != SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + ret = sqlite3_step(stmt); + if (ret != SQLITE_OK && ret != SQLITE_DONE) + FINALIZE_ON_ERROR(stmt); + + if (sqlite3_finalize(stmt) != SQLITE_OK) + DP_LOGE("sqlite3_finalize is failed."); + close(); + return true; +} + +bool DownloadHistoryDB::deleteMultipleItem(queue <unsigned int> &q) +{ + int ret = 0; + unsigned int historyId = -1; + sqlite3_stmt *stmt = NULL; + char *errmsg = NULL; + + DP_LOG_FUNC(); + + if (!open()) { + DP_LOGE("historyDB is NULL"); + return false; + } + ret = sqlite3_exec(historyDb, "PRAGMA synchronous=OFF;\ + PRAGMA count_changes=OFF; PRAGMA temp_store=memory;", + NULL, NULL, &errmsg); + if (SQLITE_OK != ret) { + sqlite3_free(errmsg); + close(); + return false; + } + + DP_LOGD("queue size[%d]",q.size()); + while (!q.empty()) { + ret = sqlite3_prepare_v2(historyDb, "delete from history where historyid=?", + -1, &stmt, NULL); + if (ret != SQLITE_OK) + FINALIZE_ON_ERROR(stmt); + historyId = q.front(); + q.pop(); + if (sqlite3_bind_int(stmt, 1, historyId) != SQLITE_OK) + DP_LOGE("sqlite3_bind_int is failed."); + ret = sqlite3_step(stmt); + if (ret != SQLITE_OK && ret != SQLITE_DONE) + FINALIZE_ON_ERROR(stmt); + } + + if (sqlite3_finalize(stmt) != SQLITE_OK) + DP_LOGE("sqlite3_finalize is failed."); + close(); + return true; +} + +bool DownloadHistoryDB::clearData(void) +{ + int ret = 0; + sqlite3_stmt *stmt = NULL; + + DP_LOG_FUNC(); + + if (!open()) { + DP_LOGE("historyDB is NULL"); + return false; + } + + ret = sqlite3_prepare_v2(historyDb, "delete from history", -1, &stmt, NULL); + if (ret != SQLITE_OK) + FINALIZE_ON_ERROR(stmt); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) + FINALIZE_ON_ERROR(stmt); + + if (sqlite3_finalize(stmt) != SQLITE_OK) + DP_LOGE("sqlite3_finalize is failed."); + close(); + return true; +} + diff --git a/src/download-provider-item.cpp b/src/download-provider-item.cpp new file mode 100644 index 0000000..df3d892 --- /dev/null +++ b/src/download-provider-item.cpp @@ -0,0 +1,653 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-item.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief item class for saving download data + */ +// FIXME later : move to util clas +#include "download-provider-item.h" +#include "download-provider-common.h" +#include "download-provider-items.h" +#include "download-provider-viewItem.h" +#include "download-provider-history-db.h" +#include "download-provider-network.h" +#include <iostream> +#include <time.h> + +Item::Item() + : m_state(ITEM::IDLE) + , m_errorCode(ERROR::NONE) + , m_historyId(-1) + , m_contentType(DP_CONTENT_UNKOWN) + , m_finishedTime(0) + , m_downloadType(DL_TYPE::TYPE_NONE) + , m_gotFirstData(false) +{ +// FIXME Later : init private members +} + +Item::Item(DownloadRequest &rRequest) + : m_state(ITEM::IDLE) + , m_errorCode(ERROR::NONE) + , m_historyId(-1) + , m_contentType(DP_CONTENT_UNKOWN) + , m_finishedTime(0) + , m_downloadType(DL_TYPE::TYPE_NONE) + , m_gotFirstData(false) +{ + m_title = S_("IDS_COM_BODY_NO_NAME"); + m_iconPath = DP_UNKNOWN_ICON_PATH; + m_aptr_request = auto_ptr<DownloadRequest>(new DownloadRequest(rRequest)); // FIXME ??? +} + +Item::~Item() +{ + DP_LOGD_FUNC(); +} + +void Item::create(DownloadRequest &rRequest) +{ +// DP_LOGD_FUNC(); + + Item *newItem = new Item(rRequest); + + Items &items = Items::getInstance(); + items.attachItem(newItem); + + ViewItem::create(newItem); + DP_LOGD("newItem[%p]",newItem); + + newItem->download(); +} + +Item *Item::createHistoryItem() +{ + string url = string(); + string cookie = string(); + DownloadRequest request(url,cookie); + Item *newItem = new Item(request); +// DP_LOGD_FUNC(); + + DP_LOGD("new History Item[%p]",newItem); + + return newItem; +} + +void Item::attachHistoryItem() +{ + Items &items = Items::getInstance(); + + DP_LOGD("attach History Item[%p]",this); + items.attachItem(this); + ViewItem::create(this); + extractIconPath(); +} + +void Item::destroy() +{ +// DP_LOG_FUNC(); + // FIXME prohibit to destroy if downloading + if (!isFinished()) { + DP_LOGE("Cannot delete this item. State[%d]",m_state); + return; + } + DP_LOGD("Item::destroy() notify()"); + + setState(ITEM::DESTROY); + notify(); +// DP_LOG("Item::destroy() notify()... END"); + m_aptr_downloadItem->deSubscribe(m_aptr_downloadObserver.get()); + if (m_aptr_downloadObserver.get()) + m_aptr_downloadObserver->clear(); + else + DP_LOGE("download observer pointer is NULL"); + /* When deleting item after download is failed */ + if (m_aptr_netEventObserver.get()) { + NetMgr &netMgrInstance = NetMgr::getInstance(); + netMgrInstance.deSubscribe(m_aptr_netEventObserver.get()); + } + Items::getInstance().detachItem(this); +} + +void Item::deleteFromDB() +{ + DownloadHistoryDB::deleteItem(m_historyId); +} + +void Item::download() +{ + NetMgr &netMgrInstance = NetMgr::getInstance(); + +// DP_LOGD_FUNC(); + + setState(ITEM::REQUESTING); + + createSubscribeData(); + + netMgrInstance.subscribe(m_aptr_netEventObserver.get()); + + m_aptr_downloadItem->start(); + + DP_LOG("Item::download() notify()"); + notify(); +} + +void Item::createSubscribeData() // autoptr's variable of this class. +{ + m_aptr_downloadObserver = auto_ptr<Observer>( + new Observer(updateCBForDownloadObserver, this, "downloadItemObserver")); + m_aptr_netEventObserver = auto_ptr<Observer>( + new Observer(netEventCBObserver, this, "netMgrObserver")); + m_aptr_downloadItem = auto_ptr<DownloadItem>(new DownloadItem(m_aptr_request)); + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to create download item"); + return; + } + m_aptr_downloadItem->subscribe(m_aptr_downloadObserver.get()); +} + +void Item::startUpdate(void) +{ + if (m_gotFirstData) { + setState(ITEM::DOWNLOADING); + if (!registeredFilePath().empty()) + /* need to parse title again, because installed path can be changed */ + extractTitle(); + return; + } + + DP_LOGD_FUNC(); + + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return; + } + m_gotFirstData = true; +// setState(ITEM::DOWNLOADING); + setState(ITEM::RECEIVING_DOWNLOAD_INFO); + + extractTitle(); + DownloadUtil &util = DownloadUtil::getInstance(); + m_contentType = util.getContentType( + m_aptr_downloadItem->mimeType().c_str(), filePath().c_str()); + extractIconPath(); +} + +void Item::updateFromDownloadItem(void) +{ +// DP_LOGD_FUNC(); + + switch (m_aptr_downloadItem->state()) { + case DL_ITEM::STARTED: + break; + case DL_ITEM::UPDATING: + startUpdate(); + break; + case DL_ITEM::COMPLETE_DOWNLOAD: + setState(ITEM::REGISTERING_TO_SYSTEM); + /* need to parse title again, because installed path can be changed */ + //extractTitle(); + break; + case DL_ITEM::INSTALL_NOTIFY: + setState(ITEM::NOTIFYING_TO_SERVER); + break; + case DL_ITEM::START_DRM_DOMAIN: + setState(ITEM::PROCESSING_DOMAIN); + break; + case DL_ITEM::FINISH_DRM_DOMAIN: + setState(ITEM::FINISH_PROCESSING_DOMAIN); + break; + case DL_ITEM::WAITING_RO: + setState(ITEM::ACTIVATING); + break; + case DL_ITEM::SUSPENDED: + setState(ITEM::SUSPEND); + m_aptr_downloadItem->resume(); + break; + case DL_ITEM::RESUMED: + //setState(ITEM::RESUMED); + break; + case DL_ITEM::FINISHED: + setState(ITEM::FINISH_DOWNLOAD); + handleFinishedItem(); + break; + case DL_ITEM::CANCELED: + /* Already update for cancel state in case of cancellation from user Response popup */ + if (state() == ITEM::CANCEL) { + DP_LOGD("Already cancelled when closing OMA download popup"); + return; + } else { + setState(ITEM::CANCEL); + handleFinishedItem(); + } + break; + case DL_ITEM::FAILED: + setState(ITEM::FAIL_TO_DOWNLOAD); + setErrorCode(m_aptr_downloadItem->errorCode()); + handleFinishedItem(); + break; + case DL_ITEM::WAITING_CONFIRM: + setState(ITEM::WAITING_USER_RESPONSE); + break; + default: + break; + } + + DP_LOGD("Item[%p]::updateFromDownloadItem() notify() dl_state[%d]state[%d]", this, m_aptr_downloadItem->state(), state()); + notify(); +} +void Item::handleFinishedItem() +{ + createHistoryId(); + m_finishedTime = time(NULL); + DownloadHistoryDB::addToHistoryDB(this); + /* If download is finished, it is not need to get network event */ + if (m_aptr_netEventObserver.get()) { + NetMgr &netMgrInstance = NetMgr::getInstance(); + netMgrInstance.deSubscribe(m_aptr_netEventObserver.get()); + } +} + +const char *Item::getErrorMessage(void) +{ + switch (m_errorCode) { + case ERROR::NETWORK_FAIL: + return S_("IDS_COM_POP_CONNECTION_FAILED"); + + case ERROR::INVALID_URL: + return S_("IDS_COM_POP_INVALID_URL"); + + case ERROR::NOT_ENOUGH_MEMORY: + return S_("IDS_COM_POP_NOT_ENOUGH_MEMORY"); + + case ERROR::FAIL_TO_INSTALL: + return __("IDS_BR_POP_INSTALLATION_FAILED"); + + case ERROR::OMA_POPUP_TIME_OUT: + return S_("IDS_COM_POP_CANCELLED") ; + + case ERROR::FAIL_TO_PARSE_DESCRIPTOR: + return __("IDS_BR_POP_INVALIDDESCRIPTOR") ; + + case ERROR::UNKNOWN: + case ERROR::ENGINE_FAIL: + return S_("IDS_COM_POP_FAILED") ; + default: + return NULL; + } +} + +void Item::extractTitle(void) +{ + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return; + } + DP_LOGD("title [%s] filePath [%s]", m_title.c_str(), filePath().c_str()); + if ((m_aptr_downloadItem->downloadType() == DL_TYPE::OMA_DOWNLOAD || + m_aptr_downloadItem->downloadType() == DL_TYPE::MIDP_DOWNLOAD) && + !m_aptr_downloadItem->contentName().empty()) { + m_title = m_aptr_downloadItem->contentName(); + } else { + size_t found = 0; + string path; + if (!registeredFilePath().empty()) + path = registeredFilePath(); + else + path = filePath(); + found = path.find_last_of("/"); + if (found != string::npos) + m_title = path.substr(found+1); + } +} + +void Item::extractIconPath() +{ + // FIXME Later : change 2 dimension array?? + switch(m_contentType) { + case DP_CONTENT_IMAGE : + m_iconPath = DP_IMAGE_ICON_PATH; + break; + case DP_CONTENT_VIDEO : + m_iconPath = DP_VIDEO_ICON_PATH; + break; + case DP_CONTENT_MUSIC: + m_iconPath = DP_MUSIC_ICON_PATH; + break; + case DP_CONTENT_PDF: + m_iconPath = DP_PDF_ICON_PATH; + break; + case DP_CONTENT_WORD: + m_iconPath = DP_WORD_ICON_PATH; + break; + case DP_CONTENT_PPT: + m_iconPath = DP_PPT_ICON_PATH; + break; + case DP_CONTENT_EXCEL: + m_iconPath = DP_EXCEL_ICON_PATH; + break; + case DP_CONTENT_HTML: + m_iconPath = DP_HTML_ICON_PATH; + break; + case DP_CONTENT_TEXT: + m_iconPath = DP_TEXT_ICON_PATH; + break; + case DP_CONTENT_RINGTONE: + m_iconPath = DP_RINGTONE_ICON_PATH; + break; + case DP_CONTENT_DRM: + m_iconPath = DP_DRM_ICON_PATH; + break; + case DP_CONTENT_JAVA: + m_iconPath = DP_JAVA_ICON_PATH; + break; + case DP_CONTENT_UNKOWN: + default: + m_iconPath = DP_UNKNOWN_ICON_PATH; + } +} + +void Item::updateCBForDownloadObserver(void *data) +{ + DP_LOGD_FUNC(); + if (data) + static_cast<Item*>(data)->updateFromDownloadItem(); +} + +void Item::netEventCBObserver(void *data) +{ + /* It is only considerd that there is one network event which is suspend now. + * If other network evnet is added, + * it is needed to add function accroding to what kinds of network event is + **/ + DP_LOG_FUNC(); + if (data) + static_cast<Item*>(data)->suspend(); +} + +void Item::sendUserResponse(bool res) +{ + bool ret = false; + DP_LOG_FUNC(); + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return; + } + ret = m_aptr_downloadItem->sendUserResponse(res); + if (ret) { + /* Update UI at once if the user cancel the oma download + * But this is really needed?? + */ + if (!res) { + setState(ITEM::CANCEL); + handleFinishedItem(); + notify(); + } else { + setState(ITEM::RECEIVING_DOWNLOAD_INFO); + } + } +} + +bool Item::play() +{ + if (m_contentType == DP_CONTENT_JAVA && + m_aptr_downloadItem->downloadType() == DL_TYPE::MIDP_DOWNLOAD) { + string pkgName; + DownloadUtil &util = DownloadUtil::getInstance(); + pkgName = util.getMidletPkgName(m_contentName, m_vendorName); + return m_fileOpener.openApp(pkgName); + } else { + return m_fileOpener.openFile(registeredFilePath(), m_contentType); + } +} + +/* Test code */ +const char *Item::stateStr(void) +{ + switch((int)state()) { + case ITEM::IDLE: + return "IDLE"; + case ITEM::REQUESTING: + return "REQUESTING"; + case ITEM::PREPARE_TO_RETRY: + return "PREPARE_TO_RETRY"; + case ITEM::WAITING_USER_RESPONSE: + return "WAITING_USER_RESPONSE"; + case ITEM::RECEIVING_DOWNLOAD_INFO: + return "RECEIVING_DOWNLOAD_INFO"; + case ITEM::DOWNLOADING: + return "DOWNLOADING"; + case ITEM::REGISTERING_TO_SYSTEM: + return "REGISTERING_TO_SYSTEM"; + case ITEM::PROCESSING_DOMAIN: + return "PROCESSING_DOMAIN"; + case ITEM::FINISH_PROCESSING_DOMAIN: + return "FINISH_PROCESSING_DOMAIN"; + case ITEM::ACTIVATING: + return "ACTIVATING"; + case ITEM::NOTIFYING_TO_SERVER: + return "NOTIFYING_TO_SERVER"; + case ITEM::SUSPEND: + return "SUSPEND"; + case ITEM::FINISH_DOWNLOAD: + return "FINISH_DOWNLOAD"; + case ITEM::FAIL_TO_DOWNLOAD: + return "FAIL_TO_DOWNLOAD"; + case ITEM::CANCEL: + return "CANCEL"; + case ITEM::PLAY: + return "PLAY"; + case ITEM::DESTROY: + return "DESTROY"; + } + return "Unknown State"; +} + +DL_TYPE::TYPE Item::downloadType() +{ + if (m_downloadType == DL_TYPE::TYPE_NONE) { + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return DL_TYPE::TYPE_NONE; + } + m_downloadType = m_aptr_downloadItem->downloadType(); + } + return m_downloadType; +} + +string &Item::contentName() +{ + if (m_contentName.empty()) { + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return m_emptyString; + } + m_contentName = m_aptr_downloadItem->contentName(); + } + return m_contentName; +} + +string &Item::vendorName() +{ + if (m_vendorName.empty()) { + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return m_emptyString; + } + m_vendorName = m_aptr_downloadItem->vendorName(); + } + return m_vendorName; +} + +string &Item::registeredFilePath() +{ + if (m_registeredFilePath.empty()) { + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return m_emptyString; + } + m_registeredFilePath = m_aptr_downloadItem->registeredFilePath(); + } + return m_registeredFilePath; +} + +string &Item::url() +{ + if (m_url.empty()) { + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return m_emptyString; + } + m_url = m_aptr_downloadItem->url(); + } + return m_url; +} + +string &Item::cookie() +{ + if (m_cookie.empty()) { + if (!m_aptr_downloadItem.get()) { + DP_LOGE("Fail to get download item"); + return m_emptyString; + } + m_cookie = m_aptr_downloadItem->cookie(); + } + return m_cookie; +} + + +void Item::createHistoryId() +{ + int count = 0; + unsigned tempId = time(NULL); + while (isExistedHistoryId(tempId)) { + srand((unsigned)(time(NULL))); + tempId = rand(); + count++; + if (count > 100) { + DP_LOGE("Fail to create unique ID"); + tempId = -1; + break; + } + DP_LOGD("random historyId[%ld]", m_historyId); + } + m_historyId = tempId; +} + +bool Item::isExistedHistoryId(unsigned int id) +{ + Items &items = Items::getInstance(); + return items.isExistedHistoryId(id); +} + +void Item::setRetryData(string &url, string &cookie) +{ + + m_url = url; + m_cookie = cookie; + m_aptr_request->setUrl(url); + m_aptr_request->setCookie(cookie); + + createSubscribeData(); + +} + +bool Item::retry() +{ + DP_LOG_FUNC(); + if (m_aptr_downloadItem.get()) { + NetMgr &netMgrInstance = NetMgr::getInstance(); + setState(ITEM::PREPARE_TO_RETRY); + notify(); + DownloadHistoryDB::deleteItem(m_historyId); + netMgrInstance.subscribe(m_aptr_netEventObserver.get()); + m_historyId = -1; + m_aptr_downloadItem->retry(); + return true; + } else { + m_state = ITEM::FAIL_TO_DOWNLOAD; + return false; + } +} + +void Item::clearForRetry() +{ + m_state = ITEM::IDLE; + m_errorCode = ERROR::NONE; + m_contentType = DP_CONTENT_UNKOWN; + m_finishedTime = 0; + m_downloadType = DL_TYPE::TYPE_NONE; + m_gotFirstData = false; +} + +bool Item::isFinished() +{ + bool ret = false; + switch (m_state) { + case ITEM::FINISH_DOWNLOAD: + case ITEM::FAIL_TO_DOWNLOAD: + case ITEM::CANCEL: + case ITEM::PLAY: + case ITEM::DESTROY: + ret = true; + break; + default: + ret = false; + } + return ret; +} + +bool Item::isFinishedWithErr() +{ + bool ret = false; + switch (m_state) { + case ITEM::FAIL_TO_DOWNLOAD: + case ITEM::CANCEL: + ret = true; + break; + default: + ret = false; + } + return ret; +} + +bool Item::isPreparingDownload() +{ + bool ret = false; + switch (m_state) { + case ITEM::IDLE: + case ITEM::REQUESTING: + case ITEM::PREPARE_TO_RETRY: + case ITEM::WAITING_USER_RESPONSE: + ret = true; + break; + default: + ret = false; + } + return ret; + +} + +bool Item::isCompletedDownload() +{ + if (isPreparingDownload() || m_state == ITEM::DOWNLOADING) + return false; + else + return true; +} + diff --git a/src/download-provider-items.cpp b/src/download-provider-items.cpp new file mode 100644 index 0000000..7fe1141 --- /dev/null +++ b/src/download-provider-items.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-items.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Interface API with item list + */ +#include "download-provider-items.h" + +void Items::attachItem(Item *item) +{ + m_items.push_back(item); +} + +void Items::detachItem(Item *item) +{ + vector<Item *>::iterator it; + for (it = m_items.begin() ; it < m_items.end() ; it++) { + if (*it == item) { + m_items.erase(it); + delete item; + } + } +} + +bool Items::isExistedHistoryId(unsigned int id) +{ + vector <Item *>::iterator it; + for (it = m_items.begin(); it < m_items.end(); it++) { + if ((*it)->historyId() == id ) { + DP_LOGD("historyId[%ld],title[%s]", + (*it)->historyId(), (*it)->title().c_str()); + return true; + } + } + return false; +} + diff --git a/src/download-provider-network.cpp b/src/download-provider-network.cpp new file mode 100644 index 0000000..6c6fa90 --- /dev/null +++ b/src/download-provider-network.cpp @@ -0,0 +1,247 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-network.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Download netowkr manager + */ + +#include <stdlib.h> +#include "download-provider-common.h" +#include "download-provider-network.h" + +enum { + NET_INACTIVE = 0, + NET_WIFI_ACTIVE, + NET_CELLULAR_ACTIVE +}; + +NetMgr::NetMgr() +{ + m_netStatus = getConnectionState(); + if (m_netStatus == NET_WIFI_ACTIVE || + m_netStatus == NET_CELLULAR_ACTIVE) { + getProxy(); + getIPAddress(); + } +} + +NetMgr::~NetMgr() +{ +} + +void NetMgr::initNetwork() +{ + if (vconf_notify_key_changed(VCONFKEY_NETWORK_STATUS, + netStatusChangedCB, NULL) < 0) + DP_LOGE("Fail to register network status callback"); + if (vconf_notify_key_changed(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, + netConfigChangedCB, NULL) < 0) + DP_LOGE("Fail to register network config change callback"); +} + +void NetMgr::deinitNetwork() +{ + if (vconf_ignore_key_changed(VCONFKEY_NETWORK_STATUS, + netStatusChangedCB) < 0) + DP_LOGE("Fail to ignore network status callback"); + if (vconf_ignore_key_changed(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, + netConfigChangedCB) < 0) + DP_LOGE("Fail to ignore network config change callback"); +} + +int NetMgr::getConnectionState() +{ + int status = VCONFKEY_NETWORK_OFF; + int ret = 0; + + ret = vconf_get_int(VCONFKEY_NETWORK_STATUS, &status); + if (ret < 0) { + DP_LOGE(" Fail to get network status : err[%d]",ret); + return NET_INACTIVE; + } + switch (status) { + case VCONFKEY_NETWORK_OFF: + DP_LOG("VCONFKEY_NETWORK_OFF"); + ret = NET_INACTIVE; + break; + case VCONFKEY_NETWORK_CELLULAR: + DP_LOG("VCONFKEY_NETWORK_CELLULAR"); + ret = getCellularStatus(); + break; + case VCONFKEY_NETWORK_WIFI: + DP_LOG("VCONFKEY_NETWORK_WIFI"); + ret = getWifiStatus(); + break; + default: + DP_LOGE("Cannot enter here"); + ret = NET_INACTIVE; + } + return ret; +} + +int NetMgr::getCellularStatus() +{ + int status = VCONFKEY_NETWORK_CELLULAR_NO_SERVICE; + int ret = 0; + + ret = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &status); + + if (ret < 0) { + DP_LOGE(" Fail to get cellular status : err[%d]",ret); + return NET_INACTIVE; + } + + switch(status) { + case VCONFKEY_NETWORK_CELLULAR_ON: + DP_LOG("VCONFKEY_NETWORK_CELLULAR_ON"); + ret = NET_CELLULAR_ACTIVE; + break; + case VCONFKEY_NETWORK_CELLULAR_3G_OPTION_OFF: + DP_LOG("VCONFKEY_NETWORK_CELLULAR_3G_OPTION_OFF"); + ret = NET_INACTIVE; + break; + case VCONFKEY_NETWORK_CELLULAR_ROAMING_OFF: + DP_LOG("VCONFKEY_NETWORK_CELLULAR_ROAMING_OFF"); + ret = NET_INACTIVE; + break; + case VCONFKEY_NETWORK_CELLULAR_FLIGHT_MODE: + DP_LOG("VCONFKEY_NETWORK_CELLULAR_FLIGHT_MODE"); + ret = NET_INACTIVE; + break; + case VCONFKEY_NETWORK_CELLULAR_NO_SERVICE: + DP_LOG("VCONFKEY_NETWORK_CELLULAR_NO_SERVICE"); + ret = NET_INACTIVE; + break; + default: + DP_LOGE("Cannot enter here"); + ret = NET_INACTIVE; + } + return ret; + +} + +int NetMgr::getWifiStatus() +{ + int status = VCONFKEY_NETWORK_WIFI_OFF; + int ret = 0; + + ret = vconf_get_int(VCONFKEY_NETWORK_WIFI_STATE, &status); + + if (ret < 0) { + DP_LOGE(" Fail to get wifi status : err[%d]",ret); + return NET_INACTIVE; + } + + switch(status) { + case VCONFKEY_NETWORK_WIFI_CONNECTED: + DP_LOG("VCONFKEY_NETWORK_WIFI_CONNECTED"); + ret = NET_WIFI_ACTIVE; + break; + case VCONFKEY_NETWORK_WIFI_NOT_CONNECTED: + DP_LOG("VCONFKEY_NETWORK_WIFI_NOT_CONNECTED"); + ret = NET_INACTIVE; + break; + case VCONFKEY_NETWORK_WIFI_OFF: + DP_LOG("VCONFKEY_NETWORK_WIFI_OFF"); + ret = NET_INACTIVE; + break; + default: + DP_LOGE("Cannot enter here"); + ret = NET_INACTIVE; + } + return ret; +} + +void NetMgr::netStatusChanged() +{ + int changedStatus = NET_INACTIVE; + changedStatus = getConnectionState(); + DP_LOG("Previous[%d] Changed[%d]", m_netStatus, changedStatus); + if (m_netStatus != changedStatus) { + if (changedStatus == NET_INACTIVE) + DP_LOG("Netowrk is disconnected"); + else + DP_LOG("Network is connected"); + m_netStatus = changedStatus; + } else { + DP_LOGE("Network status is not changed. Cannot enter here"); + } +} + +void NetMgr::netConfigChanged() +{ + int status = 0; + int ret = 0; + + DP_LOG_FUNC(); + + ret = vconf_get_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, &status); + if (ret < 0) { + DP_LOGE("Fail to get network configuration change ind : err[%d]",ret); + return; + } + DP_LOG("netConfigChanged:status[%d]", status); + + + if (status) { /* true */ + getProxy(); + getIPAddress(); + /* This notify is only for suspend event. + * If othere network event is added, it is needed to save event types + * and get function for it + **/ + notify(); + } else { + DP_LOGE("Network connection is disconnected"); + } +} + +void NetMgr::getProxy() +{ + char *proxy = NULL; + proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY); + if (proxy) { + DP_LOG("===== Proxy address[%s] =====", proxy); + free(proxy); + proxy = NULL; + } +} + +void NetMgr::getIPAddress() +{ + char *ipAddr = NULL; + ipAddr = vconf_get_str(VCONFKEY_NETWORK_IP); + if (ipAddr) { + DP_LOG("===== IP address[%s] =====", ipAddr); + free(ipAddr); + ipAddr= NULL; + } +} + +void NetMgr::netStatusChangedCB(keynode_t *keynode, void *data) +{ + NetMgr inst = NetMgr::getInstance(); + inst.netStatusChanged(); +} + +void NetMgr::netConfigChangedCB(keynode_t *keynode, void *data) +{ + NetMgr inst = NetMgr::getInstance(); + inst.netConfigChanged(); +} + diff --git a/src/download-provider-util.cpp b/src/download-provider-util.cpp new file mode 100644 index 0000000..cc4ba40 --- /dev/null +++ b/src/download-provider-util.cpp @@ -0,0 +1,283 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/* + * @file download-provider-util.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Utility APIs and interface with content player + */ + +#include <stdio.h> +#include <string.h> +#include <dlfcn.h> +#include "aul.h" +#include "xdgmime.h" +#include "app_service.h" + +#include "download-provider-util.h" + +#define JAVA_ENG_PATH "/usr/lib/libjava-installer.so" + +struct MimeTableType +{ + const char *mime; + int contentType; +}; + +#define MAX_MIME_TABLE_NUM 22 +const char *ambiguousMIMETypeList[] = { + "text/plain", + "application/octet-stream" +}; + +struct MimeTableType MimeTable[]={ + // PDF + {"application/pdf",DP_CONTENT_PDF}, + // word + {"application/msword",DP_CONTENT_WORD}, + {"application/vnd.openxmlformats-officedocument.wordprocessingml.document",DP_CONTENT_WORD}, + // ppt + {"application/vnd.ms-powerpoint",DP_CONTENT_PPT}, + {"application/vnd.openxmlformats-officedocument.presentationml.presentation",DP_CONTENT_PPT}, + // excel + {"application/vnd.ms-excel",DP_CONTENT_EXCEL}, + {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",DP_CONTENT_EXCEL}, + // html + {"text/html",DP_CONTENT_HTML}, + // txt + {"text/txt",DP_CONTENT_TEXT}, + {"text/palin",DP_CONTENT_TEXT}, + // ringtone + {"text/x-iMelody",DP_CONTENT_RINGTONE},//10 + {"application/x-smaf",DP_CONTENT_RINGTONE}, + {"audio/midi",DP_CONTENT_RINGTONE}, + {"audio/AMR",DP_CONTENT_RINGTONE}, + {"audio/AMR-WB",DP_CONTENT_RINGTONE}, + {"audio/x-xmf",DP_CONTENT_RINGTONE}, + // DRM + {"application/vnd.oma.drm.content",DP_CONTENT_DRM}, + {"application/vnd.oma.drm.message",DP_CONTENT_DRM}, + // JAVA + {"application/x-java-archive",DP_CONTENT_JAVA}, + {"application/java-archive",DP_CONTENT_JAVA}, + // SVG + {"image/svg+xml",DP_CONTENT_SVG}, //20 + // FLASH + {"application/x-shockwave-flash",DP_CONTENT_FLASH} +}; + +bool FileOpener::openFile(string &path, int contentType) +{ + service_h handle = NULL; + string filePath; + DP_LOG_FUNC(); + + if (path.empty()) + return false; + + DP_LOG("path [%s]", path.c_str()); + if (service_create(&handle) < 0) { + DP_LOGE("Fail to create service handle"); + return false; + } + + if (!handle) { + DP_LOGE("service handle is null"); + return false; + } + + if (service_set_operation(handle, SERVICE_OPERATION_VIEW) < 0) { + DP_LOGE("Fail to set service operation"); + service_destroy(handle); + return false; + } + + if (contentType == DP_CONTENT_HTML) { + filePath = "file://"; + filePath.append(path.c_str()); + } else { + filePath = path; + } + if (service_set_uri(handle, filePath.c_str()) < 0) { + DP_LOGE("Fail to set uri"); + service_destroy(handle); + return false; + } + + if (service_send_launch_request(handle, NULL, NULL) < 0) { + DP_LOGE("Fail to launch service"); + service_destroy(handle); + return false; + } + + service_destroy(handle); + + return true; +} + +bool FileOpener::openApp(string &pkgName) +{ + service_h handle = NULL; + DP_LOG_FUNC(); + if (pkgName.empty()) + return false; + + if (service_create(&handle) < 0) { + DP_LOGE("Fail to create service handle"); + return false; + } + + if (!handle) { + DP_LOGE("service handle is null"); + return false; + } + + if (service_set_package(handle, pkgName.c_str()) < 0) { + DP_LOGE("Fail to set service operation"); + service_destroy(handle); + return false; + } + + if (service_send_launch_request(handle, NULL, NULL) < 0) { + DP_LOGE("Fail to aul open"); + service_destroy(handle); + return false; + } + + service_destroy(handle); + + return true; +} + + +DownloadUtil::DownloadUtil() +{ + initDrm(); +} + +string DownloadUtil::getMidletPkgName(string& name, string& vendor) +{ + string pkgName = string(); + char appName[MAX_FILE_PATH_LEN] = {0,}; + void *handle = NULL; + int (*java_get_pkgname )(char *,char *,char *) = NULL; + + if (name.length() < 1 || vendor.length() < 1) + return pkgName; + + handle = dlopen(JAVA_ENG_PATH, RTLD_LAZY); + if ( handle == NULL ) { + DP_LOGE("dlopen error\n"); + if(handle) + dlclose(handle); + return pkgName; + } + + java_get_pkgname = (int(*)(char *,char *,char *)) dlsym( handle, "jim_get_suite_pkgname_with_vendor_suite_name"); + if ( java_get_pkgname == NULL ) { + DP_LOGE("dlopen error2\n"); + dlclose(handle); + return pkgName; + } + DP_LOG("vendor name[%s] midlet name[%s]",vendor.c_str(),name.c_str()); + + if (java_get_pkgname((char *)vendor.c_str(), (char *)name.c_str(), appName)) { + DP_LOG("pkg name[%s]\n",appName); + pkgName = appName; + } + dlclose(handle); + return pkgName; +} + +void DownloadUtil::initDrm() +{ + DP_LOG_FUNC(); +} + +int DownloadUtil::getContentType(const char *mime, const char *filePath) +{ + int i = 0; + int type = DP_CONTENT_UNKOWN; + int ret = 0; + char tempMime[MAX_FILE_PATH_LEN] = {0,}; + DP_LOGD_FUNC(); + if (mime == NULL || strlen(mime) < 1) + return DP_CONTENT_UNKOWN; + + DP_LOG("mime[%s]",mime); + strncpy(tempMime, mime, MAX_FILE_PATH_LEN-1); + if (isAmbiguousMIMEType(mime)) { + if (filePath) { + memset(tempMime, 0x00, MAX_FILE_PATH_LEN); + ret = aul_get_mime_from_file(filePath,tempMime,sizeof(tempMime)); + if (ret < AUL_R_OK ) + strncpy(tempMime, mime, MAX_FILE_PATH_LEN-1); + else + DP_LOG("mime from extension name[%s]",tempMime); + } + } + + /* Search a content type from mime table. */ + for (i = 0; i < MAX_MIME_TABLE_NUM; i++) + { + //DP_LOG("TableMime[%d][%s]",i,MimeTable[i].mime); + if (strncmp(MimeTable[i].mime, tempMime, strlen(tempMime)) == 0){ + type = MimeTable[i].contentType; + break; + } + } + /* If there is no mime at mime table, check the category with the first + * domain of mime string + * ex) video/... => video type */ + if (type == DP_CONTENT_UNKOWN) + { + const char *unaliasedMime = NULL; + /* unaliased_mimetype means representative mime among similar types */ + unaliasedMime = xdg_mime_unalias_mime_type(tempMime); + + if (unaliasedMime != NULL) { + DP_LOG("unaliased mime type[%s]\n",unaliasedMime); + if (strstr(unaliasedMime,"video/") != NULL) + type = DP_CONTENT_VIDEO; + else if (strstr(unaliasedMime,"audio/") != NULL) + type = DP_CONTENT_MUSIC; + else if (strstr(unaliasedMime,"image/") != NULL) + type = DP_CONTENT_IMAGE; + } + } + DP_LOG("type[%d]\n",type); + return type; +} + +bool DownloadUtil::isAmbiguousMIMEType(const char *mimeType) +{ + + if (!mimeType) + return false; + + int index = 0; + int listSize = sizeof(ambiguousMIMETypeList) / sizeof(const char *); + for (index = 0; index < listSize; index++) { + if (0 == strncmp(mimeType, ambiguousMIMETypeList[index], + strlen(ambiguousMIMETypeList[index]))) { + DP_LOG("It is ambiguous! [%s]", ambiguousMIMETypeList[index]); + return true; + } + } + + return false; +} + diff --git a/src/download-provider-view.cpp b/src/download-provider-view.cpp new file mode 100644 index 0000000..102d034 --- /dev/null +++ b/src/download-provider-view.cpp @@ -0,0 +1,1174 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-view.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief UI manager class for download list view and delete view + */ +#include <sstream> +#include <queue> +#include "download-provider-view.h" +#include "download-provider-history-db.h" +#include "download-provider-downloadItem.h" + +static void destroy_window_cb(void *data, Evas_Object *obj, void *event); + +enum { + DOWNLOAD_NOTIFY_SELECTED, + DOWNLOAD_NOTIFY_DELETED +}; + +DownloadView::DownloadView(void) + : eoWindow(NULL) + , eoBackground(NULL) + , eoLayout(NULL) + , eoNaviBar(NULL) + , eoNaviBarItem(NULL) + , eoBackBtn(NULL) + , eoControlBar(NULL) + , eoCbItemDelete(NULL) + , eoCbItemCancel(NULL) + , eoCbItemEmpty(NULL) + , eoBoxLayout(NULL) + , eoBox(NULL) + , eoDldList(NULL) + , eoPopup(NULL) + , eoSelectAllLayout(NULL) + , eoAllCheckedBox(NULL) + , eoNotifyInfo(NULL) + , eoNotifyInfoLayout(NULL) + , m_allChecked(EINA_FALSE) + , m_viewItemCount(0) +{ +// FIXME Later : init private members + DownloadEngine &engine = DownloadEngine::getInstance(); + engine.initEngine(); + DateUtil &inst = DateUtil::getInstance(); + inst.updateLocale(); + dldGenlistGroupStyle.item_style = "grouptitle"; + dldGenlistGroupStyle.func.text_get = getGenlistGroupLabelCB; + dldGenlistGroupStyle.func.content_get = NULL; + dldGenlistGroupStyle.func.state_get = NULL; + dldGenlistGroupStyle.func.del = NULL; + + m_today.setType(DATETIME::DATE_TYPE_TODAY); + m_yesterday.setType(DATETIME::DATE_TYPE_YESTERDAY); + m_previousDay.setType(DATETIME::DATE_TYPE_PREVIOUS); +} + +DownloadView::~DownloadView() +{ + DP_LOG_FUNC(); + DownloadEngine &engine = DownloadEngine::getInstance(); + engine.deinitEngine(); +} + +Evas_Object *DownloadView::create(void) +{ + Evas_Object *window = NULL; + window = createWindow(PACKAGE); + if (!window) + return NULL; + + createBackground(window); + createLayout(window); + setIndicator(window); + createView(); + + return window; +} + +void DownloadView::show() +{ + DP_LOG_FUNC(); + elm_win_raise(eoWindow); + handleUpdateDateGroupType(NULL); +} + +void DownloadView::hide() +{ + DP_LOG_FUNC(); + removePopup(); + destroyNotifyInfo(); + if (isGenlistEditMode()) { + hideGenlistEditMode(); + } + elm_win_lower(eoWindow); +} + +void DownloadView::activateWindow() +{ + if (!eoWindow) + create(); + + show(); +} + +void DownloadView::showViewItem(int id, const char *title) +{ + DP_LOG_FUNC(); +} + +/* This is called by AUL view mode */ +void DownloadView::playContent(int id, const char *title) +{ + DP_LOG_FUNC(); +} + +void DownloadView::setIndicator(Evas_Object *window) +{ + elm_win_indicator_mode_set(window, ELM_WIN_INDICATOR_SHOW); +} + +Evas_Object *DownloadView::createWindow(const char *windowName) +{ + eoWindow = elm_win_add(NULL, windowName, ELM_WIN_BASIC); + if (eoWindow) { + elm_win_title_set(eoWindow, __("IDS_BR_HEADER_DOWNLOAD_MANAGER")); + elm_win_borderless_set(eoWindow, EINA_TRUE); + elm_win_conformant_set(eoWindow, 1); + evas_object_smart_callback_add(eoWindow, "delete,request", + destroy_window_cb, static_cast<void*>(this)); + } + return eoWindow; +} + +Evas_Object *DownloadView::createBackground(Evas_Object *window) +{ + if (!window) + return NULL; + + eoBackground = elm_bg_add(window); + if (eoBackground) { + evas_object_size_hint_weight_set(eoBackground, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(window, eoBackground); + evas_object_show(eoBackground); + } else { + DP_LOGE("Fail to create bg object"); + } + return eoBackground; +} + +Evas_Object *DownloadView::createLayout(Evas_Object *parent) +{ + if (!parent) { + DP_LOGE("Invalid Paramter"); + return NULL; + } + + eoLayout = elm_layout_add(parent); + if (eoLayout) { + if (!elm_layout_theme_set(eoLayout, "layout", "application", "default" )) + DP_LOGE("Fail to set elm_layout_theme_set"); + + evas_object_size_hint_weight_set(eoLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(parent, eoLayout); + + edje_object_signal_emit(elm_layout_edje_get(eoLayout), "elm,state,show,indicator", "elm"); + evas_object_show(eoLayout); + } else { + DP_LOGE("Fail to create layout"); + } + return eoLayout; +} + +void DownloadView::createView() +{ + DP_LOG_FUNC(); + createNaviBar(); + createList(); + if (m_viewItemCount < 1) + showEmptyView(); +} + +void DownloadView::createNaviBar() +{ + DP_LOGD_FUNC(); + eoNaviBar = elm_naviframe_add(eoLayout); + elm_object_part_content_set(eoLayout, "elm.swallow.content", eoNaviBar); + createBackBtn(); + createBox(); + eoNaviBarItem = elm_naviframe_item_push(eoNaviBar, + __("IDS_BR_HEADER_DOWNLOAD_MANAGER"),eoBackBtn, NULL, eoBoxLayout, NULL); + createControlBar(); + evas_object_show(eoNaviBar); + +} + +void DownloadView::createBackBtn() +{ + DP_LOGD_FUNC(); + eoBackBtn = elm_button_add(eoNaviBar); + elm_object_style_set(eoBackBtn, "naviframe/end_btn/default"); + evas_object_smart_callback_add(eoBackBtn, "clicked", backBtnCB,NULL); + evas_object_show(eoBackBtn); +} + +void DownloadView::createControlBar() +{ + DP_LOGD_FUNC(); + + eoControlBar = elm_toolbar_add(eoNaviBar); + if (eoControlBar == NULL) + return; + elm_toolbar_shrink_mode_set(eoControlBar, ELM_TOOLBAR_SHRINK_EXPAND); + eoCbItemDelete = elm_toolbar_item_append(eoControlBar, NULL, + S_("IDS_COM_OPT_DELETE"), cbItemDeleteCB, eoNaviBar); + eoCbItemEmpty = elm_toolbar_item_append(eoControlBar, NULL, NULL, NULL, NULL); + elm_object_item_part_content_set(eoNaviBarItem, "controlbar", + eoControlBar); + elm_object_item_disabled_set(eoCbItemDelete, EINA_TRUE); + elm_object_item_disabled_set(eoCbItemEmpty, EINA_TRUE); + evas_object_show(eoControlBar); +} + +void DownloadView::createBox() +{ + DP_LOGD_FUNC(); + eoBoxLayout = elm_layout_add(eoNaviBar); + elm_layout_theme_set(eoBoxLayout, "layout", "application", "noindicator"); + evas_object_size_hint_weight_set(eoBoxLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + eoBox = elm_box_add(eoBoxLayout); + elm_object_part_content_set(eoBoxLayout, "elm.swallow.content", eoBox ); + + evas_object_show(eoBox); + evas_object_show(eoBoxLayout); +} + +void DownloadView::createList() +{ + //DP_LOGD_FUNC(); + eoDldList = elm_genlist_add(eoBoxLayout); + DP_LOGD("create::eoDldList[%p]",eoDldList); +/* When using ELM_LIST_LIMIT, the window size is broken at the landscape mode */ + evas_object_size_hint_weight_set(eoDldList, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(eoDldList, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_genlist_homogeneous_set(eoDldList, EINA_TRUE); + elm_genlist_block_count_set(eoDldList,8); + + elm_box_pack_end(eoBox, eoDldList); + evas_object_show(eoDldList); +} + +void destroy_window_cb(void *data, Evas_Object *obj, void *event) +{ + DP_LOG_FUNC(); + elm_exit(); +} + +void DownloadView::changedRegion() +{ + DateUtil &inst = DateUtil::getInstance(); + inst.updateLocale(); + elm_genlist_realized_items_update(eoDldList); +} + +void DownloadView::attachViewItem(ViewItem *viewItem) +{ + DP_LOG_FUNC(); + if (m_viewItemCount < 1) { + hideEmptyView(); + createList(); + } + if (viewItem) { + addViewItemToGenlist(viewItem); + m_viewItemCount++; + } +} + +void DownloadView::detachViewItem(ViewItem *viewItem) +{ + DP_LOG("delete viewItem[%p]",viewItem); + if (viewItem) { + delete viewItem; + m_viewItemCount--; + } + if (!isGenlistEditMode() && + (m_viewItemCount < 1)) + showEmptyView(); +} + +void DownloadView::update() +{ + Elm_Object_Item *it = NULL; + DP_LOG_FUNC(); + if (!eoDldList) { + DP_LOGE("download list is NULL"); + return; + } + it = elm_genlist_first_item_get(eoDldList); + while (it) { + DP_LOGD("glItem[%p]",it); + elm_genlist_item_update(it); + it = elm_genlist_item_next_get(it); + } +} + +void DownloadView::update(ViewItem *viewItem) +{ + if (!viewItem) + return; + + DP_LOG("DownloadView::update viewItem [%p]", viewItem); + elm_genlist_item_update(viewItem->genlistItem()); +} + +void DownloadView::update(Elm_Object_Item *glItem) +{ + if (!glItem) + return; + + DP_LOG("DownloadView::update glItem [%p]", glItem); + elm_genlist_item_update(glItem); +} + +void DownloadView::addViewItemToGenlist(ViewItem *viewItem) +{ + DP_LOG_FUNC(); + handleUpdateDateGroupType(viewItem); + createGenlistItem(viewItem); +} + +void DownloadView::createGenlistItem(ViewItem *viewItem) +{ + Elm_Object_Item *glItem = NULL; + Elm_Object_Item *glGroupItem = NULL; + /* EAPI Elm_Object_Item *elm_genlist_item_prepend( + * Evas_Object *obj, + * const Elm_Genlist_Item_Class *itc, + * const void *data, + * Elm_Object_Item *parent, + * Elm_Genlist_Item_Type flags, + * Evas_Smart_Cb func, + * const void *func_data) EINA_ARG_NONNULL(1); */ + glGroupItem = getGenlistGroupItem(viewItem->dateGroupType()); + DP_LOGD("group item[%p]",glGroupItem); + if (!glGroupItem) { + DateGroup *dateGrpObj = getDateGroupObj(viewItem->dateGroupType()); + if (!viewItem->isFinished()) { + glGroupItem = elm_genlist_item_prepend( + eoDldList, + &dldGenlistGroupStyle, + static_cast<const void*>(dateGrpObj), + NULL, + ELM_GENLIST_ITEM_GROUP, + NULL, + NULL); + } else { + /* Download History Item */ + glGroupItem = elm_genlist_item_append( + eoDldList, + &dldGenlistGroupStyle, + static_cast<const void*>(dateGrpObj), + NULL, + ELM_GENLIST_ITEM_GROUP, + NULL, + NULL); + } + if (!glGroupItem) + DP_LOGE("Fail to add a genlist group item"); + else + elm_genlist_item_select_mode_set(glGroupItem, + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + setGenlistGroupItem(viewItem->dateGroupType(), glGroupItem); + } + increaseGenlistGroupCount(viewItem->dateGroupType()); + if (!viewItem->isFinished()) { + glItem = elm_genlist_item_insert_after( + eoDldList, + viewItem->elmGenlistStyle(), + static_cast<const void*>(viewItem), + glGroupItem, + glGroupItem, + ELM_GENLIST_ITEM_NONE, + genlistClickCB, + static_cast<const void*>(viewItem)); + } else { + /* Download History Item */ + glItem = elm_genlist_item_append( + eoDldList, + viewItem->elmGenlistStyle(), + static_cast<const void*>(viewItem), + glGroupItem, + ELM_GENLIST_ITEM_NONE, + genlistClickCB, + static_cast<const void*>(viewItem)); + } + if (!glItem) + DP_LOGE("Fail to add a genlist item"); + + DP_LOGD("genlist groupItem[%p] item[%p] viewItem[%p]", glGroupItem, glItem, viewItem); + viewItem->setGenlistItem(glItem); + /* Move scrollbar to top. + * When groupItem means today group in case of addtion of download link item + **/ + if (!viewItem->isFinished()) + elm_genlist_item_show(glGroupItem, ELM_GENLIST_ITEM_SCROLLTO_TOP); + +} + +void DownloadView::showEmptyView() +{ + DP_LOGD_FUNC(); + if (!eoEmptyNoContent) { + eoEmptyNoContent = elm_layout_add(eoLayout); + elm_layout_theme_set(eoEmptyNoContent, "layout", "nocontents", "text"); + evas_object_size_hint_weight_set(eoEmptyNoContent, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(eoEmptyNoContent, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_part_text_set(eoEmptyNoContent, "elm.text", + __("IDS_DL_BODY_NO_DOWNLOADS")); + evas_object_size_hint_weight_set (eoEmptyNoContent, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + if (eoDldList) { + elm_box_unpack(eoBox,eoDldList); + /* Detection code */ + DP_LOGD("del::eoDldList[%p]",eoDldList); + evas_object_del(eoDldList); + eoDldList = NULL; + } + elm_box_pack_start(eoBox, eoEmptyNoContent); + } + evas_object_show(eoEmptyNoContent); + elm_object_item_disabled_set(eoCbItemDelete, EINA_TRUE); +} + +void DownloadView::hideEmptyView() +{ + DP_LOGD_FUNC(); + if(eoEmptyNoContent) { + elm_box_unpack(eoBox, eoEmptyNoContent); + evas_object_del(eoEmptyNoContent); + eoEmptyNoContent = NULL; + } + elm_object_item_disabled_set(eoCbItemDelete, EINA_FALSE); +} + +bool DownloadView::isGenlistEditMode() +{ + return (bool)elm_genlist_decorate_mode_get(eoDldList); +} + +void DownloadView::createSelectAllLayout() +{ + eoSelectAllLayout = elm_layout_add(eoBox); + elm_layout_theme_set(eoSelectAllLayout, "genlist", "item", + "select_all/default"); + evas_object_size_hint_weight_set(eoSelectAllLayout, EVAS_HINT_EXPAND, + EVAS_HINT_FILL); + evas_object_size_hint_align_set(eoSelectAllLayout, EVAS_HINT_FILL, + EVAS_HINT_FILL); + evas_object_event_callback_add(eoSelectAllLayout, EVAS_CALLBACK_MOUSE_DOWN, + selectAllClickedCB, NULL); + eoAllCheckedBox = elm_check_add(eoSelectAllLayout); + elm_check_state_pointer_set(eoAllCheckedBox, &m_allChecked); + evas_object_smart_callback_add(eoAllCheckedBox, "changed", + selectAllChangedCB, NULL); + evas_object_propagate_events_set(eoAllCheckedBox, EINA_FALSE); + elm_object_part_content_set(eoSelectAllLayout, "elm.icon", eoAllCheckedBox); + elm_object_text_set(eoSelectAllLayout, S_("IDS_COM_BODY_SELECT_ALL")); + elm_box_pack_start(eoBox, eoSelectAllLayout); + evas_object_show(eoSelectAllLayout); + m_allChecked = EINA_FALSE; +} + +void DownloadView::changeAllCheckedValue() +{ + m_allChecked = !m_allChecked; + elm_check_state_pointer_set(eoAllCheckedBox, &m_allChecked); + handleChangedAllCheckedState(); +} + +void DownloadView::destroyCheckedItem() +{ + Eina_List *list = NULL; + Elm_Object_Item *it = NULL; + ViewItem *item = NULL; + int checkedCount = 0; + queue <unsigned int> deleteQueue; + + DP_LOGD_FUNC(); + + it = elm_genlist_first_item_get(eoDldList); + + while (it) { + item = (ViewItem *)elm_object_item_data_get(it); + /* elm_genlist_item_select_mode_get is needed to check group item */ + if (elm_genlist_item_select_mode_get(it) != + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY && + item && item->checkedValue()) { + list = eina_list_append(list, it); + } + it = elm_genlist_item_next_get(it); + } + + if (!list) { + DP_LOGD("There is no delete item"); + return; + } + + checkedCount = eina_list_count(list); + if (checkedCount < 1) + return; + DP_LOGD("checkedCount[%d]", checkedCount); + + for (int i = 0; i < checkedCount; i++) + { + it = (Elm_Object_Item *)eina_list_data_get(list); + if (it) + item = (ViewItem *)elm_object_item_data_get(it); + else + DP_LOGE("genlist item is null"); + list = eina_list_next(list); + if (item) { + deleteQueue.push(item->historyId()); + item->destroy(); + } else { + DP_LOGE("viewItem is null"); + } + } + if (list) + eina_list_free(list); + + DownloadHistoryDB::deleteMultipleItem(deleteQueue); + showNotifyInfo(DOWNLOAD_NOTIFY_DELETED, checkedCount); + hideGenlistEditMode(); +} + +void DownloadView::showGenlistEditMode() +{ + DP_LOG_FUNC(); + /* Initialize notify info widget */ + destroyNotifyInfo(); + elm_object_item_text_set(eoNaviBarItem, S_("IDS_COM_OPT_DELETE")); + /* Change layoutbackground color to edit mode color */ + elm_object_style_set(eoBackground, "edit_mode"); + /* Disable the back button of control bar */ + elm_object_item_part_content_unset(eoNaviBarItem, "prev_btn"); + destroyEvasObj(eoBackBtn); + + if (eoCbItemEmpty) + elm_object_item_del(eoCbItemEmpty); + eoCbItemCancel = elm_toolbar_item_append(eoControlBar, NULL, + S_("IDS_COM_SK_CANCEL"), cbItemCancelCB, eoNaviBar); + + /* Append 'Select All' layout */ + createSelectAllLayout(); + /* Set reorder end edit mode */ + elm_genlist_reorder_mode_set(eoDldList, EINA_TRUE); + elm_genlist_decorate_mode_set(eoDldList, EINA_TRUE); + /* This means even if the ouside of checked box is selected, + it is same to click a check box. */ + elm_genlist_select_mode_set(eoDldList, ELM_OBJECT_SELECT_MODE_ALWAYS); + + Elm_Object_Item *it = NULL; + ViewItem *viewItem = NULL; + it = elm_genlist_first_item_get(eoDldList); + while (it) { + viewItem = (ViewItem *)elm_object_item_data_get(it); + if (elm_genlist_item_select_mode_get(it) != + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY && + viewItem && !(viewItem->isFinished())) + elm_object_item_disabled_set(it, EINA_TRUE); + it = elm_genlist_item_next_get(it); + } + elm_object_item_disabled_set(eoCbItemDelete, EINA_TRUE); +} + +void DownloadView::hideGenlistEditMode() +{ + DP_LOG_FUNC(); + + elm_object_item_text_set(eoNaviBarItem, __("IDS_BR_HEADER_DOWNLOAD_MANAGER")); + elm_object_style_set(eoBackground, "default"); + + /* Recreate back button */ + createBackBtn(); + elm_object_item_part_content_set(eoNaviBarItem, "prev_btn", eoBackBtn); + + if (eoCbItemCancel) { + elm_object_item_del(eoCbItemCancel); + eoCbItemCancel = NULL; + } + eoCbItemEmpty = elm_toolbar_item_append(eoControlBar, NULL, NULL, NULL, NULL); + elm_object_item_disabled_set(eoCbItemEmpty, EINA_TRUE); + + elm_box_unpack(eoBox, eoSelectAllLayout); + + destroyEvasObj(eoAllCheckedBox); + destroyEvasObj(eoSelectAllLayout); + + elm_genlist_reorder_mode_set(eoDldList, EINA_FALSE); + elm_genlist_decorate_mode_set(eoDldList, EINA_FALSE); + elm_genlist_select_mode_set(eoDldList, ELM_OBJECT_SELECT_MODE_DEFAULT); + + Elm_Object_Item *it = NULL; + ViewItem *viewItem = NULL; + it = elm_genlist_first_item_get(eoDldList); + while (it) { + viewItem = (ViewItem *)elm_object_item_data_get(it); + if (elm_genlist_item_select_mode_get(it) != + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY && viewItem) { + if (elm_object_item_disabled_get(it)) + elm_object_item_disabled_set(it, EINA_FALSE); + viewItem->setCheckedValue(EINA_FALSE); + viewItem->setCheckedBtn(NULL); + } + it = elm_genlist_item_next_get(it); + } + + m_allChecked = EINA_FALSE; + + if (m_viewItemCount < 1) { + elm_object_item_disabled_set(eoCbItemDelete, EINA_TRUE); + showEmptyView(); + } else + elm_object_item_disabled_set(eoCbItemDelete, EINA_FALSE); +} + +void DownloadView::handleChangedAllCheckedState() +{ + int checkedCount = 0; + Elm_Object_Item *it = NULL; + ViewItem *viewItem = NULL; + it = elm_genlist_first_item_get(eoDldList); + while (it) { + viewItem = (ViewItem *)elm_object_item_data_get(it); + if (elm_genlist_item_select_mode_get(it) != + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY && viewItem) { + if (viewItem->isFinished()) { + viewItem->setCheckedValue(m_allChecked); + viewItem->updateCheckedBtn(); + checkedCount++; + } + } + it = elm_genlist_item_next_get(it); + } + + if (m_allChecked && checkedCount > 0) { + elm_object_item_disabled_set(eoCbItemDelete, EINA_FALSE); + showNotifyInfo(DOWNLOAD_NOTIFY_SELECTED, checkedCount); + } else { + elm_object_item_disabled_set(eoCbItemDelete, EINA_TRUE); + showNotifyInfo(DOWNLOAD_NOTIFY_SELECTED, 0); + } +} + +void DownloadView::handleCheckedState() +{ + int checkedCount = 0; + int deleteAbleTotalCount = 0; + + DP_LOGD_FUNC(); + + Elm_Object_Item *it = NULL; + ViewItem *viewItem = NULL; + it = elm_genlist_first_item_get(eoDldList); + while (it) { + viewItem = (ViewItem *)elm_object_item_data_get(it); + if (elm_genlist_item_select_mode_get(it) != + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY && viewItem) { + if (viewItem->checkedValue()) + checkedCount++; + if (viewItem->isFinished()) + deleteAbleTotalCount++; + } + it = elm_genlist_item_next_get(it); + } + + if (checkedCount == deleteAbleTotalCount) + m_allChecked = EINA_TRUE; + else + m_allChecked = EINA_FALSE; + elm_check_state_pointer_set(eoAllCheckedBox, &m_allChecked); + + if (checkedCount == 0) { + elm_object_item_disabled_set(eoCbItemDelete, EINA_TRUE); + destroyNotifyInfo(); + } else + elm_object_item_disabled_set(eoCbItemDelete, EINA_FALSE); + showNotifyInfo(DOWNLOAD_NOTIFY_SELECTED, checkedCount); +} +void DownloadView::createNotifyInfo() +{ + DP_LOGD_FUNC(); + eoNotifyInfo = elm_notify_add(eoBoxLayout); + elm_notify_orient_set(eoNotifyInfo, ELM_NOTIFY_ORIENT_BOTTOM); + evas_object_size_hint_weight_set(eoNotifyInfo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(eoNotifyInfo, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_event_callback_add(eoNotifyInfo, EVAS_CALLBACK_SHOW, showNotifyInfoCB, eoLayout); + evas_object_event_callback_add(eoNotifyInfo, EVAS_CALLBACK_HIDE, hideNotifyInfoCB, eoLayout); + eoNotifyInfoLayout = elm_layout_add(eoNotifyInfo); + elm_object_content_set(eoNotifyInfo, eoNotifyInfoLayout); +} + +void DownloadView::showNotifyInfo(int type, int selectedCount) +{ + string buf; + DP_LOGD_FUNC(); + + if (selectedCount == 0) { + destroyNotifyInfo(); + return; + } + + if (!eoNotifyInfo) + createNotifyInfo(); + + elm_layout_theme_set(eoNotifyInfoLayout, "standard", "selectioninfo", + "vertical/bottom_12"); + buf.append(" "); + if (type == DOWNLOAD_NOTIFY_SELECTED) { + stringstream countStr; + countStr << selectedCount; + buf = S_("IDS_COM_BODY_SELECTED"); + buf.append(" ("); + buf.append(countStr.str()); + buf.append(")"); + } else if (type == DOWNLOAD_NOTIFY_DELETED) { + buf = S_("IDS_COM_POP_DELETED"); + elm_notify_timeout_set(eoNotifyInfo, 3); + } + edje_object_part_text_set(_EDJ(eoNotifyInfoLayout), "elm.text", buf.c_str()); + evas_object_show(eoNotifyInfo); +} + +void DownloadView::destroyNotifyInfo() +{ + DP_LOGD_FUNC(); + destroyEvasObj(eoNotifyInfoLayout); + destroyEvasObj(eoNotifyInfo); + eoNotifyInfoLayout = NULL; + eoNotifyInfo = NULL; +} + +/* Static callback function */ +void DownloadView::showNotifyInfoCB(void *data, Evas *evas, Evas_Object *obj, + void *event) +{ + Evas_Object *layout = (Evas_Object *)data; + if (!data) { + DP_LOGE("data is NULL"); + return; + } + edje_object_signal_emit(_EDJ(layout), "elm,layout,content,bottom_padding", + "layout"); +} + +void DownloadView::hideNotifyInfoCB(void *data, Evas *evas, Evas_Object *obj, + void *event) +{ + Evas_Object *layout = (Evas_Object *)data; + if (!data) { + DP_LOGE("data is NULL"); + return; + } + edje_object_signal_emit(_EDJ(layout), "elm,layout,content,default", "layout"); +} + +void DownloadView::selectAllClickedCB(void *data, Evas *evas, Evas_Object *obj, + void *event_info) +{ + DownloadView &view = DownloadView::getInstance(); + DP_LOGD_FUNC(); + view.changeAllCheckedValue(); +} + +void DownloadView::selectAllChangedCB(void *data, Evas_Object *obj, + void *event_info) +{ + DownloadView &view = DownloadView::getInstance(); + DP_LOGD_FUNC(); + view.handleChangedAllCheckedState(); +} + +void DownloadView::backBtnCB(void *data, Evas_Object *obj, void *event_info) +{ + DownloadView& view = DownloadView::getInstance(); + view.hide(); +} + +void DownloadView::cbItemDeleteCB(void *data, Evas_Object *obj, void *event_info) +{ + + DownloadView& view = DownloadView::getInstance(); + if (!view.isGenlistEditMode()) + view.showGenlistEditMode(); + else + view.destroyCheckedItem(); +} + +void DownloadView::cbItemCancelCB(void *data, Evas_Object *obj, void *event_info) +{ + DownloadView& view = DownloadView::getInstance(); + view.destroyNotifyInfo(); + view.hideGenlistEditMode(); +} + +void DownloadView::genlistClickCB(void *data, Evas_Object *obj, void *event_info) +{ + ViewItem *item = reinterpret_cast<ViewItem *>(data); + DP_LOGD_FUNC(); + if (!data) { + DP_LOGE("data is NULL"); + return; + } + item->clickedGenlistItem(); +} + +void DownloadView::cancelClickCB(void *data, Evas_Object *obj, void *event_info) +{ + ViewItem *item = NULL; + + DP_LOGD_FUNC(); + + if (!data) { + DP_LOGE("data is NULL"); + return; + } + item = reinterpret_cast<ViewItem *>(data); + item->requestCancel(); + +} + +void DownloadView::showErrPopup(string &desc) +{ + removePopup(); + + eoPopup = elm_popup_add(eoWindow); + evas_object_size_hint_weight_set(eoPopup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(eoPopup, desc.c_str()); + elm_popup_timeout_set(eoPopup, 2); + evas_object_smart_callback_add(eoPopup, "response", errPopupResponseCB, NULL); + evas_object_show(eoPopup); +} + +void DownloadView::showOMAPopup(string &msg, ViewItem *viewItem) +{ + Evas_Object *btn1 = NULL; + Evas_Object *btn2 = NULL; + DP_LOGD_FUNC(); + /* If another popup is shown, delete it*/ + removePopup(); + eoPopup = elm_popup_add(eoWindow); + evas_object_size_hint_weight_set(eoPopup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(eoPopup, msg.c_str()); + elm_object_part_text_set(eoPopup, "title,text", __("IDS_BR_POP_DOWNLOAD_Q")); + btn1 = elm_button_add(eoPopup); + elm_object_text_set(btn1, S_("IDS_COM_SK_OK")); + elm_object_part_content_set(eoPopup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", omaPopupResponseOKCB, + viewItem); + btn2 = elm_button_add(eoPopup); + elm_object_text_set(btn2, S_("IDS_COM_POP_CANCEL")); + elm_object_part_content_set(eoPopup, "button2", btn2); + evas_object_smart_callback_add(btn2, "clicked", omaPopupResponseCancelCB, + viewItem); + evas_object_show(eoPopup); +} + +void DownloadView::errPopupResponseCB(void *data, Evas_Object *obj, void *event_info) +{ + DP_LOGD_FUNC(); + DownloadView& view = DownloadView::getInstance(); + view.removePopup(); +} + +void DownloadView::omaPopupResponseOKCB(void *data, Evas_Object *obj, + void *event_info) +{ + ViewItem *viewItem = (ViewItem *)data; + DownloadView& view = DownloadView::getInstance(); + + DP_LOGD_FUNC(); + if (viewItem) + viewItem->sendUserResponse(true); + else + DP_LOGE("No viewItem"); + view.removePopup(); +} + +void DownloadView::omaPopupResponseCancelCB(void *data, Evas_Object *obj, + void *event_info) +{ + ViewItem *viewItem = (ViewItem *)data; + DownloadView& view = DownloadView::getInstance(); + + DP_LOGD_FUNC(); + if (viewItem) + viewItem->sendUserResponse(false); + else + DP_LOGE("No viewItem"); + view.removePopup(); +} + +void DownloadView::removePopup() +{ + DP_LOGD_FUNC(); + destroyEvasObj(eoPopup); +} + +DateGroup *DownloadView::getDateGroupObj(int type) +{ + DateGroup *obj = NULL; + switch (type) { + case DATETIME::DATE_TYPE_LATER: + case DATETIME::DATE_TYPE_TODAY: + obj = &m_today; + break; + case DATETIME::DATE_TYPE_YESTERDAY: + obj = &m_yesterday; + break; + case DATETIME::DATE_TYPE_PREVIOUS: + obj = &m_previousDay; + break; + default: + obj = NULL; + DP_LOGE("Cannot enter here"); + } + return obj; +} + +Elm_Object_Item *DownloadView::getGenlistGroupItem(int type) +{ + DateGroup *obj = getDateGroupObj(type); + if (!obj) + return NULL; + return obj->glGroupItem(); +} + +void DownloadView::setGenlistGroupItem(int type, Elm_Object_Item *item) +{ + DateGroup *obj = getDateGroupObj(type); + if (!obj) + return; + obj->setGlGroupItem(item); +} + +void DownloadView::increaseGenlistGroupCount(int type) +{ + DateGroup *obj = getDateGroupObj(type); + if (!obj) + return; + if (type == DATETIME::DATE_TYPE_TODAY || type == DATETIME::DATE_TYPE_LATER) { + if (m_today.getCount() < 1) { + DateUtil &inst = DateUtil::getInstance(); + inst.setTodayStandardTime(); + } + } + obj->increaseCount(); + DP_LOGD("increased count[%d]",obj->getCount()); +} + +int DownloadView::getGenlistGroupCount(int type) +{ + DateGroup *obj = getDateGroupObj(type); + if (!obj) + return 0; + DP_LOGD("Group count[%d]",obj->getCount()); + return obj->getCount(); +} + +void DownloadView::handleGenlistGroupItem(int type) +{ + DateGroup *obj = getDateGroupObj(type); + if (!obj) + return; + obj->decreaseCount(); + DP_LOGD("count[%d]type[%d]",obj->getCount(),type); + if (obj->getCount() < 1) { + //DP_LOGD("Group Item[%p][%d]", obj->glGroupItem(),type); + elm_object_item_del(obj->glGroupItem()); + obj->setGlGroupItem(NULL); + } +} + +void DownloadView::handleUpdateDateGroupType(ViewItem *viewItem) +{ + int diffDays = 0; + DateUtil &inst = DateUtil::getInstance(); + DP_LOGD_FUNC(); + diffDays = inst.getDiffDaysFromToday(); + if (viewItem) { + /* Update a view item which is added now + * This should be only called when attaching item + **/ + viewItem->extractDateGroupType(); + } else if (diffDays != 0) { + /* FIXME later + * Now, it is recreated download items and group items. + * Consider to move only group item later. + * This should be only called from show() function + **/ +/* FIXME later + * Another problem is happend becuase eina list is used repacing with vector */ +#if 0 + cleanGenlistData(); + Elm_Object_Item *it = NULL; + ViewItem *viewItem = NULL; + it = elm_genlist_first_item_get(eoDldList); + while (it) { + viewItem = (ViewItem *)elm_object_item_data_get(it); + if (!viewItem || elm_genlist_item_select_mode_get(it) != + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) + continue; + viewItem->extractDateGroupType(); + createGenlistItem(viewItem); + it = elm_genlist_item_next_get(it); + } +#endif + } + inst.setTodayStandardTime(); +} + +void DownloadView::moveRetryItem(ViewItem *viewItem) +{ + Elm_Object_Item *todayGroupItem = NULL; + Elm_Object_Item *firstItem = NULL; + DP_LOGD_FUNC(); + if (!viewItem) { + DP_LOGE("view item is NULL"); + return; + } + firstItem = elm_genlist_first_item_get(eoDldList); + if (firstItem) { + DP_LOGD("groupItem[%p] viewItem[%p]", firstItem, viewItem); + /* This is group item */ + if (elm_genlist_item_select_mode_get(firstItem) == + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) { + /* The top item is the item after group item */ + firstItem = elm_genlist_item_next_get(firstItem); + DP_LOGD("firstItem[%p], present item[%p]", firstItem, viewItem->genlistItem()); + if (firstItem == viewItem->genlistItem()) { + DP_LOGD("This is already top item. Don't need to move"); + return; + } + } + } + elm_object_item_del(viewItem->genlistItem()); + viewItem->setGenlistItem(NULL); + handleGenlistGroupItem(viewItem->dateGroupType()); + todayGroupItem = getGenlistGroupItem(DATETIME::DATE_TYPE_TODAY); + if (!todayGroupItem) { + DateGroup *dateGrpObj = getDateGroupObj(DATETIME::DATE_TYPE_TODAY); + todayGroupItem = elm_genlist_item_prepend( + eoDldList, + &dldGenlistGroupStyle, + static_cast<const void*>(dateGrpObj), + NULL, + ELM_GENLIST_ITEM_GROUP, + NULL, + NULL); + setGenlistGroupItem(DATETIME::DATE_TYPE_TODAY, todayGroupItem); + if (!todayGroupItem) + DP_LOGE("Fail to add a genlist group item"); + else + elm_genlist_item_select_mode_set(todayGroupItem, + ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + increaseGenlistGroupCount(DATETIME::DATE_TYPE_TODAY); + Elm_Object_Item *glItem = elm_genlist_item_insert_after( + eoDldList, + viewItem->elmGenlistStyle(), + static_cast<const void*>(viewItem), + todayGroupItem, + todayGroupItem, + ELM_GENLIST_ITEM_NONE, + genlistClickCB, + static_cast<const void*>(viewItem)); + if (!glItem) + DP_LOGE("Fail to add a genlist item"); + DP_LOGD("genlist groupItem[%p] item[%p] viewItem[%p]", todayGroupItem, + glItem, viewItem); + viewItem->setGenlistItem(glItem); + elm_genlist_item_show(todayGroupItem, ELM_GENLIST_ITEM_SCROLLTO_TOP); + viewItem->extractDateGroupType(); +} + +char *DownloadView::getGenlistGroupLabel(void *data, Evas_Object *obj, const char *part) +{ + DateGroup *dateGrp = static_cast<DateGroup *>(data); + + if(!data || !obj || !part) + return NULL; + + DP_LOGD("ViewItem::getListGroupLabel:part[%s] groupDateType[%d] obj[%p]", part, dateGrp->getType(), obj); + if (strncmp(part, "elm.text", strlen("elm.text")) == 0) { + DateUtil &inst = DateUtil::getInstance(); + string msg; + string outBuf; + double udateTime = 0; + switch (dateGrp->getType()) { + case DATETIME::DATE_TYPE_PREVIOUS: + msg = S_("IDS_COM_BODY_PREVIOUS_DAYS"); + break; + case DATETIME::DATE_TYPE_YESTERDAY: + udateTime = inst.yesterdayTime()*1000; + msg = S_("IDS_COM_BODY_YESTERDAY"); + msg += " ("; + inst.getDateStr(LOCALE_STYLE::FULL_DATE, udateTime, outBuf); + msg += outBuf; + msg += ")"; + break; + case DATETIME::DATE_TYPE_LATER: + case DATETIME::DATE_TYPE_TODAY: + udateTime = inst.nowTime()*1000; + msg = S_("IDS_COM_BODY_TODAY"); + msg += " ("; + inst.getDateStr(LOCALE_STYLE::FULL_DATE, udateTime, outBuf); + msg += outBuf; + msg += ")"; + break; + default : + DP_LOGE("Cannot enter here"); + return NULL; + } + return strdup(msg.c_str()); + } + return NULL; +} + +char *DownloadView::getGenlistGroupLabelCB(void *data, Evas_Object *obj, const char *part) +{ +// DP_LOGD_FUNC(); + if(!data || !obj || !part) + return NULL; + + DownloadView &view = DownloadView::getInstance(); + return view.getGenlistGroupLabel(data, obj, part); +} + +void DownloadView::cleanGenlistData() +{ + Elm_Object_Item *grpItem = NULL; + DP_LOGD_FUNC(); + grpItem = m_today.glGroupItem(); + if (grpItem) + elm_object_item_del(grpItem); + m_today.initData(); + grpItem = m_yesterday.glGroupItem(); + if (grpItem) + elm_object_item_del(grpItem); + m_yesterday.initData(); + grpItem = m_previousDay.glGroupItem(); + if (grpItem) + elm_object_item_del(grpItem); + m_previousDay.initData(); + elm_genlist_clear(eoDldList); +} + diff --git a/src/download-provider-viewItem.cpp b/src/download-provider-viewItem.cpp new file mode 100644 index 0000000..2f4ca8a --- /dev/null +++ b/src/download-provider-viewItem.cpp @@ -0,0 +1,580 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-viewItem.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief item data class for download view + */ +#include "download-provider-viewItem.h" +#include "download-provider-items.h" +#include "download-provider-view.h" + +ViewItem::ViewItem(Item *item) + : m_item(item) + , m_glItem(NULL) + , m_progressBar(NULL) + , m_checkedBtn(NULL) + , m_checked(EINA_FALSE) + , m_isRetryCase(false) + , m_dateGroupType(DATETIME::DATE_TYPE_NONE) +{ + // FIXME need to makes exchange subject?? not yet, but keep it in mind! + if (item) { + m_aptr_observer = auto_ptr<Observer>( + new Observer(updateCB, this, "viewItemObserver")); + item->subscribe(m_aptr_observer.get()); + } + + dldGenlistStyle.item_style = "3text.3icon"; + dldGenlistStyle.func.text_get = getGenlistLabelCB; + dldGenlistStyle.func.content_get = getGenlistIconCB; + dldGenlistStyle.func.state_get = NULL; + dldGenlistStyle.func.del = NULL; + dldGenlistStyle.decorate_all_item_style = "edit_default"; + + dldHistoryGenlistStyle.item_style = "3text.1icon.2"; + dldHistoryGenlistStyle.func.text_get = getGenlistLabelCB; + dldHistoryGenlistStyle.func.content_get = getGenlistIconCB; + dldHistoryGenlistStyle.func.state_get = NULL; + dldHistoryGenlistStyle.func.del = NULL; + dldHistoryGenlistStyle.decorate_all_item_style = "edit_default"; + + dldGenlistSlideStyle.item_style = "3text.1icon.2"; + dldGenlistSlideStyle.func.text_get = getGenlistLabelCB; + dldGenlistSlideStyle.func.content_get= getGenlistIconCB; + dldGenlistSlideStyle.func.state_get = NULL; + dldGenlistSlideStyle.func.del = NULL; + dldGenlistSlideStyle.decorate_all_item_style = "edit_default"; + +} + +ViewItem::~ViewItem() +{ + DP_LOGD_FUNC(); +} + +void ViewItem::create(Item *item) +{ + ViewItem *newViewItem = new ViewItem(item); + + DownloadView &view = DownloadView::getInstance(); + view.attachViewItem(newViewItem); +} + +void ViewItem::destroy() +{ + DP_LOGD("ViewItem::destroy"); + /* After item is destory, + view item also will be destroyed through event system */ + if (m_item) + m_item->destroy(); +} + +void ViewItem::updateCB(void *data) +{ + if (data) + static_cast<ViewItem*>(data)->updateFromItem(); +} + +void ViewItem::updateFromItem() +{ + DownloadView &view = DownloadView::getInstance(); + DP_LOGD("ViewItem::updateFromItem() ITEM::[%d]", state()); + if (state() == ITEM::DESTROY) { + int tempType = 0; + DP_LOGD("ViewItem::updateFromItem() ITEM::DESTROY"); + if (m_item) + m_item->deSubscribe(m_aptr_observer.get()); + m_aptr_observer->clear(); + elm_object_item_del(m_glItem); + m_glItem = NULL; + tempType = dateGroupType(); + view.detachViewItem(this); + view.handleGenlistGroupItem(tempType); + return; + } + + if (state() == ITEM::WAITING_USER_RESPONSE) { + string buf; + buf.append("Name : "); + buf.append(m_item->contentName()); + buf.append("<br>"); + buf.append("Size : "); + buf.append(getHumanFriendlyBytesStr(fileSize(), false)); + buf.append("<br>"); + buf.append("Vendor : "); + buf.append(m_item->vendorName()); + buf.append("<br>"); + if (m_item->isMidletInstalled()) { + buf.append("<br>"); + buf.append(S_("IDS_COM_POP_ALREDY_EXISTS")); + buf.append("<br>"); + buf.append("Want to update?"); + } + view.showOMAPopup(buf, this); + return; + } + + if (state() == ITEM::DOWNLOADING) { + if (fileSize() > 0 && m_progressBar) { + double percentageProgress = 0.0; + percentageProgress = (double)(receivedFileSize()) / + (double)(fileSize()); + DP_LOGD("progress value[%.2f]",percentageProgress); + elm_progressbar_value_set(m_progressBar, percentageProgress); + } + elm_genlist_item_fields_update(m_glItem,"elm.text.2", + ELM_GENLIST_ITEM_FIELD_TEXT); + } else if (m_isRetryCase && state() == ITEM::RECEIVING_DOWNLOAD_INFO) { + elm_genlist_item_item_class_update(m_glItem, &dldGenlistStyle); + } else if (!isFinished()) { + elm_genlist_item_update(m_glItem); + } else {/* finished state */ + if (state() == ITEM::FINISH_DOWNLOAD) + elm_genlist_item_item_class_update(m_glItem, &dldHistoryGenlistStyle); + else + elm_genlist_item_item_class_update(m_glItem, &dldGenlistSlideStyle); + if (view.isGenlistEditMode()) + elm_object_item_disabled_set(m_glItem, EINA_FALSE); + } +} + +char *ViewItem::getGenlistLabelCB(void *data, Evas_Object *obj, const char *part) +{ +// DP_LOGD_FUNC(); + + if(!data || !obj || !part) + return NULL; + + ViewItem *item = static_cast<ViewItem *>(data); + return item->getGenlistLabel(obj, part); +} + +char *ViewItem::getGenlistLabel(Evas_Object *obj, const char *part) +{ + DP_LOGD("ViewItem::getListLabel:part[%s]", part); + + if (strncmp(part, "elm.text.1", strlen("elm.text.1")) == 0) { + return strdup(getTitle()); + } else if (strncmp(part, "elm.text.2", strlen("elm.text.2")) == 0) { + return strdup(getMessage()); + } else if (strncmp(part, "elm.text.3", strlen("elm.text.3")) == 0) { + if (!isFinished()) { + return NULL; + } else { + string outBuf; + DateUtil &inst = DateUtil::getInstance(); + double udateTime = finishedTime() * 1000; + if (dateGroupType() == DATETIME::DATE_TYPE_PREVIOUS + || dateGroupType() == DATETIME::DATE_TYPE_LATER) + inst.getDateStr(LOCALE_STYLE::SHORT_DATE, udateTime, outBuf); + else + inst.getDateStr(LOCALE_STYLE::TIME, udateTime, outBuf); + return strdup(outBuf.c_str()); + } + } else { + DP_LOGD("No Implementation"); + return NULL; + } +} + +Evas_Object *ViewItem::getGenlistIconCB(void *data, Evas_Object *obj, + const char *part) +{ +// DP_LOGD_FUNC(); + if(!data || !obj || !part) { + DP_LOGE("parameter is NULL"); + return NULL; + } + + ViewItem *item = static_cast<ViewItem *>(data); + return item->getGenlistIcon(obj, part); +} + +Evas_Object *ViewItem::getGenlistIcon(Evas_Object *obj, const char *part) +{ + //DP_LOGD("ViewItem::getGenlistIcon:part[%s]state[%s]", part, stateStr()); + + if (elm_genlist_decorate_mode_get(obj) && isFinished()) { + if (strncmp(part,"elm.edit.icon.1", strlen("elm.edit.icon.1")) == 0) { + Evas_Object *checkBtn = elm_check_add(obj); + elm_check_state_pointer_set(checkBtn, &m_checked); + evas_object_smart_callback_add(checkBtn, "changed", checkChangedCB, + this); + m_checkedBtn = checkBtn; + return checkBtn; + } else if (strncmp(part,"elm.edit.icon.2", strlen("elm.edit.icon.2")) == + 0) { + return NULL; + } + + } + /* elm.icon.2 should be checked prior to elm.icon */ + if (strncmp(part,"elm.icon.2", strlen("elm.icon.2")) == 0) { + if (state() == ITEM::RECEIVING_DOWNLOAD_INFO || + state() == ITEM::PREPARE_TO_RETRY || + state() == ITEM::DOWNLOADING || + isPreparingDownload()) + return createCancelBtn(obj); + else + return NULL; + } else if (strncmp(part,"elm.icon.1", strlen("elm.icon.1")) == 0 || + strncmp(part, "elm.icon", strlen("elm.icon")) == 0) { +// if (strncmp(part,"elm.icon.1", strlen("elm.icon.1")) == 0) { + Evas_Object *icon = elm_icon_add(obj); + elm_icon_file_set(icon, getIconPath(), NULL); + evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL,1,1); + return icon; + } else if (strcmp(part,"elm.swallow.progress") == 0) { + return createProgressBar(obj); + } else { + DP_LOGE("Cannot enter here"); + return NULL; + } +} + +void ViewItem::checkChangedCB(void *data, Evas_Object *obj, + void *event_info) +{ + DownloadView &view = DownloadView::getInstance(); + DP_LOGD_FUNC(); + //ViewItem *item = static_cast<ViewItem *>(data); + //DP_LOGD("checked[%d] viewItem[%p]",(bool)(item->checkedValue()),item); + view.handleCheckedState(); +} + +void ViewItem::clickedDeleteButton() +{ + DP_LOGD("ViewItem::clickedDeleteButton()"); + m_item->deleteFromDB(); + destroy(); +} + +void ViewItem::clickedCancelButton() +{ + DP_LOG("ViewItem::clickedCancelButton()"); + requestCancel(); +} + +void ViewItem::requestCancel() +{ + if (m_item) { + m_item->cancel(); + } +} + +void ViewItem::clickedRetryButton() +{ + DP_LOG_FUNC(); + retryViewItem(); +} + +void ViewItem::clickedGenlistItem() +{ + DownloadView &view = DownloadView::getInstance(); + DP_LOG_FUNC(); + if (!m_item) { + DP_LOGE("m_item is NULL"); + return; + } + if (view.isGenlistEditMode()) { + m_checked = !m_checked; + if (m_checkedBtn) + elm_genlist_item_fields_update(genlistItem(),"elm.edit.icon.1", + ELM_GENLIST_ITEM_FIELD_CONTENT); + else + DP_LOGE("m_checkedBtn is NULL"); + view.handleCheckedState(); + } else if (state() == ITEM::FINISH_DOWNLOAD) { + bool ret = m_item->play(); + if (ret == false) { + string desc = __("IDS_BR_POP_UNABLE_TO_OPEN_FILE"); + view.showErrPopup(desc); + } + } else if (isFinishedWithErr()) { + retryViewItem(); + } + elm_genlist_item_selected_set(genlistItem(), EINA_FALSE); +} + +Elm_Genlist_Item_Class *ViewItem::elmGenlistStyle() +{ + /* Change the genlist style class in case of download history item */ + if (state() == ITEM::FINISH_DOWNLOAD) + return &dldHistoryGenlistStyle; + else if (isFinishedWithErr()) + return &dldGenlistSlideStyle; + else + return &dldGenlistStyle; +} + +const char *ViewItem::getMessage() +{ + DP_LOGD("ViewItem state() ITEM::[%d]", state()); + const char *buff = NULL; + switch(state()) { + case ITEM::IDLE: + case ITEM::REQUESTING: + case ITEM::PREPARE_TO_RETRY: + case ITEM::WAITING_USER_RESPONSE: + case ITEM::RECEIVING_DOWNLOAD_INFO: + /* Do not display string and show only the progress bar */ +// buff = __("Check for download"); + buff = ""; + break; + case ITEM::DOWNLOADING: + buff = getHumanFriendlyBytesStr(receivedFileSize(), true); +// DP_LOGD("%s", buff); + break; + case ITEM::CANCEL: + buff = S_("IDS_COM_POP_CANCELLED"); + break; + case ITEM::FAIL_TO_DOWNLOAD: + buff = getErrMsg(); + break; + case ITEM::REGISTERING_TO_SYSTEM: + buff = S_("IDS_COM_POP_INSTALLING_ING"); + break; + case ITEM::ACTIVATING: + buff = S_("IDS_COM_POP_ACTIVATING"); + break; + case ITEM::NOTIFYING_TO_SERVER: + buff = __("IDS_BR_BODY_NOTIFYING_ING"); + break; + case ITEM::PROCESSING_DOMAIN: + buff = S_("IDS_COM_POP_PROCESSING"); + break; + case ITEM::FINISH_PROCESSING_DOMAIN: + buff = __("IDS_BR_BODY_PROCESSING_COMPLETED"); + break; + case ITEM::FINISH_DOWNLOAD: + buff = __("IDS_EMAIL_BODY_COMPLETE"); + break; + default: + buff = ""; + break; + } + return buff; +} + +const char *ViewItem::getHumanFriendlyBytesStr(unsigned long int bytes, + bool progressOption) +{ + double doubleTypeBytes = 0.0; + const char *unitStr[4] = {"B", "KB", "MB", "GB"}; + int unit = 0; + unsigned long int unitBytes = bytes; + + /* using bit operation to avoid floating point arithmetic */ + for (unit=0; (unitBytes > 1024 && unit < 4) ; unit++) { + unitBytes = unitBytes >> 10; + } + + unitBytes = 1 << (10*unit); + doubleTypeBytes = ((double)bytes / (double)(unitBytes)); + // FIXME following code should be broken into another function, but leave it now to save function call time.s + char str[32] = {0}; + if (progressOption && fileSize() != 0) { + /* using fixed point arithmetic to avoid floating point arithmetic */ + const int fixed_point = 6; + unsigned long long int receivedBytes = receivedFileSize() << fixed_point; + unsigned long long int result = (receivedBytes*100) / fileSize(); + unsigned long long int result_int = result >> fixed_point; + unsigned long long int result_fraction = result & + ~(0xFFFFFFFF << fixed_point); + if (unit == 0) + snprintf(str, sizeof(str), "%lu %s / %llu.%.2llu %%", + bytes, unitStr[unit], result_int, result_fraction); + else + snprintf(str, sizeof(str), "%.2f %s / %llu.%.2llu %%", + doubleTypeBytes, unitStr[unit], result_int, result_fraction); + } else { + if (unit == 0) + snprintf(str, sizeof(str), "%lu %s", bytes, unitStr[unit]); + else + snprintf(str, sizeof(str), "%.2f %s", doubleTypeBytes, unitStr[unit]); + } + return string(str).c_str(); +} + +unsigned long int ViewItem::receivedFileSize() +{ + if (m_item) + return m_item->receivedFileSize(); + + return 0; +} + +unsigned long int ViewItem::fileSize() +{ + if (m_item) + return m_item->fileSize(); + + return 0; +} + +const char *ViewItem::getTitle() +{ + const char *title = NULL; + if (m_item) + title = m_item->title().c_str(); + + if (!title) + return S_("IDS_COM_BODY_NO_NAME"); + + return title; +} + +Evas_Object *ViewItem::createProgressBar(Evas_Object *parent) +{ + Evas_Object *progress = NULL; + if (!parent) { + DP_LOGE("parent is NULL"); + return NULL; + } + progress = elm_progressbar_add(parent); + setProgressBar(progress); + if (isFinished()) { + DP_LOGE("Cannot enter here. finished item has othere genlist style"); + return NULL; + } + + if (fileSize() == 0 || isPreparingDownload()) { + //DP_LOGD("Pending style::progressBar[%p]",progress); + elm_object_style_set(progress, "pending_list"); + elm_progressbar_horizontal_set(progress, EINA_TRUE); + evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(progress, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_progressbar_pulse(progress, EINA_TRUE); + } else { + //DP_LOGD("List style::progressBar[%p] fileSize[%d] state[%d]",progress, fileSize(),state()); + elm_object_style_set(progress, "list_progress"); + elm_progressbar_horizontal_set(progress, EINA_TRUE); + + if (isCompletedDownload()) + elm_progressbar_value_set(progress, 1.0); + /* When realized event is happened, the progress is created. + This is needed for that case */ + else if (state() == ITEM::DOWNLOADING) { + double percentageProgress = 0.0; + percentageProgress = (double)(receivedFileSize()) / + (double)(fileSize()); + elm_progressbar_value_set(progress, percentageProgress); + } + } + evas_object_show(progress); + return progress; +} + +void ViewItem::updateCheckedBtn() +{ + if (m_checkedBtn) + elm_check_state_pointer_set(m_checkedBtn,&m_checked); +} + +void ViewItem::deleteBtnClickedCB(void *data, Evas_Object *obj, void *event_info) +{ + DP_LOGD_FUNC(); + if (!data) { + DP_LOGE("data is NULL"); + return; + } + ViewItem *viewItem = static_cast<ViewItem *>(data); + viewItem->clickedDeleteButton(); +} + +void ViewItem::retryBtnClickedCB(void *data, Evas_Object *obj, void *event_info) +{ + DP_LOGD_FUNC(); + if (!data) { + DP_LOGE("data is NULL"); + return; + } + ViewItem *viewItem = static_cast<ViewItem *>(data); + viewItem->clickedRetryButton(); +} + +Evas_Object *ViewItem::createCancelBtn(Evas_Object *parent) +{ + DP_LOGD_FUNC(); + Evas_Object *button = elm_button_add(parent); + elm_object_part_content_set(parent, "btn_style1", button); + elm_object_style_set(button, "style1/auto_expand"); + evas_object_size_hint_aspect_set(button, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + elm_object_text_set(button, S_("IDS_COM_SK_CANCEL")); + evas_object_propagate_events_set(button, EINA_FALSE); + evas_object_smart_callback_add(button,"clicked", cancelBtnClickedCB, this); + return button; +} + +void ViewItem::cancelBtnClickedCB(void *data, Evas_Object *obj, void *event_info) +{ + DP_LOGD_FUNC(); + if (!data) { + DP_LOGE("data is NULL"); + return; + } + ViewItem *viewItem = static_cast<ViewItem *>(data); + viewItem->clickedCancelButton(); +} + +void ViewItem::extractDateGroupType() +{ + DP_LOGD_FUNC(); + /* History Item */ + //DP_LOGD("state[%s],finishedTime[%ld]",stateStr(),finishedTime()); + if (isFinished() && finishedTime() > 0) { + int diffDay = 0; + DateUtil &inst = DateUtil::getInstance(); + double nowTime = inst.nowTime(); + double finishTime = finishedTime(); + diffDay = inst.getDiffDays((time_t)nowTime, (time_t)finishTime); + if (diffDay == 0) + m_dateGroupType = DATETIME::DATE_TYPE_TODAY; + else if (diffDay == 1) + m_dateGroupType = DATETIME::DATE_TYPE_YESTERDAY; + else if (diffDay > 1) + m_dateGroupType = DATETIME::DATE_TYPE_PREVIOUS; + else + m_dateGroupType = DATETIME::DATE_TYPE_LATER; + return; + } + /* Item which is added now or retrying item */ + m_dateGroupType = DATETIME::DATE_TYPE_TODAY; +} + + +void ViewItem::retryViewItem(void) +{ + DownloadView &view = DownloadView::getInstance(); + DP_LOGD_FUNC(); + if (m_item) { + m_isRetryCase = true; + m_item->clearForRetry(); + if (!m_item->retry()) { + DownloadView &view = DownloadView::getInstance(); + string desc = S_("IDS_COM_POP_FAILED"); + view.showErrPopup(desc); + m_item->deleteFromDB(); + m_item->destroy(); + return; + } + /* Move a item to Today group, if it is not included to Today group */ + view.moveRetryItem(this); + } +} diff --git a/src/include/download-provider-common.h b/src/include/download-provider-common.h new file mode 100644 index 0000000..4131c0d --- /dev/null +++ b/src/include/download-provider-common.h @@ -0,0 +1,103 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-common.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Common define and data + */ + +#ifndef DOWNLOAD_PROVIDER_DOWNLOAD_COMMON_H +#define DOWNLOAD_PROVIDER_DOWNLOAD_COMMON_H + +#include <libintl.h> +#include "download-provider-debug.h" + +#if !defined(PACKAGE) + #define PACKAGE "download-provider" +#endif + +#define _EDJ(o) elm_layout_edje_get(o) +#define __(s) dgettext(PACKAGE, s) +#define S_(s) dgettext("sys_string", s) + +#define ERROR_POPUP_LOW_MEM S_("IDS_COM_POP_NOT_ENOUGH_MEMORY") +#define ERROR_POPUP_UNKNOWN S_("IDS_COM_POP_INTERNAL_ERROR") +#define ERROR_POPUP_INVALID_URL S_("IDS_COM_POP_INVALID_URL") + +#define DP_DRM_ICON_PATH IMAGEDIR"/U06_icon_DRM.png" +#define DP_JAVA_ICON_PATH IMAGEDIR"/U06_icon_Java.png" +#define DP_UNKNOWN_ICON_PATH IMAGEDIR"/U06_icon_Unknown.png" +#define DP_EXCEL_ICON_PATH IMAGEDIR"/U06_icon_excel.png" +#define DP_HTML_ICON_PATH IMAGEDIR"/U06_icon_html.png" +#define DP_MUSIC_ICON_PATH IMAGEDIR"/U06_icon_music.png" +#define DP_PDF_ICON_PATH IMAGEDIR"/U06_icon_pdf.png" +#define DP_PPT_ICON_PATH IMAGEDIR"/U06_icon_ppt.png" +#define DP_RINGTONE_ICON_PATH IMAGEDIR"/U06_icon_ringtone.png" +#define DP_TEXT_ICON_PATH IMAGEDIR"/U06_icon_text.png" +#define DP_WORD_ICON_PATH IMAGEDIR"/U06_icon_word.png" +#define DP_VIDEO_ICON_PATH IMAGEDIR"/U06_icon_video.png" +#define DP_IMAGE_ICON_PATH IMAGEDIR"/U06_icon_image.png" + +#define MAX_FILE_PATH_LEN 256 +#define MAX_BUF_LEN 256 + +#define LOAD_HISTORY_COUNT 500 + +enum +{ + DP_CONTENT_NONE = 0, + DP_CONTENT_IMAGE, + DP_CONTENT_VIDEO, + DP_CONTENT_MUSIC, + DP_CONTENT_PDF, + DP_CONTENT_WORD, + DP_CONTENT_PPT, // 5 + DP_CONTENT_EXCEL, + DP_CONTENT_HTML, + DP_CONTENT_TEXT, + DP_CONTENT_RINGTONE, + DP_CONTENT_DRM, // 10 + DP_CONTENT_JAVA, + DP_CONTENT_SVG, + DP_CONTENT_FLASH, + DP_CONTENT_UNKOWN +}; + +namespace DL_TYPE{ +enum TYPE { + TYPE_NONE, + HTTP_DOWNLOAD, + OMA_DOWNLOAD, + MIDP_DOWNLOAD +}; +} + +namespace ERROR { +enum CODE { + NONE, + INVALID_URL, + NETWORK_FAIL, + NOT_ENOUGH_MEMORY, + FAIL_TO_INSTALL, + FAIL_TO_PARSE_DESCRIPTOR, + OMA_POPUP_TIME_OUT, + ENGINE_FAIL, + UNKNOWN +}; +} + +#endif /* DOWNLOAD_PROVIDER_DOWNLOAD_COMMON_H */ diff --git a/src/include/download-provider-dateTime.h b/src/include/download-provider-dateTime.h new file mode 100644 index 0000000..87caf11 --- /dev/null +++ b/src/include/download-provider-dateTime.h @@ -0,0 +1,111 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-dateTime.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief data and utility APIs for Date and Time + */ + +#ifndef DOWNLOAD_PROVIDER_DATE_TIME_H +#define DOWNLOAD_PROVIDER_DATE_TIME_H + +#include <time.h> +#include <Elementary.h> +#include <unicode/udat.h> +#include <unicode/udatpg.h> +#include <unicode/ustring.h> + +#include "download-provider-common.h" + +using namespace std; + +namespace DATETIME { +enum { + DATE_TYPE_NONE = 0, + DATE_TYPE_LATER, + DATE_TYPE_TODAY, + DATE_TYPE_YESTERDAY, + DATE_TYPE_PREVIOUS, +}; +} + +namespace LOCALE_STYLE{ +enum { + TIME = 0, + SHORT_DATE, + MEDIUM_DATE, + FULL_DATE +}; +} + +class DateGroup { +public: + DateGroup(void); + ~DateGroup(void); + + Elm_Object_Item *glGroupItem() { return m_glGroupItem; } + void setGlGroupItem(Elm_Object_Item *i) { m_glGroupItem = i; } + void increaseCount(void) { count++; } + void decreaseCount(void) { count--; } + int getCount(void) { return count; } + void initData(void); + void setType(int t) { type = t; } + int getType(void) { return type; } + +private: + int count; + int type; + Elm_Object_Item *m_glGroupItem; +}; + +class DateUtil { +public: + static DateUtil& getInstance(void) { + static DateUtil inst; + return inst; + } + + inline void setTodayStandardTime(void) { m_todayStandardTime = time(NULL); } + int getDiffDaysFromToday(void); + int getDiffDays(time_t nowTime, time_t refTime); + void updateLocale(void); + void getDateStr(int style, double time, string &outBuf); + inline double nowTime(void) { return (double)(time(NULL)); } + /* yesterday is same to 24*60*60 seconds from now */ + inline double yesterdayTime(void) { return (double)(time(NULL)+24*60*60); } + +private: + DateUtil(void); + ~DateUtil(void); + + UDateFormat *getBestPattern(const char *patternStr, + UDateTimePatternGenerator *generator, const char *locale); + void deinitLocaleData(void); + /* Update this in case of follows + * 1. show main view. + * 2. add new item + * 3. create today group + **/ + time_t m_todayStandardTime; + UDateFormat *dateShortFormat; + UDateFormat *dateMediumFormat; + UDateFormat *dateFullFormat; + UDateFormat *timeFormat12H; + UDateFormat *timeFormat24H; +}; + +#endif /* DOWNLOAD_PROVIDER_DATE_TIME_H */ diff --git a/src/include/download-provider-debug.h b/src/include/download-provider-debug.h new file mode 100644 index 0000000..4c4552b --- /dev/null +++ b/src/include/download-provider-debug.h @@ -0,0 +1,76 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-debug.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief debug function + */ + +#ifndef DOWNLOAD_PROVIDER_DEBUG_H +#define DOWNLOAD_PROVIDER_DEBUG_H + +#define _USE_DLOG 1 + +#ifdef _USE_DLOG +#include <dlog.h> + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "DownloadProvider" + +#define DP_LOG(format, args...) LOGI("[%s] "format, __func__, ##args) +#define DP_LOGD(format, args...) LOGD("[%s] "format, __func__, ##args) +#define DP_LOG_START(msg) LOGI("<<= [%s] Start =>>\n",msg) +#define DP_LOG_FUNC() LOGI("<<= [%s]=>>\n",__func__) +#define DP_LOGD_FUNC() LOGD("<<= [%s]=>>\n",__func__) +#define DP_LOG_END(msg) LOGI("<<= [%s] End [%d] =>>\n",msg) +#define DP_LOGE(format, args...) LOGE("[%s][ERR] "format, __func__, ##args) +#define DP_LOG_TEST(format, args...) LOGI("####TEST####[%s] "format, __func__, ##args) + +#else + +#include <stdio.h> +#include <pthread.h> + +#define DP_LOG(args...) do {\ + printf("[DP:%s][LN:%d][%lu]",__func__,__LINE__,pthread_self());\ + printf(args);printf("\n"); }while(0) +#define DP_LOGD(args...) do {\ + printf("[DP_D:%s][LN:%d][%lu]",__func__,__LINE__,pthread_self());\ + printf(args);printf("\n");}while(0) +#define DP_LOGE(args...) do {\ + printf("[DP_ERR:%s][LN:%d][%lu]",__func__,__LINE__,pthread_self());\ + printf(args);printf("\n");}while(0) +#define DP_LOG_FUNC() do {\ + printf("<<==[DP:%s][LN:%d][%lu] ==>> \n",__func__,__LINE__,pthread_self());\ + }while(0) +#define DP_LOGD_FUNC() do {\ + printf("<<==[DP_D:%s][LN:%d][%lu] ==>> \n",__func__,__LINE__,pthread_self());\ + }while(0) +#define DP_LOG_START(msg) do {\ + printf("<<==[DP:%s][LN:%d][%lu] Start ==>> \n",\ + __FUNCTION__,__LINE__,pthread_self());\ + }while(0) +#define DP_LOG_END(msg) do {\ + printf("<<==[DP:%s][LN:%d][%lu] End ==>> \n",\ + __FUNCTION__,__LINE__,pthread_self());\ + }while(0) +#endif /*_USE_DLOG*/ + +#endif /* DOWNLOAD_PROVIDER_DEBUG_H */ diff --git a/src/include/download-provider-downloadItem.h b/src/include/download-provider-downloadItem.h new file mode 100644 index 0000000..9421246 --- /dev/null +++ b/src/include/download-provider-downloadItem.h @@ -0,0 +1,140 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-downloadItem.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief download item class + */ + +#ifndef DOWNLOAD_PROVIDER_DOWNLOAD_ITEM_H +#define DOWNLOAD_PROVIDER_DOWNLOAD_ITEM_H + +#include "download-provider-common.h" +#include "download-provider-downloadRequest.h" +#include "download-provider-event.h" +#include "download-agent-interface.h" +#include <memory> + +namespace DL_ITEM { +enum STATE { + IGNORE, + STARTED, + WAITING_CONFIRM, + UPDATING, + COMPLETE_DOWNLOAD, + INSTALL_NOTIFY, + START_DRM_DOMAIN, + FINISH_DRM_DOMAIN, + WAITING_RO, + SUSPENDED, + RESUMED, + FINISHED, + CANCELED, + FAILED +}; +} + +class DownloadItem { +public: + DownloadItem(); /* FIXME remove after cleanup ecore_pipe */ + DownloadItem(auto_ptr<DownloadRequest> request); + ~DownloadItem(); + + void start(void); + void cancel(void); + void retry(void); + bool sendUserResponse(bool res); + void suspend(void); + void resume(void); + + inline int downloadId(void) { return m_da_req_id;} + inline void setDownloadId(int id) { m_da_req_id = id; } + + inline unsigned long int receivedFileSize(void) { return m_receivedFileSize; } + inline void setReceivedFileSize(unsigned long int size) { m_receivedFileSize = size; } + + inline unsigned long int fileSize(void) { return m_fileSize; } + inline void setFileSize(unsigned long int size) { m_fileSize = size; } + + inline string &filePath(void) { return m_filePath; } + inline void setFilePath(const char *path) { if (path) m_filePath = path; } + inline void setFilePath(string &path) { m_filePath = path; } + + inline string ®isteredFilePath(void) { return m_registeredFilePath; } + inline void setRegisteredFilePath(string &path) { m_registeredFilePath = path; } + + inline string &mimeType(void) { return m_mimeType; } + inline void setMimeType(const char *mime) { m_mimeType = mime; } + inline void setMimeType(string &mime) { m_mimeType = mime; } + + inline DL_ITEM::STATE state(void) { return m_state; } + inline void setState(DL_ITEM::STATE state) { m_state = state; } + + inline ERROR::CODE errorCode(void) { return m_errorCode; } + inline void setErrorCode(ERROR::CODE err) { m_errorCode = err; } + inline bool isMidletInstalled(void) { return m_isMidletInstalled; } + inline void setIsMidletInstalled(bool b) { m_isMidletInstalled = b; } + inline DL_TYPE::TYPE downloadType(void) { return m_downloadType; } + inline void setDownloadType(DL_TYPE::TYPE t) { m_downloadType = t;} + inline string &contentName(void) { return m_contentName; } + inline void setContentName(string &name) { m_contentName = name; } + inline string &vendorName(void) { return m_vendorName; } + inline void setVendorName(string &name) { m_vendorName = name; } + + inline void notify(void) { m_subject.notify(); } + inline void subscribe(Observer *o) { if (o) m_subject.attach(o); } + inline void deSubscribe(Observer *o) { if (o) m_subject.detach(o); } + inline string &url(void) { return m_aptr_request->getUrl(); } + inline string &cookie(void) { return m_aptr_request->getCookie(); } + + DL_ITEM::STATE _convert_da_state_to_download_state(int da_state); + ERROR::CODE _convert_da_error(int da_err); + +private: + auto_ptr<DownloadRequest> m_aptr_request; + Subject m_subject; + da_handle_t m_da_req_id; + DL_ITEM::STATE m_state; + ERROR::CODE m_errorCode; + unsigned long int m_receivedFileSize; + unsigned long int m_fileSize; + string m_filePath; + string m_registeredFilePath; + string m_mimeType; + DL_TYPE::TYPE m_downloadType; + bool m_isMidletInstalled; /* For MIDP */ + string m_contentName; /* For OMA & MIDP */ + string m_vendorName; /* For MIDP */ +}; + +class DownloadEngine { +public: + static DownloadEngine &getInstance(void) { + static DownloadEngine downloadEngine; + return downloadEngine; + } + + void initEngine(void); + void deinitEngine(void); +private: + DownloadEngine(void); + ~DownloadEngine(void); + +}; + + +#endif /* DOWNLOAD_PROVIDER_DOWNLOAD_ITEM_H */ diff --git a/src/include/download-provider-downloadRequest.h b/src/include/download-provider-downloadRequest.h new file mode 100644 index 0000000..a21f7df --- /dev/null +++ b/src/include/download-provider-downloadRequest.h @@ -0,0 +1,49 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-downloadRequest.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Download Request class + */ + +#ifndef DOWNLOAD_PROVIDER_DOWNLOAD_REQUEST_H +#define DOWNLOAD_PROVIDER_DOWNLOAD_REQUEST_H + +#include <string> + +using namespace std; + +class DownloadRequest +{ +public: +// DownloadRequest(); + DownloadRequest(string url, string cookie); + DownloadRequest(DownloadRequest &rRequest); + ~DownloadRequest(); + + string &getUrl(); + string &getCookie(); + bool isUrlEmpty(); + bool isCookieEmpty(); + void setUrl(string url); + void setCookie(string cookie); +private: + string m_url; + string m_cookie; +}; + +#endif /* DOWNLOAD_PROVIDER_DOWNLOAD_REQUEST_H */ diff --git a/src/include/download-provider-event.h b/src/include/download-provider-event.h new file mode 100644 index 0000000..e9378a6 --- /dev/null +++ b/src/include/download-provider-event.h @@ -0,0 +1,72 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-event.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Download event class + */ +#ifndef DOWNLOAD_PROVIDER_EVENT_H +#define DOWNLOAD_PROVIDER_EVENT_H + +#include <vector> +/* For debug */ +#include <string> + +using namespace std; + +class Observer; +class Subject +{ +public: + Subject(){} + ~Subject(){} + + void attach(Observer *); + void detach(Observer *); + void notify(void); + +private: + vector<Observer*> _observers; +}; + +typedef void (*updateFunction)(void *data); + +class Observer +{ +public: + /* For debug */ + Observer(updateFunction uf, void *data, const char *name); + //Observer(updateFunction uf, void *data); + ~Observer(){} + + void update(Subject *s); + void set(updateFunction uf, void *data); + void clear(void); + void *getUserData(void) { return m_userData; } + /* For debug */ + string name(void) { return observerName; } + +private: + void call(void); + + updateFunction m_updateFunction; + void *m_userData; + /* For debug */ + string observerName; +}; + +#endif /* DOWNLOAD_PROVIDER_EVENT_H */ diff --git a/src/include/download-provider-history-db.h b/src/include/download-provider-history-db.h new file mode 100644 index 0000000..b22883e --- /dev/null +++ b/src/include/download-provider-history-db.h @@ -0,0 +1,56 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-history-db.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Manager for a download history DB + */ + +#ifndef DOWNLOAD_PROVIDER_HISTORY_DB_H +#define DOWNLOAD_PROVIDER_HISTORY_DB_H + +#include <string> +#include <queue> +#include <db-util.h> +#include "download-provider-item.h" +extern "C" { +#include <unicode/utypes.h> +} + +using namespace std; + +class DownloadHistoryDB +{ +public: + static bool addToHistoryDB(Item *item); + static bool createRemainedItemsFromHistoryDB(int limit, int offset); + static bool createItemsFromHistoryDB(void); + static bool deleteItem(unsigned int historyId); + static bool deleteMultipleItem(queue <unsigned int> &q); + static bool clearData(void); + static bool getCountOfHistory(int *count); +private: + DownloadHistoryDB(void); + ~DownloadHistoryDB(void); + static sqlite3* historyDb; + static bool open(void); + static bool isOpen(void) { return historyDb ? true : false; } + static void close(void); +}; + +#endif /* DOWNLOAD_PROVIDER_HISTORY_DB_H */ + diff --git a/src/include/download-provider-item.h b/src/include/download-provider-item.h new file mode 100644 index 0000000..65ab1eb --- /dev/null +++ b/src/include/download-provider-item.h @@ -0,0 +1,204 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-item.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Item class + */ +#ifndef DOWNLOAD_PROVIDER_ITEM_H +#define DOWNLOAD_PROVIDER_ITEM_H + +#include <string> +#include <memory> +#include "download-provider-event.h" +#include "download-provider-downloadRequest.h" +#include "download-provider-downloadItem.h" +#include "download-provider-util.h" + +using namespace std; + +namespace ITEM { +enum STATE { + IDLE, + REQUESTING, + PREPARE_TO_RETRY, + WAITING_USER_RESPONSE, + RECEIVING_DOWNLOAD_INFO, + DOWNLOADING, + REGISTERING_TO_SYSTEM, + PROCESSING_DOMAIN, + FINISH_PROCESSING_DOMAIN, + ACTIVATING, + NOTIFYING_TO_SERVER, + SUSPEND, + FINISH_DOWNLOAD, + FAIL_TO_DOWNLOAD, + CANCEL, + PLAY, + DESTROY +}; +} + +class DownloadNoti; + +class Item { +public: + static void create(DownloadRequest &rRequest); + static Item *createHistoryItem(void); + ~Item(void); + + void attachHistoryItem(void); + void destroy(void); + /* SHOULD call this before destrying an item*/ + void deleteFromDB(void); + void download(void); + inline void cancel(void) + { + if (m_aptr_downloadItem.get()) + m_aptr_downloadItem->cancel(); + return; + } + void clearForRetry(void); + bool retry(void); + + void sendUserResponse(bool res); + bool play(void); + + inline void subscribe(Observer *o) { m_subjectForView.attach(o); } + inline void deSubscribe(Observer *o) { m_subjectForView.detach(o); } + + static void updateCBForDownloadObserver(void *data); + static void netEventCBObserver(void *data); + void updateFromDownloadItem(void); + inline void suspend(void) { m_aptr_downloadItem->suspend(); } + + inline int id(void) { + if (m_aptr_downloadItem.get()) + return m_aptr_downloadItem->downloadId(); + + return -1; + } // FIXME create Item's own id + + inline unsigned long int receivedFileSize(void) { + if (m_aptr_downloadItem.get()) + return m_aptr_downloadItem->receivedFileSize(); + return 0; + } + + inline unsigned long int fileSize(void) { + if (m_aptr_downloadItem.get()) + return m_aptr_downloadItem->fileSize(); + return 0; + } + + inline string &filePath(void) { + if (m_aptr_downloadItem.get()) + return m_aptr_downloadItem->filePath(); + return m_emptyString; + } + + inline bool isMidletInstalled(void) { + if (m_aptr_downloadItem.get()) + return m_aptr_downloadItem->isMidletInstalled(); + return false; + } + + inline void setHistoryId(unsigned int i) { m_historyId = i; } + inline unsigned int historyId(void) { return m_historyId; } // FIXME duplicated with m_id + inline string &title(void) {return m_title;} + inline void setTitle(string &title) { m_title = title; } + string &contentName(void); + inline void setContentName(string &c) { m_contentName = c; } + string &vendorName(void); + inline void setVendorName(string &v) { m_vendorName = v; } + string ®isteredFilePath(void); + inline void setRegisteredFilePath(string &r) { m_registeredFilePath = r; } + string &url(void); + string &cookie(void); + void setRetryData(string &url, string &cookie); + int contentType(void) { return m_contentType; } + inline void setContentType(int t) { m_contentType = t; } + DL_TYPE::TYPE downloadType(void); + inline void setDownloadType(DL_TYPE::TYPE t) { m_downloadType = t; } + +// string &getIconPath(void) {return m_iconPath; } + inline string &iconPath(void) { return m_iconPath; } + + inline void setState(ITEM::STATE state) { m_state = state; } + inline ITEM::STATE state(void) { return m_state; } + + inline void setErrorCode(ERROR::CODE err) { m_errorCode = err; } + inline ERROR::CODE errorCode(void) { return m_errorCode; } + const char *getErrorMessage(void); + inline void setFinishedTime(double t) { m_finishedTime = t; } + inline double finishedTime(void) { return m_finishedTime; } + + inline string getMidletPkgName(void) { + DownloadUtil &util = DownloadUtil::getInstance(); + return util.getMidletPkgName(m_contentName, m_vendorName); + } + + bool isFinished(void); /* include finish download state with error */ + bool isFinishedWithErr(void); + bool isPreparingDownload(void); /* Before downloading start */ + bool isCompletedDownload(void); /* After stating installation */ + + /* Test code */ + const char *stateStr(void); + +private: + Item(void); + Item(DownloadRequest &rRequest); + + inline void notify(void) { m_subjectForView.notify(); } + + void createSubscribeData(void); + void extractTitle(void); + void extractIconPath(void); + + void startUpdate(void); + void createHistoryId(void); + bool isExistedHistoryId(unsigned int id); + void handleFinishedItem(void); + + auto_ptr<DownloadRequest> m_aptr_request; + auto_ptr<DownloadItem> m_aptr_downloadItem; + FileOpener m_fileOpener; + + Subject m_subjectForView; + auto_ptr<Observer> m_aptr_downloadObserver; + auto_ptr<Observer> m_aptr_netEventObserver; + + ITEM::STATE m_state; + ERROR::CODE m_errorCode; + string m_title; + unsigned int m_historyId; + int m_contentType; + string m_iconPath; // FIXME Later:is it right to exist here? (ViewItem or not) + string m_emptyString; // FIXME this is temporary to avoid crash when filePath() is called if m_aptr_downloaditem points nothing + double m_finishedTime; + DL_TYPE::TYPE m_downloadType; + string m_contentName; + string m_vendorName; + string m_registeredFilePath; + string m_url; + string m_cookie; + + bool m_gotFirstData; +}; + +#endif /* DOWNLOAD_PROVIDER_ITEM_H */ diff --git a/src/include/download-provider-items.h b/src/include/download-provider-items.h new file mode 100644 index 0000000..8395719 --- /dev/null +++ b/src/include/download-provider-items.h @@ -0,0 +1,45 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/* + * @file download-provider-items.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief item inventory class + */ +#ifndef DOWNLOAD_PROVIDER_ITEMS_H +#define DOWNLOAD_PROVIDER_ITEMS_H + +#include "download-provider-item.h" +#include <vector> + +class Items { +public: + static Items& getInstance(void) { + static Items inst; + return inst; + } + + void attachItem(Item *item); + void detachItem(Item *item); + bool isExistedHistoryId(unsigned int id); +private: + Items(){} + ~Items(){DP_LOGD_FUNC();} + + vector<Item*> m_items; +}; + +#endif /* DOWNLOAD_PROVIDER_ITEMS_H */ diff --git a/src/include/download-provider-network.h b/src/include/download-provider-network.h new file mode 100644 index 0000000..2d0f5eb --- /dev/null +++ b/src/include/download-provider-network.h @@ -0,0 +1,57 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-network.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Download netowkr manager + */ + +#ifndef DOWNLOAD_PROVIDER_NETWORK_H +#define DOWNLOAD_PROVIDER_NETWORK_H + +#include "vconf.h" +#include "vconf-keys.h" +#include "download-provider-event.h" + +class NetMgr { +public: + static NetMgr& getInstance(void) { + static NetMgr inst; + return inst; + } + void initNetwork(void); + void deinitNetwork(void); + void netStatusChanged(void); + void netConfigChanged(void); + inline void subscribe(Observer *o) { m_subject.attach(o); } + inline void deSubscribe(Observer *o) { m_subject.detach(o); } + static void netStatusChangedCB(keynode_t *keynode, void *data); + static void netConfigChangedCB(keynode_t *keynode, void *data); +private: + NetMgr(void); + ~NetMgr(void); + int getConnectionState(void); + int getCellularStatus(void); + int getWifiStatus(void); + void getProxy(void); + void getIPAddress(void); + inline void notify() { m_subject.notify(); } + int m_netStatus; + Subject m_subject; +}; + +#endif diff --git a/src/include/download-provider-util.h b/src/include/download-provider-util.h new file mode 100644 index 0000000..0ed6575 --- /dev/null +++ b/src/include/download-provider-util.h @@ -0,0 +1,57 @@ +/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
+ *
+ * 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.
+ */
+
+/*
+ * @file download-provider-util.h
+ * @author Jungki Kwak (jungki.kwak@samsung.com)
+ * @brief Utility APIs and interface with content player
+ */
+
+#ifndef DOWNLOAD_PROVIDER_UTIL_H
+#define DOWNLOAD_PROVIDER_UTIL_H
+
+#include <string>
+#include "download-provider-common.h"
+
+using namespace std;
+class FileOpener {
+public:
+ FileOpener() {}
+ ~FileOpener() {}
+
+ bool openFile(string &path, int contentType);
+ bool openApp(string &pkgName);
+};
+
+class DownloadUtil
+{
+public:
+ static DownloadUtil& getInstance(void) {
+ static DownloadUtil inst;
+ return inst;
+ }
+
+ string getMidletPkgName(string& name, string& vendor);
+ int getContentType(const char *mimem, const char *filePath);
+
+private:
+ DownloadUtil(void);
+ ~DownloadUtil(void) {}
+ void initDrm(void);
+ bool isAmbiguousMIMEType(const char *mimeType);
+};
+
+#endif//DOWNLOAD_PROVIDER_UTIL_H
diff --git a/src/include/download-provider-view.h b/src/include/download-provider-view.h new file mode 100644 index 0000000..4fdfab0 --- /dev/null +++ b/src/include/download-provider-view.h @@ -0,0 +1,160 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-view.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Download UI View manager + */ + +#ifndef DOWNLOAD_PROVIDER_VIEW_H +#define DOWNLOAD_PROVIDER_VIEW_H + +#include <Elementary.h> +#include <libintl.h> + +#include <vector> +#include "download-provider-common.h" +#include "download-provider-viewItem.h" +#include "download-provider-dateTime.h" + +enum { + POPUP_EVENT_EXIT = 0, + POPUP_EVENT_ERR, +}; + +class DownloadView { +public: + static DownloadView& getInstance(void) { + static DownloadView inst; + return inst; + } + + Evas_Object *create(void); + void createView(void); + void activateWindow(void); + void show(void); + void hide(void); + + void attachViewItem(ViewItem *viewItem); + void detachViewItem(ViewItem *viewItem); + + void changedRegion(void); + void showErrPopup(string &desc); + void showOMAPopup(string &msg, ViewItem *viewItem); + void update(); + void update(ViewItem *viewItem); + void update(Elm_Object_Item *glItem); + void showViewItem(int id, const char *title); + void playContent(int id, const char *title); + void handleChangedAllCheckedState(void); + void handleCheckedState(void); + bool isGenlistEditMode(void); + void handleGenlistGroupItem(int type); + void moveRetryItem(ViewItem *viewItem); + static char *getGenlistGroupLabelCB(void *data, Evas_Object *obj, + const char *part); + +private: + static void showNotifyInfoCB(void *data, Evas *evas, Evas_Object *obj, void *event); + static void hideNotifyInfoCB(void *data, Evas *evas, Evas_Object *obj, void *event); + static void backBtnCB(void *data, Evas_Object *obj, void *event_info); + static void cbItemDeleteCB(void *data, Evas_Object *obj, void *event_info); + static void cbItemCancelCB(void *data, Evas_Object *obj, void *event_info); + static void selectAllClickedCB(void *data, Evas *evas, Evas_Object *obj, + void *event_info); + static void selectAllChangedCB(void *data, Evas_Object *obj, + void *event_info); + static void genlistClickCB(void *data, Evas_Object *obj, void *event_info); + static void cancelClickCB(void *data, Evas_Object *obj, void *event_info); + static void errPopupResponseCB(void *data, Evas_Object *obj, void *event_info); + static void omaPopupResponseOKCB(void *data, Evas_Object *obj, void *event_info); + static void omaPopupResponseCancelCB(void *data, Evas_Object *obj, void *event_info); + +private: + DownloadView(); + ~DownloadView(); + + inline void destroyEvasObj(Evas_Object *e) { if(e) evas_object_del(e); e = NULL;} + void setTheme(void); + void setIndicator(Evas_Object *window); + Evas_Object *createWindow(const char *windowName); + Evas_Object *createBackground(Evas_Object *window); + Evas_Object *createLayout(Evas_Object *parent); + void createTheme(void); + void createNaviBar(void); + void createBackBtn(void); + void createControlBar(void); + void createBox(void); + void createList(void); + + void removeTheme(void); + + void addViewItemToGenlist(ViewItem *viewItem); + void createGenlistItem(ViewItem *viewItem); + void showEmptyView(void); + void hideEmptyView(void); + + void removePopup(void); + void showGenlistEditMode(void); + void hideGenlistEditMode(void); + void createSelectAllLayout(void); + void changeAllCheckedValue(void); + void destroyCheckedItem(void); + void showNotifyInfo(int type, int selectedCount); + void destroyNotifyInfo(void); + void createNotifyInfo(void); + + DateGroup *getDateGroupObj(int type); + Elm_Object_Item *getGenlistGroupItem(int type); + int getGenlistGroupCount(int type); + void setGenlistGroupItem(int type, Elm_Object_Item *item); + void increaseGenlistGroupCount(int type); + void handleUpdateDateGroupType(ViewItem *viewItem); + void cleanGenlistData(); + char *getGenlistGroupLabel(void *data, Evas_Object *obj, const char *part); + + Evas_Object *eoWindow; + Evas_Object *eoBackground; + Evas_Object *eoLayout; + Elm_Theme *eoTheme; + + Evas_Object *eoEmptyNoContent; + Evas_Object *eoNaviBar; + Elm_Object_Item *eoNaviBarItem; + Evas_Object *eoBackBtn; + Evas_Object *eoControlBar; + Elm_Object_Item *eoCbItemDelete; + Elm_Object_Item *eoCbItemCancel; + Elm_Object_Item *eoCbItemEmpty; + Evas_Object *eoBoxLayout; + Evas_Object *eoBox; + Evas_Object *eoDldList; + Evas_Object *eoPopup; + Evas_Object *eoSelectAllLayout; + Evas_Object *eoAllCheckedBox; + Evas_Object *eoNotifyInfo; + Evas_Object *eoNotifyInfoLayout; + Elm_Genlist_Item_Class dldGenlistGroupStyle; + Eina_Bool m_allChecked; + + int m_viewItemCount; + DateGroup m_today; + DateGroup m_yesterday; + DateGroup m_previousDay; +}; + +#endif /* DOWNLOAD_PROVIDER_VIEW_H */ diff --git a/src/include/download-provider-viewItem.h b/src/include/download-provider-viewItem.h new file mode 100644 index 0000000..70e8ec5 --- /dev/null +++ b/src/include/download-provider-viewItem.h @@ -0,0 +1,136 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file download-provider-viewItem.h + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief Item class for Download view + */ + +#ifndef DOWNLOAD_PROVIDER_VIEW_ITEM_H +#define DOWNLOAD_PROVIDER_VIEW_ITEM_H + +#include "download-provider-event.h" +#include "download-provider-item.h" +#include <Elementary.h> +#include <memory> + +using namespace std; + +class ViewItem { +public: + ~ViewItem(); + static void create(Item *item); + void destroy(void); + inline void deleteFromDB(void) { m_item->deleteFromDB(); } + + inline void setItem(Item *item) { m_item = item; } + static void updateCB(void *); + + + static char *getGenlistLabelCB(void *data, Evas_Object *obj, + const char *part); + char *getGenlistLabel(Evas_Object *obj, const char *part); + + static Evas_Object *getGenlistIconCB(void *data, Evas_Object *obj, + const char *part); + Evas_Object *getGenlistIcon(Evas_Object *obj, const char *part); + + static void checkChangedCB(void *data, Evas_Object *obj, void *event_info); + + const char *getMessage(void); + const char *getBytesStr(void); + const char *getHumanFriendlyBytesStr(unsigned long int bytes, + bool progressOption); + + Elm_Genlist_Item_Class *elmGenlistStyle(void); + + inline Elm_Genlist_Item_Class *elmGenlistItemClass(void) + { return &dldGenlistStyle; } + inline Elm_Genlist_Item_Class *elmGenlistHistoryItemClass(void) + { return &dldHistoryGenlistStyle; } + inline Elm_Genlist_Item_Class *elmGenlistFailedItemClass(void) + { return &dldGenlistSlideStyle; } + inline ITEM::STATE state(void) { return m_item->state(); } + inline const char* stateStr(void) { return m_item->stateStr(); } + inline bool isFinished(void) { return m_item->isFinished(); } + inline bool isFinishedWithErr(void) { return m_item->isFinishedWithErr(); } + inline bool isPreparingDownload(void) { return m_item->isPreparingDownload(); } + inline bool isCompletedDownload(void) { return m_item->isCompletedDownload(); } + + unsigned long int receivedFileSize(void); + unsigned long int fileSize(void); + const char *getTitle(void); + inline const char *getErrMsg(void) { return m_item->getErrorMessage(); } + const char *getIconPath(void) { return m_item->iconPath().c_str(); } + + inline Elm_Object_Item *genlistItem(void) { return m_glItem; } + inline void setGenlistItem(Elm_Object_Item *glItem) { m_glItem = glItem; } + inline void setProgressBar(Evas_Object *p) { m_progressBar = p; } + + void clickedDeleteButton(void); + void clickedCancelButton(void); + void clickedRetryButton(void); + void clickedGenlistItem(void); + void requestCancel(void); + inline void sendUserResponse(bool res) + { + return m_item->sendUserResponse(res); + } + inline Eina_Bool checkedValue(void) { return m_checked; } + void setCheckedValue(Eina_Bool b) { m_checked = b; } + inline Evas_Object *checkedBtn(void) { return m_checkedBtn; } + void setCheckedBtn(Evas_Object *e) { m_checkedBtn = e; } + + void updateCheckedBtn(void); + + inline int dateGroupType(void) { return m_dateGroupType; } + void setDateGroupType (int t) { m_dateGroupType = t; } + + inline double finishedTime(void) { return m_item->finishedTime();} + void extractDateGroupType(void); + + inline unsigned int historyId(void) { return m_item->historyId(); } +private: + ViewItem(Item *item); + + void updateFromItem(void); + Evas_Object *createProgressBar(Evas_Object *parent); + Evas_Object *createCancelBtn(Evas_Object *parent); + void retryViewItem(void); + + static void deleteBtnClickedCB(void *data, Evas_Object *obj, + void *event_info); + static void cancelBtnClickedCB(void *data, Evas_Object *obj, + void *event_info); + static void retryBtnClickedCB(void *data, Evas_Object *obj, + void *event_info); + + auto_ptr<Observer> m_aptr_observer; + Item *m_item; + + Elm_Genlist_Item_Class dldGenlistStyle; + Elm_Genlist_Item_Class dldHistoryGenlistStyle; + Elm_Genlist_Item_Class dldGenlistSlideStyle; + Elm_Object_Item *m_glItem; + Evas_Object *m_progressBar; + Evas_Object *m_checkedBtn; + Eina_Bool m_checked; + bool m_isRetryCase; + int m_dateGroupType; +}; + +#endif /* DOWNLOAD_PROVIDER_VIEW_ITEM_H */ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c3748b6 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,222 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + +/** + * @file main.cpp + * @author Jungki Kwak (jungki.kwak@samsung.com) + * @brief main file for download provider + */ + +#include <list> +#include <string> +#include <iostream> +#include <memory> + +#include "Ecore_X.h" +#include "aul.h" +#include "vconf.h" +#include "app.h" +#include "app_service.h" + +#include "download-provider-common.h" +#include "download-provider-view.h" +#include "download-provider-network.h" +#include "download-provider-downloadRequest.h" +#include "download-provider-history-db.h" + +using namespace std; + +struct app_data_t { + Ecore_Idler *idler; + int history_count; + int load_count; +}; + +static void __lang_changed_cb(void *data) +{ + DP_LOG("=== Language changed nofification ==="); + return; +} + +static void __region_changed_cb(void *data) +{ + DownloadView &view = DownloadView::getInstance(); + view.changedRegion(); + DP_LOG("=== Region changed nofification ==="); + return; +} + +static void __low_memory_cb(void *data) +{ + DP_LOG("=== Low memory nofification ==="); + return; +} + +static Eina_Bool __load_remained_history(void *data) +{ + struct app_data_t *app_data = (struct app_data_t *)data; + if (app_data && app_data->load_count <= app_data->history_count) { + app_data->load_count += LOAD_HISTORY_COUNT; + DownloadHistoryDB::createRemainedItemsFromHistoryDB( + LOAD_HISTORY_COUNT, app_data->load_count); + return ECORE_CALLBACK_RENEW; + } else + return ECORE_CALLBACK_CANCEL; +} + +static bool __app_create(void *data) +{ + int count = 0; + struct app_data_t *app_data = (struct app_data_t *)data; + DP_LOG_START("App Create"); + + DownloadView &view = DownloadView::getInstance(); + Evas_Object *window = view.create(); + if (!window) { + DP_LOGE("Fail to create main window"); + return false; + } + /* Init network */ + NetMgr &netObj = NetMgr::getInstance(); + netObj.initNetwork(); + + evas_object_show(window); + view.show(); + + DownloadHistoryDB::getCountOfHistory(&count); + if (count > 0) { + DownloadHistoryDB::createItemsFromHistoryDB(); + if (count > LOAD_HISTORY_COUNT) { + if (app_data) { + app_data->history_count = count; + app_data->idler = ecore_idler_add(__load_remained_history, app_data); + } + } + } + + DP_LOG_END("App Create"); + + return true; +} + +static void __app_terminate(void *data) +{ + struct app_data_t *app_data = (struct app_data_t *)data; + NetMgr &netObj = NetMgr::getInstance(); + netObj.deinitNetwork(); + if (app_data && app_data->idler) + ecore_idler_del(app_data->idler); + if (app_data) { + free(app_data); + app_data = NULL; + } + return; +} + +static void __app_pause(void *data) +{ + DP_LOG_FUNC(); + return; +} + +static void __app_resume(void *data) +{ + return; +} + +static void __app_service(service_h s, void *data) +{ + string s_url = std::string(); + string s_cookie = std::string(); + char *url = NULL; + char *cookie = NULL; + char *mode = NULL; + char *app_op = NULL; + DownloadView &view = DownloadView::getInstance(); + + DP_LOG_FUNC(); + + if (service_get_operation(s, &app_op) < 0) { + DP_LOGE("Fail to get service operation"); + return; + } + DP_LOG("operation[%s]", app_op); + + if (service_get_uri(s, &url) < 0) { + DP_LOGE("Invalid URL"); + } else { + DP_LOG("url[%s]",url); + if (url) + s_url = url; + } + + if (service_get_extra_data(s, "cookie", &cookie) < 0) { + DP_LOG("No cookie"); + } else { + DP_LOG("cookie[%s]",cookie); + if (cookie) + s_cookie = cookie; + } + + if (service_get_extra_data(s, "mode", &mode) < 0) { + DP_LOG("No mode"); + } else { + DP_LOG("mode[%s]",mode); + if ( 0 == strncmp(mode, "view", strlen("view"))) { + DP_LOG("View mode"); + view.activateWindow(); + return; + } + DP_LOGE("Invalid mode"); + view.activateWindow(); + return; + } + + DownloadRequest request(s_url, s_cookie); + Item::create(request); + view.activateWindow(); + + return; +} + +int main(int argc, char *argv[]) +{ + app_event_callback_s evt_cb = {0,}; + int ret = 0; + struct app_data_t *app_data = NULL; + + app_data = (struct app_data_t *)calloc(1, sizeof(struct app_data_t)); + if (!app_data) { + DP_LOGE("Fail to calloc of app data"); + return ret; + } + + evt_cb.create = __app_create; + evt_cb.terminate = __app_terminate; + evt_cb.pause = __app_pause; + evt_cb.resume = __app_resume; + evt_cb.service = __app_service; + evt_cb.low_memory = __low_memory_cb; + evt_cb.low_battery = NULL; + evt_cb.device_orientation = NULL; + evt_cb.language_changed = __lang_changed_cb; + evt_cb.region_format_changed = __region_changed_cb; + + ret = app_efl_main(&argc, &argv, &evt_cb, app_data); + + return ret; +} + |