Revert manifest to default one
[profile/ivi/download-provider.git] / src / agent / download-agent-dl-info-util.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-info-util.c
21  * @brief               create and destroy functions for download_info
22  * @author              Keunsoon Lee(keunsoon.lee@samsung.com)
23  * @author              Jungki Kwak(jungki.kwak@samsung.com)
24  ***/
25
26 #include <string.h>
27
28 #include "download-agent-client-mgr.h"
29 #include "download-agent-dl-info-util.h"
30 #include "download-agent-debug.h"
31 #include "download-agent-utils.h"
32 #include "download-agent-file.h"
33 #include "download-agent-http-mgr.h"
34 #include "download-agent-plugin-conf.h"
35
36 pthread_mutex_t mutex_download_state[DA_MAX_DOWNLOAD_ID];
37 static pthread_mutex_t mutex_download_mgr = PTHREAD_MUTEX_INITIALIZER;
38 download_mgr_t download_mgr;
39
40 void init_state_watcher(state_watcher_t *state_watcher);
41 void cleanup_state_watcher(state_watcher_t *state_watcher);
42
43 da_result_t set_default_header_info(void);
44
45 void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic);
46 void cleanup_req_dl_info_http(req_dl_info *http_download);
47 void destroy_file_info(file_info *file);
48
49 da_result_t init_download_mgr() {
50         da_result_t ret = DA_RESULT_OK;
51         int i = 0;
52
53         DA_LOG_FUNC_START(Default);
54
55         if (is_client_app_mgr_init() == DA_FALSE) {
56                 DA_LOG_ERR(Default, "client app manager is not initiated!");
57                 return DA_ERR_INVALID_CLIENT;
58         }
59
60         _da_thread_mutex_lock(&mutex_download_mgr);
61
62         if (download_mgr.is_init == DA_FALSE) {
63                 download_mgr.is_init = DA_TRUE;
64
65                 for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
66                         _da_thread_mutex_init(&mutex_download_state[i], DA_NULL);
67                         init_download_info(i);
68                 }
69
70                 init_state_watcher(&(download_mgr.state_watcher));
71                 init_dl_req_id_history(&(download_mgr.dl_req_id_history));
72
73                 download_mgr.default_hdr_info = (default_http_hdr_info_t *) calloc(1,
74                                 sizeof(default_http_hdr_info_t));
75                 if (download_mgr.default_hdr_info) {
76                         /* Don't check return value,
77                          *  because UA and UAprof is not mandatory field at HTTP request header */
78                         set_default_header_info();
79                 } else {
80                         DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
81                         ret = DA_ERR_FAIL_TO_MEMALLOC;
82                 }
83         }
84
85         _da_thread_mutex_unlock(&mutex_download_mgr);
86
87         return ret;
88 }
89
90 da_result_t deinit_download_mgr(void) {
91         da_result_t ret = DA_RESULT_OK;
92
93         DA_LOG_FUNC_START(Default);
94
95         _da_thread_mutex_lock(&mutex_download_mgr);
96         if (download_mgr.is_init == DA_TRUE) {
97                 int i = 0;
98                 download_info_t *dl_info = DA_NULL;
99                 void *t_return = NULL;
100                 for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
101                         dl_info = &(download_mgr.download_info[i]);
102                         if (dl_info && dl_info->is_using) {
103                                 request_to_abort_http_download(GET_DL_CURRENT_STAGE(i));
104                                 DA_LOG_CRITICAL(Thread, "===download id[%d] thread id[%lu] join===",i, GET_DL_THREAD_ID(i));
105 /* Because the download daemon can call the deinit function, the resources of pthread are not freed
106    FIXME later : It is needed to change the termination flow again.
107                 if (pthread_join(GET_DL_THREAD_ID(i), &t_return) < 0) {
108                         DA_LOG_ERR(Thread, "join client thread is failed!!!");
109                 }
110 */
111                 DA_LOG_CRITICAL(Thread, "===download id[%d] thread join return[%d]===",i, (char*)t_return);
112 }
113 }
114                 download_mgr.is_init = DA_FALSE;
115                 cleanup_state_watcher(&(download_mgr.state_watcher));
116                 if (NULL != download_mgr.default_hdr_info) {
117                         if (NULL != download_mgr.default_hdr_info->user_agent_string)
118                                 free(download_mgr.default_hdr_info->user_agent_string);
119
120                         download_mgr.default_hdr_info->user_agent_string = NULL;
121
122                         free(download_mgr.default_hdr_info);
123                         download_mgr.default_hdr_info = NULL;
124                 }
125                 deinit_dl_req_id_history(&(download_mgr.dl_req_id_history));
126         }
127         _da_thread_mutex_unlock(&mutex_download_mgr);
128         return ret;
129 }
130
131 da_result_t set_default_header_info(void)
132 {
133         da_result_t ret = DA_RESULT_OK;
134
135         ret = get_user_agent_string(
136                         &download_mgr.default_hdr_info->user_agent_string);
137
138         if (DA_RESULT_OK != ret)
139                 goto ERR;
140         else
141                 DA_LOG(Default, "download_mgr.default_hdr_info->user_agent_string = %s ",
142                                         download_mgr.default_hdr_info->user_agent_string);
143 ERR:
144         return ret;
145 }
146
147 void init_download_info(int download_id)
148 {
149         download_info_t *dl_info = DA_NULL;
150
151 //      DA_LOG_FUNC_START(Default);
152
153         _da_thread_mutex_lock(&mutex_download_state[download_id]);
154         DA_LOG(Default, "Init download_id [%d] Info", download_id);
155         dl_info = &(download_mgr.download_info[download_id]);
156
157         dl_info->is_using = DA_FALSE;
158         dl_info->state = DOWNLOAD_STATE_IDLE;
159         dl_info->download_stage_data = DA_NULL;
160         dl_info->dl_req_id = DA_NULL;
161         dl_info->user_install_path = DA_NULL;
162         dl_info->user_data = DA_NULL;
163
164         Q_init_queue(&(dl_info->queue));
165
166         DA_LOG(Default, "Init download_id [%d] Info END", download_id);
167         _da_thread_mutex_unlock(&mutex_download_state[download_id]);
168
169         return;
170 }
171
172 void destroy_download_info(int download_id)
173 {
174         download_info_t *dl_info = DA_NULL;
175
176         DA_LOG_FUNC_START(Default);
177
178         DA_LOG(Default, "Destroying download_id [%d] Info", download_id);
179
180         if (download_id == DA_INVALID_ID) {
181                 DA_LOG_ERR(Default, "invalid download_id");
182                 return;
183         }
184
185         dl_info = &(download_mgr.download_info[download_id]);
186         if (DA_FALSE == dl_info->is_using) {
187 /*              DA_LOG_ERR(Default, "invalid download_id"); */
188                 return;
189         }
190
191         _da_thread_mutex_lock (&mutex_download_state[download_id]);
192         dl_info->state = DOWNLOAD_STATE_IDLE;
193         DA_LOG(Default, "Changed download_state to - [%d] ", dl_info->state);
194
195         dl_info->active_dl_thread_id = 0;
196
197         if (dl_info->download_stage_data != DA_NULL) {
198                 remove_download_stage(download_id, dl_info->download_stage_data);
199                 dl_info->download_stage_data = DA_NULL;
200         }
201         dl_info->dl_req_id = DA_NULL;
202         if (dl_info->user_install_path) {
203                 free(dl_info->user_install_path);
204                 dl_info->user_install_path = DA_NULL;
205         }
206         dl_info->user_data = DA_NULL;
207         dl_info->cur_da_state = DA_STATE_WAITING;
208
209         Q_destroy_queue(&(dl_info->queue));
210
211         dl_info->is_using = DA_FALSE;
212
213         DA_LOG(Default, "Destroying download_id [%d] Info END", download_id);
214         _da_thread_mutex_unlock (&mutex_download_state[download_id]);
215         return;
216 }
217
218 void *Add_new_download_stage(int download_id)
219 {
220         stage_info *download_stage_data = NULL;
221         stage_info *new_download_stage_data = NULL;
222
223         DA_LOG_FUNC_START(Default);
224
225         new_download_stage_data = (stage_info*)calloc(1, sizeof(stage_info));
226         if (!new_download_stage_data)
227                 goto ERR;
228
229         new_download_stage_data->dl_id = download_id;
230         download_stage_data = GET_DL_CURRENT_STAGE(download_id);
231         if (download_stage_data) {
232                 while (download_stage_data->next_stage_info) {
233                         download_stage_data
234                                         = download_stage_data->next_stage_info;
235                 };
236                 download_stage_data->next_stage_info = new_download_stage_data;
237         } else {
238                 GET_DL_CURRENT_STAGE(download_id) = new_download_stage_data;
239         }
240         DA_LOG(Default, "NEW STAGE ADDED FOR DOWNLOAD ID[%d] new_stage[%p]", download_id,new_download_stage_data);
241
242 ERR:
243         return new_download_stage_data;
244 }
245
246 void remove_download_stage(int download_id, stage_info *in_stage)
247 {
248         stage_info *stage = DA_NULL;
249
250         DA_LOG_FUNC_START(Default);
251
252         stage = GET_DL_CURRENT_STAGE(download_id);
253         if (DA_NULL == stage) {
254                 DA_LOG_VERBOSE(Default, "There is no stage field on download_id = %d", download_id);
255                 goto ERR;
256         }
257
258         if (DA_NULL == in_stage) {
259                 DA_LOG_VERBOSE(Default, "There is no in_stage to remove.");
260                 goto ERR;
261         }
262
263         if (in_stage == stage) {
264                 DA_LOG_VERBOSE(Default, "Base stage will be removed. in_stage[%p]",in_stage);
265                 DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info);
266                 GET_DL_CURRENT_STAGE(download_id) = stage->next_stage_info;
267                 empty_stage_info(in_stage);
268                 free(in_stage);
269                 in_stage = DA_NULL;
270         } else {
271                 while (in_stage != stage->next_stage_info) {
272                         stage = stage->next_stage_info;
273                 }
274                 if (in_stage == stage->next_stage_info) {
275                         stage->next_stage_info
276                                 = stage->next_stage_info->next_stage_info;
277                         DA_LOG_VERBOSE(Default, "Stage will be removed. in_stage[%p]",in_stage);
278                         DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info);
279                         empty_stage_info(in_stage);
280                         free(in_stage);
281                         in_stage = DA_NULL;
282                 }
283         }
284
285 ERR:
286         return;
287 }
288
289 void empty_stage_info(stage_info *in_stage)
290 {
291         source_info_t *source_information = NULL;
292         req_dl_info *request_download_info = NULL;
293         file_info *file_information = NULL;
294
295         DA_LOG_FUNC_START(Default);
296
297         DA_LOG(Default, "Stage to Remove:[%p]", in_stage);
298         source_information = GET_STAGE_SOURCE_INFO(in_stage);
299
300         cleanup_source_info_basic_download(
301                         GET_SOURCE_BASIC(source_information));
302
303         request_download_info = GET_STAGE_TRANSACTION_INFO(in_stage);
304
305         cleanup_req_dl_info_http(request_download_info);
306
307         file_information = GET_STAGE_CONTENT_STORE_INFO(in_stage);
308         destroy_file_info(file_information);
309 }
310
311 void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic)
312 {
313         if (NULL == source_info_basic)
314                 goto ERR;
315
316         DA_LOG_FUNC_START(Default);
317
318         if (NULL != source_info_basic->url) {
319                 free(source_info_basic->url);
320                 source_info_basic->url = DA_NULL;
321         }
322
323 ERR:
324         return;
325
326 }
327
328 void cleanup_req_dl_info_http(req_dl_info *http_download)
329 {
330         DA_LOG_FUNC_START(Default);
331
332         if (http_download->http_info.http_msg_request) {
333                 http_msg_request_destroy(
334                                 &(http_download->http_info.http_msg_request));
335         }
336
337         if (http_download->http_info.http_msg_response) {
338                 http_msg_response_destroy(
339                                 &(http_download->http_info.http_msg_response));
340         }
341
342         if (DA_NULL != http_download->location_url) {
343                 free(http_download->location_url);
344                 http_download->location_url = DA_NULL;
345         }
346         if (DA_NULL != http_download->content_type_from_header) {
347                 free(http_download->content_type_from_header);
348                 http_download->content_type_from_header = DA_NULL;
349         }
350
351         if (DA_NULL != http_download->etag_from_header) {
352                 free(http_download->etag_from_header);
353                 http_download->etag_from_header = DA_NULL;
354         }
355
356         http_download->invloved_transaction_id = DA_INVALID_ID;
357         http_download->content_len_from_header = 0;
358         http_download->downloaded_data_size = 0;
359
360         _da_thread_mutex_destroy(&(http_download->mutex_http_state));
361
362         return;
363 }
364
365 void destroy_file_info(file_info *file_information)
366 {
367 //      DA_LOG_FUNC_START(Default);
368
369         if (!file_information)
370                 return;
371
372         if (file_information->file_name_tmp) {
373                 free(file_information->file_name_tmp);
374                 file_information->file_name_tmp = NULL;
375         }
376
377         if (file_information->file_name_final) {
378                 free(file_information->file_name_final);
379                 file_information->file_name_final = NULL;
380         }
381
382         if (file_information->content_type) {
383                 free(file_information->content_type);
384                 file_information->content_type = NULL;
385         }
386
387         if (file_information->pure_file_name) {
388                 free(file_information->pure_file_name);
389                 file_information->pure_file_name = NULL;
390         }
391
392         if (file_information->extension) {
393                 free(file_information->extension);
394                 file_information->extension = NULL;
395         }
396         return;
397 }
398
399 void clean_up_client_input_info(client_input_t *client_input)
400 {
401         DA_LOG_FUNC_START(Default);
402
403         if (client_input) {
404                 client_input->user_data = NULL;
405
406                 if (client_input->install_path) {
407                         free(client_input->install_path);
408                         client_input->install_path = DA_NULL;
409                 }
410
411                 if (client_input->file_name) {
412                         free(client_input->file_name);
413                         client_input->file_name = DA_NULL;
414                 }
415
416                 client_input_basic_t *client_input_basic =
417                                 &(client_input->client_input_basic);
418
419                 if (client_input_basic && client_input_basic->req_url) {
420                         free(client_input_basic->req_url);
421                         client_input_basic->req_url = DA_NULL;
422                 }
423
424                 if (client_input_basic && client_input_basic->user_request_header) {
425                         int i = 0;
426                         int count = client_input_basic->user_request_header_count;
427                         for (i = 0; i < count; i++)
428                         {
429                                 if (client_input_basic->user_request_header[i]) {
430                                         free(client_input_basic->user_request_header[i]);
431                                         client_input_basic->user_request_header[i] = DA_NULL;
432                                 }
433                         }
434
435                         free(client_input_basic->user_request_header);
436                         client_input_basic->user_request_header = DA_NULL;
437                         client_input_basic->user_request_header_count = 0;
438                 }
439         } else {
440                 DA_LOG_ERR(Default, "client_input is NULL.");
441         }
442
443         return;
444 }
445
446 da_result_t get_download_id_for_dl_req_id(
447         da_handle_t dl_req_id,
448         da_handle_t* download_id)
449 {
450         da_result_t ret = DA_ERR_INVALID_DL_REQ_ID;
451         int iter = 0;
452
453         if (dl_req_id < 0) {
454                 DA_LOG_ERR(Default, "dl_req_id is less than 0 - %d", dl_req_id);
455                 return DA_ERR_INVALID_DL_REQ_ID;
456         }
457
458         _da_thread_mutex_lock(&mutex_download_mgr);
459         for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
460                 if (download_mgr.download_info[iter].is_using == DA_TRUE) {
461                         if (download_mgr.download_info[iter].dl_req_id ==
462                                 dl_req_id) {
463                                 *download_id = iter;
464                                 ret = DA_RESULT_OK;
465                                 break;
466                         }
467                 }
468         }
469         _da_thread_mutex_unlock(&mutex_download_mgr);
470
471         return ret;
472 }
473
474
475 da_result_t get_available_download_id(da_handle_t *available_id)
476 {
477         da_result_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
478         int i;
479
480         _da_thread_mutex_lock(&mutex_download_mgr);
481         for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
482                 if (download_mgr.download_info[i].is_using == DA_FALSE) {
483                         init_download_info(i);
484
485                         download_mgr.download_info[i].is_using = DA_TRUE;
486
487                         download_mgr.download_info[i].dl_req_id
488                                 = get_available_dl_req_id(&(download_mgr.dl_req_id_history));
489
490                         *available_id = i;
491                         DA_LOG_CRITICAL(Default, "available download id = %d", *available_id);
492                         ret = DA_RESULT_OK;
493
494                         break;
495                 }
496         }
497         _da_thread_mutex_unlock(&mutex_download_mgr);
498
499         return ret;
500 }
501
502 da_bool_t is_valid_dl_ID( download_id)
503 {
504         da_bool_t ret = DA_FALSE;
505
506         if (download_id >= 0 && download_id < DA_MAX_DOWNLOAD_ID) {
507                 if (download_mgr.download_info[download_id].is_using == DA_TRUE)
508                         ret = DA_TRUE;
509         }
510
511         return ret;
512 }
513
514 void init_state_watcher(state_watcher_t *state_watcher)
515 {
516         DA_LOG_FUNC_START(Default);
517
518         _da_thread_mutex_init(&(state_watcher->mutex), DA_NULL);
519
520         _da_thread_mutex_lock(&(state_watcher->mutex));
521         state_watcher->type = STATE_WATCHER_TYPE_NONE;
522         state_watcher->state_watching_bitmap = 0;
523         state_watcher->is_progressing_to_all = DA_FALSE;
524         _da_thread_mutex_unlock(&(state_watcher->mutex));
525 }
526
527 void cleanup_state_watcher(state_watcher_t *state_watcher)
528 {
529         DA_LOG_FUNC_START(Default);
530
531         _da_thread_mutex_lock(&(state_watcher->mutex));
532         state_watcher->type = STATE_WATCHER_TYPE_NONE;
533         state_watcher->state_watching_bitmap = 0;
534         state_watcher->is_progressing_to_all = DA_FALSE;
535         _da_thread_mutex_unlock(&(state_watcher->mutex));
536
537         _da_thread_mutex_destroy(&(state_watcher->mutex));
538 }
539
540 void state_watcher_flag_ON_for_download_id(
541                 state_watcher_t *state_watcher,
542                 int download_id)
543 {
544         unsigned short mask = 0;
545
546         _da_thread_mutex_lock(&(state_watcher->mutex));
547
548         mask = 1 << download_id;
549
550         state_watcher->state_watching_bitmap |= mask;
551
552         DA_LOG(Default, "state_watcher [%d], download_id [%d]", state_watcher->state_watching_bitmap, download_id);
553
554         _da_thread_mutex_unlock(&(state_watcher->mutex));
555 }
556
557 void state_watcher_flag_OFF_for_download_id(
558                 state_watcher_t *state_watcher,
559                 int download_id)
560 {
561         unsigned short mask = 0;
562
563         _da_thread_mutex_lock(&(state_watcher->mutex));
564
565         mask = ~(1 << download_id);
566
567         state_watcher->state_watching_bitmap &= mask;
568
569         DA_LOG(Default, "state_watcher [%d], download_id [%d]", state_watcher->state_watching_bitmap, download_id);
570
571         _da_thread_mutex_unlock(&(state_watcher->mutex));
572 }
573
574 da_bool_t state_watcher_is_flag_on_for_download_id_Q(
575                 state_watcher_t *state_watcher,
576                 int download_id)
577 {
578         da_bool_t b_ret = DA_FALSE;
579         unsigned short mask = 0;
580         unsigned short result = 0;
581
582         _da_thread_mutex_lock(&(state_watcher->mutex));
583
584         mask = 1 << download_id;
585
586         result = state_watcher->state_watching_bitmap & mask;
587
588         /*      DA_LOG(Default, "state_watcher after [%d]", state_watcher->state_watching_bitmap); */
589
590         _da_thread_mutex_unlock(&(state_watcher->mutex));
591
592         if (result)
593                 b_ret = DA_TRUE;
594         else
595                 b_ret = DA_FALSE;
596
597         return b_ret;
598 }
599
600 da_bool_t state_watcher_need_redirect_Q(int download_id)
601 {
602         da_bool_t b_ret = DA_FALSE;
603         state_watcher_t *state_watcher = DA_NULL;
604
605         state_watcher = &(download_mgr.state_watcher);
606
607         b_ret = state_watcher_is_flag_on_for_download_id_Q(state_watcher,
608                         download_id);
609
610         DA_LOG(Default, "state_watcher - need to redirect? [%d]", b_ret);
611
612         return b_ret;
613 }
614
615 void state_watcher_redirect_state(int download_id, da_state state, int err)
616 {
617         state_watcher_t *state_watcher = DA_NULL;
618
619         DA_LOG_FUNC_START(Default);
620
621         DA_LOG(Default, "download_id = [%d], receiving state = [%d]", download_id, state);
622
623         state_watcher = &(download_mgr.state_watcher);
624
625         switch (state) {
626         case DA_STATE_FAILED:
627         case DA_STATE_FINISHED:
628                 state_watcher_flag_OFF_for_download_id(state_watcher,
629                                 download_id);
630                 send_client_da_state(download_id, state, err);
631
632                 break;
633
634         case DA_STATE_CANCELED:
635                 state_watcher_flag_OFF_for_download_id(state_watcher,
636                                 download_id);
637
638                 if (state_watcher->type == STATE_WATCHER_TYPE_CANCEL) {
639                         if (!(state_watcher->state_watching_bitmap) &&
640                                 (state_watcher->is_progressing_to_all
641                                                         == DA_FALSE)) {
642                                 send_client_da_state(download_id,
643                                                 DA_STATE_CANCELED_ALL,
644                                                 DA_RESULT_OK);
645                         }
646                 } else {
647                         send_client_da_state(download_id, state, err);
648                 }
649
650                 break;
651
652         case DA_STATE_SUSPENDED:
653                 state_watcher_flag_OFF_for_download_id(state_watcher,
654                                 download_id);
655
656                 if (state_watcher->type == STATE_WATCHER_TYPE_SUSPEND) {
657                         if (!(state_watcher->state_watching_bitmap) &&
658                                 (state_watcher->is_progressing_to_all
659                                                         == DA_FALSE)) {
660                                 send_client_da_state(download_id,
661                                                 DA_STATE_SUSPENDED_ALL,
662                                                 DA_RESULT_OK);
663                         }
664                 }
665
666                 break;
667
668         case DA_STATE_RESUMED:
669                 state_watcher_flag_OFF_for_download_id(state_watcher,
670                                 download_id);
671
672                 if (state_watcher->type == STATE_WATCHER_TYPE_RESUME) {
673                         if (!(state_watcher->state_watching_bitmap) &&
674                                 (state_watcher->is_progressing_to_all
675                                                         == DA_FALSE)) {
676                                 send_client_da_state(download_id,
677                                                 DA_STATE_RESUMED_ALL,
678                                                 DA_RESULT_OK);
679                         }
680                 }
681
682                 break;
683
684         default:
685                 DA_LOG(Default, "blocked...");
686                 break;
687         }
688 }