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 stage = GET_DL_CURRENT_STAGE(download_id);
167 ret = request_to_cancel_http_download(stage);
168 if (ret != DA_RESULT_OK)
170 DA_LOG(Default, "Download cancel Successful for download id - %d", download_id);
175 da_result_t cancel_download(int dl_req_id)
177 da_result_t ret = DA_RESULT_OK;
179 int download_id = DA_INVALID_ID;
181 DA_LOG_FUNC_START(Default);
183 if ((dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS) ||
184 (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI)) {
185 DA_LOG(Default, "All download items will be cancelled");
186 ret = cancel_download_all(dl_req_id);
190 ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
191 if (ret != DA_RESULT_OK) {
192 DA_LOG_ERR(Default, "dl req ID is not Valid");
196 if (DA_FALSE == is_valid_dl_ID(download_id)) {
197 DA_LOG_ERR(Default, "Download ID is not Valid");
198 ret = DA_ERR_INVALID_ARGUMENT;
202 ret = __cancel_download_with_download_id(download_id);
209 da_result_t cancel_download_all(int dl_req_id)
211 da_result_t ret = DA_RESULT_OK;
213 int download_id = DA_INVALID_ID;
215 da_bool_t b_any_flag_on = DA_FALSE;
217 state_watcher_t *state_watcher = DA_NULL;
219 DA_LOG_FUNC_START(Default);
221 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
222 state_watcher = &(download_mgr.state_watcher);
224 _da_thread_mutex_lock(&(state_watcher->mutex));
225 state_watcher->type = STATE_WATCHER_TYPE_CANCEL;
226 state_watcher->is_progressing_to_all = DA_TRUE;
227 _da_thread_mutex_unlock(&(state_watcher->mutex));
230 for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
231 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
234 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
235 state_watcher_flag_ON_for_download_id(state_watcher,
238 b_any_flag_on = DA_TRUE;
240 /* ToDo: retry if fail, check download_state, don't set flag for state_watcher if state is invalid */
241 ret = __cancel_download_with_download_id(download_id);
242 /*if (ret == DA_RESULT_OK) {
243 state_watcher_flag_ON_for_download_id(
244 state_watcher, download_id);
245 b_any_flag_on = DA_TRUE;
251 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
252 _da_thread_mutex_lock(&(state_watcher->mutex));
253 state_watcher->is_progressing_to_all = DA_FALSE;
254 _da_thread_mutex_unlock(&(state_watcher->mutex));
257 if (b_any_flag_on == DA_FALSE) {
258 DA_LOG_ERR(Default, "There is no item to be able to cancel.");
259 ret = DA_ERR_INVALID_DL_REQ_ID;
265 static da_result_t __suspend_download_with_download_id(int download_id)
267 da_result_t ret = DA_RESULT_OK;
268 download_state_t download_state;
269 stage_info *stage = DA_NULL;
271 DA_LOG_FUNC_START(Default);
273 _da_thread_mutex_lock (&mutex_download_state[download_id]);
274 download_state = GET_DL_STATE_ON_ID(download_id);
275 DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(download_id));
276 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
278 stage = GET_DL_CURRENT_STAGE(download_id);
280 return DA_ERR_CANNOT_SUSPEND;
282 ret = request_to_suspend_http_download(stage);
283 if (ret != DA_RESULT_OK)
285 DA_LOG(Default, "Download Suspend Successful for download id-%d", download_id);
290 da_result_t suspend_download(int dl_req_id)
292 da_result_t ret = DA_RESULT_OK;
293 int download_id = DA_INVALID_ID;
295 DA_LOG_FUNC_START(Default);
297 if ((dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS) ||
298 (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI)) {
299 DA_LOG(Default, "All download items will be suspended");
300 ret = suspend_download_all(dl_req_id);
304 ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
305 if (ret != DA_RESULT_OK) {
306 DA_LOG_ERR(Default, "dl req ID is not Valid");
310 if (DA_FALSE == is_valid_dl_ID(download_id)) {
311 DA_LOG_ERR(Default, "Download ID is not Valid");
312 ret = DA_ERR_INVALID_ARGUMENT;
316 ret = __suspend_download_with_download_id(download_id);
323 da_result_t suspend_download_all(int dl_req_id)
325 da_result_t ret = DA_RESULT_OK;
327 int download_id = DA_INVALID_ID;
329 da_bool_t b_any_flag_on = DA_FALSE;
331 state_watcher_t *state_watcher = DA_NULL;
333 DA_LOG_FUNC_START(Default);
335 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
336 state_watcher = &(download_mgr.state_watcher);
338 _da_thread_mutex_lock(&(state_watcher->mutex));
339 state_watcher->type = STATE_WATCHER_TYPE_SUSPEND;
340 state_watcher->is_progressing_to_all = DA_TRUE;
341 _da_thread_mutex_unlock(&(state_watcher->mutex));
344 for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
345 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
347 /* ToDo: retry if fail, check download_state, don't set flag for state_watcher if state is invalid */
348 ret = __suspend_download_with_download_id(download_id);
349 if (ret == DA_RESULT_OK) {
350 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
351 state_watcher_flag_ON_for_download_id(
352 state_watcher, download_id);
354 b_any_flag_on = DA_TRUE;
360 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
361 _da_thread_mutex_lock(&(state_watcher->mutex));
362 state_watcher->is_progressing_to_all = DA_FALSE;
363 _da_thread_mutex_unlock(&(state_watcher->mutex));
366 if (b_any_flag_on == DA_FALSE) {
367 DA_LOG_ERR(Default, "There is no item to be able to suspend.");
368 ret = DA_ERR_CANNOT_SUSPEND;
374 static da_result_t __resume_download_with_download_id(int download_id)
376 da_result_t ret = DA_RESULT_OK;
377 download_state_t download_state;
378 stage_info *stage = DA_NULL;
380 DA_LOG_FUNC_START(Default);
382 _da_thread_mutex_lock (&mutex_download_state[download_id]);
383 download_state = GET_DL_STATE_ON_ID(download_id);
384 DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(download_id));
385 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
387 stage = GET_DL_CURRENT_STAGE(download_id);
389 ret = request_to_resume_http_download(stage);
390 if (ret != DA_RESULT_OK)
392 DA_LOG(Default, "Download Resume Successful for download id-%d", download_id);
397 da_result_t resume_download(int dl_req_id)
399 da_result_t ret = DA_RESULT_OK;
400 int download_id = DA_INVALID_ID;
402 DA_LOG_FUNC_START(Default);
404 if ((dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS) ||
405 (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI)) {
406 DA_LOG(Default, "All download items will be resumed");
407 ret = resume_download_all(dl_req_id);
411 ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
412 if (ret != DA_RESULT_OK)
415 if (DA_FALSE == is_valid_dl_ID(download_id)) {
416 DA_LOG_ERR(Default, "Download ID is not Valid");
417 ret = DA_ERR_INVALID_ARGUMENT;
421 ret = __resume_download_with_download_id(download_id);
427 da_result_t resume_download_all(int dl_req_id)
429 da_result_t ret = DA_RESULT_OK;
431 int download_id = DA_INVALID_ID;
433 da_bool_t b_any_flag_on = DA_FALSE;
435 state_watcher_t *state_watcher = DA_NULL;
437 DA_LOG_FUNC_START(Default);
439 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
440 state_watcher = &(download_mgr.state_watcher);
442 _da_thread_mutex_lock(&(state_watcher->mutex));
443 state_watcher->type = STATE_WATCHER_TYPE_RESUME;
444 state_watcher->is_progressing_to_all = DA_TRUE;
445 _da_thread_mutex_unlock(&(state_watcher->mutex));
448 for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
449 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
452 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
453 state_watcher_flag_ON_for_download_id(state_watcher,
456 b_any_flag_on = DA_TRUE;
458 /* ToDo: retry if fail, check download_state, don't set flag for state_watcher if state is invalid */
459 ret = __resume_download_with_download_id(download_id);
460 /*if (ret == DA_RESULT_OK) {
461 state_watcher_flag_ON_for_download_id(
462 state_watcher, download_id);
463 b_any_flag_on = DA_TRUE;
469 if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
470 _da_thread_mutex_lock(&(state_watcher->mutex));
471 state_watcher->is_progressing_to_all = DA_FALSE;
472 _da_thread_mutex_unlock(&(state_watcher->mutex));
475 if (b_any_flag_on == DA_FALSE) {
476 DA_LOG(Default, "There is no item to be able to cancel.");
477 ret = DA_ERR_INVALID_DL_REQ_ID;
483 da_result_t send_user_noti_and_finish_download_flow(int download_id)
485 da_result_t ret = DA_RESULT_OK;
486 download_state_t download_state = DA_NULL;
487 da_bool_t need_destroy_download_info = DA_FALSE;
489 DA_LOG_FUNC_START(Default);
491 _da_thread_mutex_lock (&mutex_download_state[download_id]);
492 download_state = GET_DL_STATE_ON_ID(download_id);
493 DA_LOG(Default, "state = %d", download_state);
494 _da_thread_mutex_unlock (&mutex_download_state[download_id]);
496 switch (download_state) {
497 case DOWNLOAD_STATE_FINISH:
498 send_client_da_state(download_id, DA_STATE_FINISHED,
500 need_destroy_download_info = DA_TRUE;
502 case DOWNLOAD_STATE_CANCELED:
503 send_client_da_state(download_id, DA_STATE_CANCELED,
505 need_destroy_download_info = DA_TRUE;
508 DA_LOG(Default, "download state = %d", download_state);
512 if (need_destroy_download_info == DA_TRUE) {
513 destroy_download_info(download_id);
515 DA_LOG_CRITICAL(Default, "download info is not destroyed");