4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jungki Kwak <jungki.kwak@samsung.com>, Keunsoon Lee <keunsoon.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 * @file download-agent-dl-mgr.c
21 * @brief common functions for oma and direct download
22 * @author Keunsoon Lee(keunsoon.lee@samsung.com)
23 * @author Jungki Kwak(jungki.kwak@samsung.com)
26 #include "download-agent-client-mgr.h"
27 #include "download-agent-debug.h"
28 #include "download-agent-dl-mgr.h"
29 #include "download-agent-utils.h"
30 #include "download-agent-http-mgr.h"
31 #include "download-agent-installation.h"
32 #include "download-agent-file.h"
33 #include "download-agent-plugin-conf.h"
36 static da_result_t __cancel_download_with_download_id(int download_id);
37 static da_result_t __suspend_download_with_download_id(int download_id);
40 da_result_t requesting_download(stage_info *stage)
42 da_result_t ret = DA_RESULT_OK;
43 req_dl_info *request_session = DA_NULL;
44 download_state_t download_state = DA_INVALID_ID;
46 DA_LOG_FUNC_START(Default);
49 DA_LOG_ERR(Default, "stage is null..");
50 ret = DA_ERR_INVALID_ARGUMENT;
54 ret = make_req_dl_info_http(stage, GET_STAGE_TRANSACTION_INFO(stage));
55 if (ret != DA_RESULT_OK)
58 request_session = GET_STAGE_TRANSACTION_INFO(stage);
59 ret = request_http_download(stage);
60 if (DA_RESULT_OK == ret) {
61 DA_LOG(Default, "Http download is complete.");
63 DA_LOG_ERR(Default, "Http download is failed. ret = %d", ret);
67 _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
68 download_state = GET_DL_STATE_ON_STAGE(stage);
69 _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
71 /* Ignore install content process if the download is failed or paused or canceled */
72 if (download_state == DOWNLOAD_STATE_PAUSED ||
73 download_state == DOWNLOAD_STATE_CANCELED) {
81 da_result_t handle_after_download(stage_info *stage)
83 da_result_t ret = DA_RESULT_OK;
85 DA_LOG_FUNC_START(Default);
87 if (DA_TRUE == is_this_client_manual_download_type()) {
88 if (DA_RESULT_OK == ret) {
89 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_FINISH,stage);
93 CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_READY_TO_INSTAL,stage);
98 da_result_t process_install(stage_info *stage)
100 da_result_t ret = DA_RESULT_OK;
102 DA_LOG_FUNC_START(Default);
104 if (DA_NULL == stage)
105 return DA_ERR_INVALID_ARGUMENT;
107 /* install process. */
108 ret = install_content(stage);
110 if (DA_RESULT_OK == ret) {
111 int download_id = GET_STAGE_DL_ID(stage);
112 char *content_type = DA_NULL;
114 if (GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage))) {
115 content_type = strdup(
116 GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)));
118 /* Fixme : Is Content-Type on HTTP header mandatory? */
119 DA_LOG_ERR(Default, "no content type!");
120 ret = DA_ERR_MISMATCH_CONTENT_TYPE;
124 /* update installed path */
125 send_client_update_downloading_info(
127 GET_DL_REQ_ID(download_id),
128 GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
129 GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage))
134 content_type = DA_NULL;
142 static da_result_t __cancel_download_with_download_id(int download_id)
144 da_result_t ret = DA_RESULT_OK;
145 download_state_t download_state;
146 stage_info *stage = DA_NULL;
148 DA_LOG_FUNC_START(Default);
150 _da_thread_mutex_lock (&mutex_download_state[download_id]);
151 download_state = GET_DL_STATE_ON_ID(download_id);
152 DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(download_id));
153 if (download_state == DOWNLOAD_STATE_IDLE) {
154 /* FIXME later : It is better to check and exit itself at download thread */
155 pthread_cancel(GET_DL_THREAD_ID(download_id));
156 } else if (download_state >= DOWNLOAD_STATE_READY_TO_INSTAL) {
157 DA_LOG_CRITICAL(Default, "Already download is completed. Do not send cancel request");
158 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
161 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
163 if (ret != DA_RESULT_OK)
166 stage = GET_DL_CURRENT_STAGE(download_id);
170 ret = request_to_cancel_http_download(stage);
171 if (ret != DA_RESULT_OK)
173 DA_LOG(Default, "Download cancel Successful for download id - %d", download_id);
178 da_result_t cancel_download(int dl_req_id)
180 da_result_t ret = DA_RESULT_OK;
182 int download_id = DA_INVALID_ID;
184 DA_LOG_FUNC_START(Default);
186 if ((dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS) ||
187 (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI)) {
188 DA_LOG(Default, "All download items will be cancelled");
189 ret = cancel_download_all(dl_req_id);
193 ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
194 if (ret != DA_RESULT_OK) {
195 DA_LOG_ERR(Default, "dl req ID is not Valid");
199 if (DA_FALSE == is_valid_dl_ID(download_id)) {
200 DA_LOG_ERR(Default, "Download ID is not Valid");
201 ret = DA_ERR_INVALID_ARGUMENT;
205 ret = __cancel_download_with_download_id(download_id);
212 da_result_t cancel_download_all(int dl_req_id)
214 da_result_t ret = DA_RESULT_OK;
216 int download_id = DA_INVALID_ID;
218 da_bool_t b_any_flag_on = DA_FALSE;
220 state_watcher_t *state_watcher = DA_NULL;
222 DA_LOG_FUNC_START(Default);
224 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
225 state_watcher = &(download_mgr.state_watcher);
227 _da_thread_mutex_lock(&(state_watcher->mutex));
228 state_watcher->type = STATE_WATCHER_TYPE_CANCEL;
229 state_watcher->is_progressing_to_all = DA_TRUE;
230 _da_thread_mutex_unlock(&(state_watcher->mutex));
233 for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
234 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
237 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
238 state_watcher_flag_ON_for_download_id(state_watcher,
241 b_any_flag_on = DA_TRUE;
243 /* ToDo: retry if fail, check download_state, don't set flag for state_watcher if state is invalid */
244 ret = __cancel_download_with_download_id(download_id);
245 /*if (ret == DA_RESULT_OK) {
246 state_watcher_flag_ON_for_download_id(
247 state_watcher, download_id);
248 b_any_flag_on = DA_TRUE;
254 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
255 _da_thread_mutex_lock(&(state_watcher->mutex));
256 state_watcher->is_progressing_to_all = DA_FALSE;
257 _da_thread_mutex_unlock(&(state_watcher->mutex));
260 if (b_any_flag_on == DA_FALSE) {
261 DA_LOG_ERR(Default, "There is no item to be able to cancel.");
262 ret = DA_ERR_INVALID_DL_REQ_ID;
268 static da_result_t __suspend_download_with_download_id(int download_id)
270 da_result_t ret = DA_RESULT_OK;
271 download_state_t download_state;
272 stage_info *stage = DA_NULL;
274 DA_LOG_FUNC_START(Default);
276 _da_thread_mutex_lock (&mutex_download_state[download_id]);
277 download_state = GET_DL_STATE_ON_ID(download_id);
278 DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(download_id));
279 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
281 if (ret != DA_RESULT_OK)
284 stage = GET_DL_CURRENT_STAGE(download_id);
286 return DA_ERR_CANNOT_SUSPEND;
288 ret = request_to_suspend_http_download(stage);
289 if (ret != DA_RESULT_OK)
291 DA_LOG(Default, "Download Suspend Successful for download id-%d", download_id);
296 da_result_t suspend_download(int dl_req_id)
298 da_result_t ret = DA_RESULT_OK;
299 int download_id = DA_INVALID_ID;
301 DA_LOG_FUNC_START(Default);
303 if ((dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS) ||
304 (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI)) {
305 DA_LOG(Default, "All download items will be suspended");
306 ret = suspend_download_all(dl_req_id);
310 ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
311 if (ret != DA_RESULT_OK) {
312 DA_LOG_ERR(Default, "dl req ID is not Valid");
316 if (DA_FALSE == is_valid_dl_ID(download_id)) {
317 DA_LOG_ERR(Default, "Download ID is not Valid");
318 ret = DA_ERR_INVALID_ARGUMENT;
322 ret = __suspend_download_with_download_id(download_id);
329 da_result_t suspend_download_all(int dl_req_id)
331 da_result_t ret = DA_RESULT_OK;
333 int download_id = DA_INVALID_ID;
335 da_bool_t b_any_flag_on = DA_FALSE;
337 state_watcher_t *state_watcher = DA_NULL;
339 DA_LOG_FUNC_START(Default);
341 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
342 state_watcher = &(download_mgr.state_watcher);
344 _da_thread_mutex_lock(&(state_watcher->mutex));
345 state_watcher->type = STATE_WATCHER_TYPE_SUSPEND;
346 state_watcher->is_progressing_to_all = DA_TRUE;
347 _da_thread_mutex_unlock(&(state_watcher->mutex));
350 for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
351 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
353 /* ToDo: retry if fail, check download_state, don't set flag for state_watcher if state is invalid */
354 ret = __suspend_download_with_download_id(download_id);
355 if (ret == DA_RESULT_OK) {
356 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
357 state_watcher_flag_ON_for_download_id(
358 state_watcher, download_id);
360 b_any_flag_on = DA_TRUE;
366 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
367 _da_thread_mutex_lock(&(state_watcher->mutex));
368 state_watcher->is_progressing_to_all = DA_FALSE;
369 _da_thread_mutex_unlock(&(state_watcher->mutex));
372 if (b_any_flag_on == DA_FALSE) {
373 DA_LOG_ERR(Default, "There is no item to be able to suspend.");
374 ret = DA_ERR_CANNOT_SUSPEND;
380 static da_result_t __resume_download_with_download_id(int download_id)
382 da_result_t ret = DA_RESULT_OK;
383 download_state_t download_state;
384 stage_info *stage = DA_NULL;
386 DA_LOG_FUNC_START(Default);
388 _da_thread_mutex_lock (&mutex_download_state[download_id]);
389 download_state = GET_DL_STATE_ON_ID(download_id);
390 DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(download_id));
391 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
393 if (ret != DA_RESULT_OK)
396 stage = GET_DL_CURRENT_STAGE(download_id);
398 ret = request_to_resume_http_download(stage);
399 if (ret != DA_RESULT_OK)
401 DA_LOG(Default, "Download Resume Successful for download id-%d", download_id);
406 da_result_t resume_download(int dl_req_id)
408 da_result_t ret = DA_RESULT_OK;
409 int download_id = DA_INVALID_ID;
411 DA_LOG_FUNC_START(Default);
413 if ((dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS) ||
414 (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI)) {
415 DA_LOG(Default, "All download items will be resumed");
416 ret = resume_download_all(dl_req_id);
420 ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
421 if (ret != DA_RESULT_OK)
424 if (DA_FALSE == is_valid_dl_ID(download_id)) {
425 DA_LOG_ERR(Default, "Download ID is not Valid");
426 ret = DA_ERR_INVALID_ARGUMENT;
430 ret = __resume_download_with_download_id(download_id);
436 da_result_t resume_download_all(int dl_req_id)
438 da_result_t ret = DA_RESULT_OK;
440 int download_id = DA_INVALID_ID;
442 da_bool_t b_any_flag_on = DA_FALSE;
444 state_watcher_t *state_watcher = DA_NULL;
446 DA_LOG_FUNC_START(Default);
448 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
449 state_watcher = &(download_mgr.state_watcher);
451 _da_thread_mutex_lock(&(state_watcher->mutex));
452 state_watcher->type = STATE_WATCHER_TYPE_RESUME;
453 state_watcher->is_progressing_to_all = DA_TRUE;
454 _da_thread_mutex_unlock(&(state_watcher->mutex));
457 for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
458 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
461 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
462 state_watcher_flag_ON_for_download_id(state_watcher,
465 b_any_flag_on = DA_TRUE;
467 /* ToDo: retry if fail, check download_state, don't set flag for state_watcher if state is invalid */
468 ret = __resume_download_with_download_id(download_id);
469 /*if (ret == DA_RESULT_OK) {
470 state_watcher_flag_ON_for_download_id(
471 state_watcher, download_id);
472 b_any_flag_on = DA_TRUE;
478 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
479 _da_thread_mutex_lock(&(state_watcher->mutex));
480 state_watcher->is_progressing_to_all = DA_FALSE;
481 _da_thread_mutex_unlock(&(state_watcher->mutex));
484 if (b_any_flag_on == DA_FALSE) {
485 DA_LOG(Default, "There is no item to be able to cancel.");
486 ret = DA_ERR_INVALID_DL_REQ_ID;
492 da_result_t send_user_noti_and_finish_download_flow(int download_id)
494 da_result_t ret = DA_RESULT_OK;
495 download_state_t download_state = DA_NULL;
496 da_bool_t need_destroy_download_info = DA_FALSE;
498 DA_LOG_FUNC_START(Default);
500 _da_thread_mutex_lock (&mutex_download_state[download_id]);
501 download_state = GET_DL_STATE_ON_ID(download_id);
502 DA_LOG(Default, "state = %d", download_state);
503 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
505 switch (download_state) {
506 case DOWNLOAD_STATE_FINISH:
507 send_client_da_state(download_id, DA_STATE_FINISHED,
509 need_destroy_download_info = DA_TRUE;
511 case DOWNLOAD_STATE_CANCELED:
512 send_client_da_state(download_id, DA_STATE_CANCELED,
514 need_destroy_download_info = DA_TRUE;
517 DA_LOG(Default, "download state = %d", download_state);
521 if (need_destroy_download_info == DA_TRUE) {
522 destroy_download_info(download_id);
524 DA_LOG_CRITICAL(Default, "download info is not destroyed");