4 #include <Elementary.h>
16 #define HISTORY_ENTRY "history"
18 typedef struct _Call_Info_List {
22 typedef struct _History {
24 Eet_Data_Descriptor *edd;
25 Eet_Data_Descriptor *edd_list;
26 Call_Info_List *calls;
27 Elm_Genlist_Item_Class *itc;
28 Evas_Object *genlist_all, *genlist_missed;
31 typedef struct _Call_Info {
39 static OFono_Callback_List_Call_Node *callback_node_call_removed = NULL;
40 static OFono_Callback_List_Call_Node *callback_node_call_changed = NULL;
42 static Call_Info *_history_call_info_list_search(Eina_List *list,
48 EINA_LIST_FOREACH(list, l, call_info)
49 if (!strcmp(call_info->line_id, line_id))
55 static void _history_call_changed(void *data, OFono_Call *call)
57 History *history = data;
58 const char *line_id = ofono_call_line_id_get(call);
60 OFono_Call_State state = ofono_call_state_get(call);
63 _history_call_info_list_search(history->calls->list, line_id);
66 /* Otherwise I missed the call or the person didn't
69 if ((call_info->state == OFONO_CALL_STATE_INCOMING ||
70 call_info->state == OFONO_CALL_STATE_DIALING) &&
71 state != OFONO_CALL_STATE_DISCONNECTED)
72 call_info->state = state;
75 call_info = calloc(1, sizeof(Call_Info));
76 EINA_SAFETY_ON_NULL_RETURN(call_info);
78 call_info->state = state;
79 call_info->start_time = time(NULL);
80 call_info->line_id = eina_stringshare_add(line_id);
81 call_info->name = eina_stringshare_add(ofono_call_name_get(call));
82 history->calls->list =
83 eina_list_prepend(history->calls->list, call_info);
86 static void _history_call_log_save(History *history)
88 if (!(eet_data_write(history->log,
89 history->edd_list, HISTORY_ENTRY,
90 history->calls, EET_COMPRESSION_DEFAULT)))
91 ERR("Could in the history log file");
94 static void _history_call_removed(void *data, OFono_Call *call)
96 History *history = data;
97 const char *line_id = ofono_call_line_id_get(call);
103 _history_call_info_list_search(history->calls->list, line_id);
104 EINA_SAFETY_ON_NULL_RETURN(call_info);
105 start = call_info->start_time;
108 if (call_info->state == OFONO_CALL_STATE_INCOMING) {
109 INF("Missed call - Id: %s - time: %s", line_id, tm);
110 elm_genlist_item_append(history->genlist_missed, history->itc,
111 call_info, NULL, ELM_GENLIST_ITEM_NONE,
113 } else if (call_info->state == OFONO_CALL_STATE_DIALING)
114 INF("Call not answered - Id: %s - time: %s", line_id, tm);
116 INF("A call has ended - Id: %s - time: %s", line_id, tm);
118 call_info->end_time = time(NULL);
119 _history_call_log_save(history);
120 elm_genlist_item_append(history->genlist_all, history->itc, call_info,
121 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
124 static void _call_info_free(Call_Info *call_info)
126 eina_stringshare_del(call_info->line_id);
127 eina_stringshare_del(call_info->name);
131 static void _on_del(void *data, Evas *e __UNUSED__,
132 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
134 History *history = data;
135 Call_Info *call_info;
136 ofono_call_removed_cb_del(callback_node_call_removed);
137 ofono_call_changed_cb_del(callback_node_call_changed);
138 eet_close(history->log);
139 eet_data_descriptor_free(history->edd);
140 eet_data_descriptor_free(history->edd_list);
141 EINA_LIST_FREE(history->calls->list, call_info)
142 _call_info_free(call_info);
143 free(history->calls);
144 elm_genlist_item_class_free(history->itc);
149 static void _history_call_info_descriptor_init(Eet_Data_Descriptor **edd,
150 Eet_Data_Descriptor **edd_list)
152 Eet_Data_Descriptor_Class eddc;
154 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Call_Info);
155 *edd = eet_data_descriptor_stream_new(&eddc);
157 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Call_Info_List);
158 *edd_list = eet_data_descriptor_stream_new(&eddc);
160 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
161 "state", state, EET_T_INT);
162 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
163 "start_time", start_time, EET_T_LONG_LONG);
164 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
165 "end_time", end_time, EET_T_LONG_LONG);
166 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
167 "line_id", line_id, EET_T_STRING);
168 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
169 "name", name, EET_T_STRING);
171 EET_DATA_DESCRIPTOR_ADD_LIST(*edd_list, Call_Info_List, "list", list,
175 static void _history_call_log_read(History *history)
177 Call_Info *call_info;
180 history->calls = eet_data_read(history->log, history->edd_list,
183 if (!history->calls) {
184 history->calls = calloc(1, sizeof(Call_Info_List));
188 EINA_LIST_FOREACH(history->calls->list, l, call_info) {
191 elm_genlist_item_append(history->genlist_all, history->itc,
192 call_info, NULL, ELM_GENLIST_ITEM_NONE,
194 if (call_info->state == OFONO_CALL_STATE_INCOMING)
195 elm_genlist_item_append(history->genlist_missed,
196 history->itc, call_info, NULL,
197 ELM_GENLIST_ITEM_NONE,
202 static char *_item_label_get(void *data, Evas_Object *obj __UNUSED__,
205 Call_Info *call_info = data;
207 if (strncmp(part, "text.call", strlen("text.call")))
210 part += strlen("text.call.");
212 if (!strcmp(part, "name")) {
214 name = call_info->name;
215 if (!call_info->name || call_info->name[0] == '\0')
216 name = call_info->line_id;
220 if (!strcmp(part, "time"))
221 return date_format(call_info->end_time);
223 /* TODO: Fetch phone type from contacts information*/
224 if (!strcmp(part, "type"))
225 return strdup("TODO:TELEPHONE TYPE");
227 ERR("Unexpected text part: %s", part);
232 static Eina_Bool _item_state_get(void *data, Evas_Object *obj __UNUSED__,
235 Call_Info *call_info = data;
237 if (!strcmp(part, "missed")) {
238 if (call_info->state == OFONO_CALL_STATE_INCOMING ||
239 call_info->state == OFONO_CALL_STATE_DIALING)
243 } else if (!strcmp(part, "completed")) {
244 if (call_info->state == OFONO_CALL_STATE_INCOMING ||
245 call_info->state == OFONO_CALL_STATE_DIALING)
249 } else if (!strcmp(part, "outgoing"))
251 else if (!strcmp(part, "incoming"))
254 ERR("Unexpected state part: %s", part);
258 static void _on_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
259 const char *emission, const char *source __UNUSED__)
261 EINA_SAFETY_ON_NULL_RETURN(emission);
262 emission += strlen("clicked,");
264 if (!strcmp(emission, "all"))
265 elm_object_signal_emit(obj, "show,all", "gui");
267 elm_object_signal_emit(obj, "show,missed", "gui");
270 static void _on_more_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
271 const char *emission __UNUSED__,
272 const char *source __UNUSED__)
277 static Evas_Object *_item_content_get(void *data __UNUSED__, Evas_Object *obj,
278 const char *part __UNUSED__)
282 btn = gui_layout_add(obj, "history/img");
283 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
284 elm_object_signal_callback_add(btn, "clicked,more", "gui",
285 _on_more_clicked, NULL);
290 Evas_Object *history_add(Evas_Object *parent)
293 const char *config_path;
295 Elm_Genlist_Item_Class *itc;
296 Evas_Object *obj, *genlist_all, *genlist_missed;
299 history = calloc(1, sizeof(History));
300 EINA_SAFETY_ON_NULL_RETURN_VAL(history, NULL);
302 obj = gui_layout_add(parent, "history_bg");
303 EINA_SAFETY_ON_NULL_GOTO(obj, err_layout);
305 genlist_all = elm_genlist_add(obj);
306 EINA_SAFETY_ON_NULL_GOTO(genlist_all, err_object_new);
308 genlist_missed = elm_genlist_add(obj);
309 EINA_SAFETY_ON_NULL_GOTO(genlist_missed, err_object_new);
311 itc = elm_genlist_item_class_new();
312 EINA_SAFETY_ON_NULL_GOTO(itc, err_object_new);
313 itc->item_style = "history";
314 itc->func.text_get = _item_label_get;
315 itc->func.content_get = _item_content_get;
316 itc->func.state_get = _item_state_get;
317 itc->func.del = NULL;
318 history->genlist_all = genlist_all;
319 history->genlist_missed = genlist_missed;
322 elm_object_part_content_set(obj, "elm.swallow.all", genlist_all);
323 elm_object_part_content_set(obj, "elm.swallow.missed", genlist_missed);
324 elm_object_signal_emit(obj, "show,all", "gui");
325 elm_object_signal_callback_add(obj, "clicked,*", "gui",
328 config_path = efreet_config_home_get();
329 snprintf(path, sizeof(path), "%s/%s", config_path, PACKAGE_NAME);
330 ecore_file_mkpath(path);
331 snprintf(path, sizeof(path), "%s/%s/history.eet", config_path,
333 history->log = eet_open(path, EET_FILE_MODE_READ_WRITE);
334 EINA_SAFETY_ON_NULL_GOTO(history->log, err_item_class);
336 _history_call_info_descriptor_init(&history->edd, &history->edd_list);
337 _history_call_log_read(history);
338 EINA_SAFETY_ON_NULL_GOTO(history->calls, err_log_read);
339 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _on_del,
341 callback_node_call_changed =
342 ofono_call_changed_cb_add(_history_call_changed, history);
343 callback_node_call_removed =
344 ofono_call_removed_cb_add(_history_call_removed, history);
348 eet_close(history->log);
350 elm_genlist_item_class_free(itc);