Revert manifest to default one
[profile/ivi/download-provider.git] / src / agent / download-agent-dl-mgr.c
1 /*
2  * Download Agent
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jungki Kwak <jungki.kwak@samsung.com>, Keunsoon Lee <keunsoon.lee@samsung.com>
7  *
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
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
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)
24  ***/
25
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"
34
35
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);
38
39
40 da_result_t requesting_download(stage_info *stage)
41 {
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;
45
46         DA_LOG_FUNC_START(Default);
47
48         if (!stage) {
49                 DA_LOG_ERR(Default, "stage is null..");
50                 ret = DA_ERR_INVALID_ARGUMENT;
51                 goto ERR;
52         }
53
54         ret = make_req_dl_info_http(stage, GET_STAGE_TRANSACTION_INFO(stage));
55         if (ret != DA_RESULT_OK)
56                 goto ERR;
57
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.");
62         } else {
63                 DA_LOG_ERR(Default, "Http download is failed. ret = %d", ret);
64                 goto ERR;
65         }
66
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)]);
70
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) {
74                 return ret;
75         }
76
77 ERR:
78         return ret;
79 }
80
81 da_result_t handle_after_download(stage_info *stage)
82 {
83         da_result_t ret = DA_RESULT_OK;
84
85         DA_LOG_FUNC_START(Default);
86
87         if (DA_TRUE == is_this_client_manual_download_type()) {
88                 if (DA_RESULT_OK == ret) {
89                         CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_FINISH,stage);
90                 }
91                 return ret;
92         }
93         CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_READY_TO_INSTAL,stage);
94
95         return ret;
96 }
97
98 da_result_t process_install(stage_info *stage)
99 {
100         da_result_t ret = DA_RESULT_OK;
101
102         DA_LOG_FUNC_START(Default);
103
104         if (DA_NULL == stage)
105                 return DA_ERR_INVALID_ARGUMENT;
106
107         /* install process. */
108         ret = install_content(stage);
109
110         if (DA_RESULT_OK == ret) {
111                 int download_id = GET_STAGE_DL_ID(stage);
112                 char *content_type = DA_NULL;
113
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)));
117                 } else {
118                         /* Fixme : Is Content-Type on HTTP header mandatory? */
119                         DA_LOG_ERR(Default, "no content type!");
120                         ret = DA_ERR_MISMATCH_CONTENT_TYPE;
121                         return ret;
122                 }
123
124                 /* update installed path */
125                 send_client_update_downloading_info(
126                         download_id,
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))
130                                 );
131
132                 if (content_type) {
133                         free(content_type);
134                         content_type = DA_NULL;
135                 }
136
137                 return DA_RESULT_OK;
138         }
139         return ret;
140 }
141
142 static da_result_t __cancel_download_with_download_id(int download_id)
143 {
144         da_result_t ret = DA_RESULT_OK;
145         download_state_t download_state;
146         stage_info *stage = DA_NULL;
147
148         DA_LOG_FUNC_START(Default);
149
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]);
159                 return ret;
160         }
161         _da_thread_mutex_unlock (&mutex_download_state[download_id]);
162
163         stage = GET_DL_CURRENT_STAGE(download_id);
164         if (!stage)
165                 return DA_RESULT_OK;
166
167         ret = request_to_cancel_http_download(stage);
168         if (ret != DA_RESULT_OK)
169                 goto ERR;
170         DA_LOG(Default, "Download cancel Successful for download id - %d", download_id);
171 ERR:
172         return ret;
173 }
174
175 da_result_t cancel_download(int dl_req_id)
176 {
177         da_result_t ret = DA_RESULT_OK;
178
179         int download_id = DA_INVALID_ID;
180
181         DA_LOG_FUNC_START(Default);
182
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);
187                 return ret;
188         }
189
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");
193                 goto ERR;
194         }
195
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;
199                 goto ERR;
200         }
201
202         ret = __cancel_download_with_download_id(download_id);
203
204 ERR:
205         return ret;
206
207 }
208
209 da_result_t cancel_download_all(int dl_req_id)
210 {
211         da_result_t ret = DA_RESULT_OK;
212
213         int download_id = DA_INVALID_ID;
214         int iter = 0;
215         da_bool_t b_any_flag_on = DA_FALSE;
216
217         state_watcher_t *state_watcher = DA_NULL;
218
219         DA_LOG_FUNC_START(Default);
220
221         if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
222                 state_watcher = &(download_mgr.state_watcher);
223
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));
228         }
229
230         for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
231                 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
232                         download_id = iter;
233
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,
236                                         download_id);
237                         }
238                         b_any_flag_on = DA_TRUE;
239
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;
246                         }*/
247                 }
248
249         }
250
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));
255         }
256
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;
260         }
261
262         return ret;
263 }
264
265 static da_result_t __suspend_download_with_download_id(int download_id)
266 {
267         da_result_t ret = DA_RESULT_OK;
268         download_state_t download_state;
269         stage_info *stage = DA_NULL;
270
271         DA_LOG_FUNC_START(Default);
272
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]);
277
278         stage = GET_DL_CURRENT_STAGE(download_id);
279         if (!stage)
280                 return DA_ERR_CANNOT_SUSPEND;
281
282         ret = request_to_suspend_http_download(stage);
283         if (ret != DA_RESULT_OK)
284                 goto ERR;
285         DA_LOG(Default, "Download Suspend Successful for download id-%d", download_id);
286 ERR:
287         return ret;
288 }
289
290 da_result_t suspend_download(int dl_req_id)
291 {
292         da_result_t ret = DA_RESULT_OK;
293         int download_id = DA_INVALID_ID;
294
295         DA_LOG_FUNC_START(Default);
296
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);
301                 return ret;
302         }
303
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");
307                 goto ERR;
308         }
309
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;
313                 goto ERR;
314         }
315
316         ret = __suspend_download_with_download_id(download_id);
317
318 ERR:
319         return ret;
320
321 }
322
323 da_result_t suspend_download_all(int dl_req_id)
324 {
325         da_result_t ret = DA_RESULT_OK;
326
327         int download_id = DA_INVALID_ID;
328         int iter = 0;
329         da_bool_t b_any_flag_on = DA_FALSE;
330
331         state_watcher_t *state_watcher = DA_NULL;
332
333         DA_LOG_FUNC_START(Default);
334
335         if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
336                 state_watcher = &(download_mgr.state_watcher);
337
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));
342         }
343
344         for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
345                 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
346                         download_id = iter;
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);
353                                 }
354                                 b_any_flag_on = DA_TRUE;
355                         }
356                 }
357
358         }
359
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));
364         }
365
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;
369         }
370
371         return ret;
372 }
373
374 static da_result_t __resume_download_with_download_id(int download_id)
375 {
376         da_result_t ret = DA_RESULT_OK;
377         download_state_t download_state;
378         stage_info *stage = DA_NULL;
379
380         DA_LOG_FUNC_START(Default);
381
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]);
386
387         stage = GET_DL_CURRENT_STAGE(download_id);
388
389         ret = request_to_resume_http_download(stage);
390         if (ret != DA_RESULT_OK)
391                 goto ERR;
392         DA_LOG(Default, "Download Resume Successful for download id-%d", download_id);
393 ERR:
394         return ret;
395 }
396
397 da_result_t resume_download(int dl_req_id)
398 {
399         da_result_t ret = DA_RESULT_OK;
400         int download_id = DA_INVALID_ID;
401
402         DA_LOG_FUNC_START(Default);
403
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);
408                 return ret;
409         }
410
411         ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
412         if (ret != DA_RESULT_OK)
413                 goto ERR;
414
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;
418                 goto ERR;
419         }
420
421         ret = __resume_download_with_download_id(download_id);
422
423 ERR:
424         return ret;
425 }
426
427 da_result_t resume_download_all(int dl_req_id)
428 {
429         da_result_t ret = DA_RESULT_OK;
430
431         int download_id = DA_INVALID_ID;
432         int iter = 0;
433         da_bool_t b_any_flag_on = DA_FALSE;
434
435         state_watcher_t *state_watcher = DA_NULL;
436
437         DA_LOG_FUNC_START(Default);
438
439         if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
440                 state_watcher = &(download_mgr.state_watcher);
441
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));
446         }
447
448         for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
449                 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
450                         download_id = iter;
451
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,
454                                         download_id);
455                         }
456                         b_any_flag_on = DA_TRUE;
457
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;
464                         }*/
465                 }
466
467         }
468
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));
473         }
474
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;
478         }
479
480         return ret;
481 }
482
483 da_result_t send_user_noti_and_finish_download_flow(int download_id)
484 {
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;
488
489         DA_LOG_FUNC_START(Default);
490
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]);
495
496         switch (download_state) {
497         case DOWNLOAD_STATE_FINISH:
498                 send_client_da_state(download_id, DA_STATE_FINISHED,
499                                 DA_RESULT_OK);
500                 need_destroy_download_info = DA_TRUE;
501                 break;
502         case DOWNLOAD_STATE_CANCELED:
503                 send_client_da_state(download_id, DA_STATE_CANCELED,
504                                 DA_RESULT_OK);
505                 need_destroy_download_info = DA_TRUE;
506                 break;
507         default:
508                 DA_LOG(Default, "download state = %d", download_state);
509                 break;
510         }
511
512         if (need_destroy_download_info == DA_TRUE) {
513                 destroy_download_info(download_id);
514         } else {
515                 DA_LOG_CRITICAL(Default, "download info is not destroyed");
516         }
517
518         return ret;
519 }
520