Remove DRM dependency
[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         if (ret != DA_RESULT_OK)
164                 goto ERR;
165
166         stage = GET_DL_CURRENT_STAGE(download_id);
167         if (!stage)
168                 return DA_RESULT_OK;
169
170         ret = request_to_cancel_http_download(stage);
171         if (ret != DA_RESULT_OK)
172                 goto ERR;
173         DA_LOG(Default, "Download cancel Successful for download id - %d", download_id);
174 ERR:
175         return ret;
176 }
177
178 da_result_t cancel_download(int dl_req_id)
179 {
180         da_result_t ret = DA_RESULT_OK;
181
182         int download_id = DA_INVALID_ID;
183
184         DA_LOG_FUNC_START(Default);
185
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);
190                 return ret;
191         }
192
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");
196                 goto ERR;
197         }
198
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;
202                 goto ERR;
203         }
204
205         ret = __cancel_download_with_download_id(download_id);
206
207 ERR:
208         return ret;
209
210 }
211
212 da_result_t cancel_download_all(int dl_req_id)
213 {
214         da_result_t ret = DA_RESULT_OK;
215
216         int download_id = DA_INVALID_ID;
217         int iter = 0;
218         da_bool_t b_any_flag_on = DA_FALSE;
219
220         state_watcher_t *state_watcher = DA_NULL;
221
222         DA_LOG_FUNC_START(Default);
223
224         if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
225                 state_watcher = &(download_mgr.state_watcher);
226
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));
231         }
232
233         for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
234                 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
235                         download_id = iter;
236
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,
239                                         download_id);
240                         }
241                         b_any_flag_on = DA_TRUE;
242
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;
249                         }*/
250                 }
251
252         }
253
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));
258         }
259
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;
263         }
264
265         return ret;
266 }
267
268 static da_result_t __suspend_download_with_download_id(int download_id)
269 {
270         da_result_t ret = DA_RESULT_OK;
271         download_state_t download_state;
272         stage_info *stage = DA_NULL;
273
274         DA_LOG_FUNC_START(Default);
275
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]);
280
281         if (ret != DA_RESULT_OK)
282                 goto ERR;
283
284         stage = GET_DL_CURRENT_STAGE(download_id);
285         if (!stage)
286                 return DA_ERR_CANNOT_SUSPEND;
287
288         ret = request_to_suspend_http_download(stage);
289         if (ret != DA_RESULT_OK)
290                 goto ERR;
291         DA_LOG(Default, "Download Suspend Successful for download id-%d", download_id);
292 ERR:
293         return ret;
294 }
295
296 da_result_t suspend_download(int dl_req_id)
297 {
298         da_result_t ret = DA_RESULT_OK;
299         int download_id = DA_INVALID_ID;
300
301         DA_LOG_FUNC_START(Default);
302
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);
307                 return ret;
308         }
309
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");
313                 goto ERR;
314         }
315
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;
319                 goto ERR;
320         }
321
322         ret = __suspend_download_with_download_id(download_id);
323
324 ERR:
325         return ret;
326
327 }
328
329 da_result_t suspend_download_all(int dl_req_id)
330 {
331         da_result_t ret = DA_RESULT_OK;
332
333         int download_id = DA_INVALID_ID;
334         int iter = 0;
335         da_bool_t b_any_flag_on = DA_FALSE;
336
337         state_watcher_t *state_watcher = DA_NULL;
338
339         DA_LOG_FUNC_START(Default);
340
341         if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
342                 state_watcher = &(download_mgr.state_watcher);
343
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));
348         }
349
350         for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
351                 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
352                         download_id = iter;
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);
359                                 }
360                                 b_any_flag_on = DA_TRUE;
361                         }
362                 }
363
364         }
365
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));
370         }
371
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;
375         }
376
377         return ret;
378 }
379
380 static da_result_t __resume_download_with_download_id(int download_id)
381 {
382         da_result_t ret = DA_RESULT_OK;
383         download_state_t download_state;
384         stage_info *stage = DA_NULL;
385
386         DA_LOG_FUNC_START(Default);
387
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]);
392
393         if (ret != DA_RESULT_OK)
394                 goto ERR;
395
396         stage = GET_DL_CURRENT_STAGE(download_id);
397
398         ret = request_to_resume_http_download(stage);
399         if (ret != DA_RESULT_OK)
400                 goto ERR;
401         DA_LOG(Default, "Download Resume Successful for download id-%d", download_id);
402 ERR:
403         return ret;
404 }
405
406 da_result_t resume_download(int dl_req_id)
407 {
408         da_result_t ret = DA_RESULT_OK;
409         int download_id = DA_INVALID_ID;
410
411         DA_LOG_FUNC_START(Default);
412
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);
417                 return ret;
418         }
419
420         ret = get_download_id_for_dl_req_id(dl_req_id, &download_id);
421         if (ret != DA_RESULT_OK)
422                 goto ERR;
423
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;
427                 goto ERR;
428         }
429
430         ret = __resume_download_with_download_id(download_id);
431
432 ERR:
433         return ret;
434 }
435
436 da_result_t resume_download_all(int dl_req_id)
437 {
438         da_result_t ret = DA_RESULT_OK;
439
440         int download_id = DA_INVALID_ID;
441         int iter = 0;
442         da_bool_t b_any_flag_on = DA_FALSE;
443
444         state_watcher_t *state_watcher = DA_NULL;
445
446         DA_LOG_FUNC_START(Default);
447
448         if (dl_req_id == DA_DOWNLOAD_REQ_ID_FOR_ALL_ITEMS_WITH_UNIFIED_NOTI) {
449                 state_watcher = &(download_mgr.state_watcher);
450
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));
455         }
456
457         for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
458                 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
459                         download_id = iter;
460
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,
463                                         download_id);
464                         }
465                         b_any_flag_on = DA_TRUE;
466
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;
473                         }*/
474                 }
475
476         }
477
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));
482         }
483
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;
487         }
488
489         return ret;
490 }
491
492 da_result_t send_user_noti_and_finish_download_flow(int download_id)
493 {
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;
497
498         DA_LOG_FUNC_START(Default);
499
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]);
504
505         switch (download_state) {
506         case DOWNLOAD_STATE_FINISH:
507                 send_client_da_state(download_id, DA_STATE_FINISHED,
508                                 DA_RESULT_OK);
509                 need_destroy_download_info = DA_TRUE;
510                 break;
511         case DOWNLOAD_STATE_CANCELED:
512                 send_client_da_state(download_id, DA_STATE_CANCELED,
513                                 DA_RESULT_OK);
514                 need_destroy_download_info = DA_TRUE;
515                 break;
516         default:
517                 DA_LOG(Default, "download state = %d", download_state);
518                 break;
519         }
520
521         if (need_destroy_download_info == DA_TRUE) {
522                 destroy_download_info(download_id);
523         } else {
524                 DA_LOG_CRITICAL(Default, "download info is not destroyed");
525         }
526
527         return ret;
528 }
529