4 #include <Elementary.h>
15 #define HISTORY_ENTRY "history"
17 typedef struct _Call_Info_List {
21 typedef struct _History {
23 Eet_Data_Descriptor *edd;
24 Eet_Data_Descriptor *edd_list;
25 Call_Info_List *calls;
26 Elm_Genlist_Item_Class *itc;
27 Evas_Object *genlist_all, *genlist_missed;
28 Elm_Object_Item *all, *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,
43 const char *line_id) {
47 EINA_LIST_FOREACH (list, l, call_info)
48 if (!strcmp(call_info->line_id, line_id))
54 static void _history_call_changed(void *data, OFono_Call *call) {
55 History *history = data;
56 const char *line_id = ofono_call_line_id_get(call);
58 OFono_Call_State state = ofono_call_state_get(call);
61 _history_call_info_list_search(history->calls->list, line_id);
64 /* Otherwise I missed the call or the person didn't
67 if ((call_info->state == OFONO_CALL_STATE_INCOMING ||
68 call_info->state == OFONO_CALL_STATE_DIALING) &&
69 state != OFONO_CALL_STATE_DISCONNECTED)
70 call_info->state = state;
73 call_info = calloc(1, sizeof(Call_Info));
74 EINA_SAFETY_ON_NULL_RETURN(call_info);
76 call_info->state = state;
77 call_info->start_time = time(NULL);
78 call_info->line_id = eina_stringshare_add(line_id);
79 call_info->name = eina_stringshare_add(ofono_call_name_get(call));
80 history->calls->list =
81 eina_list_prepend(history->calls->list, call_info);
84 static void _history_call_log_save(History *history) {
85 if (!(eet_data_write(history->log,
86 history->edd_list, HISTORY_ENTRY,
87 history->calls, EET_COMPRESSION_DEFAULT)))
88 ERR("Could in the history log file");
91 static void _history_call_removed(void *data, OFono_Call *call) {
92 History *history = data;
93 const char *line_id = ofono_call_line_id_get(call);
99 _history_call_info_list_search(history->calls->list, line_id);
100 EINA_SAFETY_ON_NULL_RETURN(call_info);
101 start = call_info->start_time;
104 if (call_info->state == OFONO_CALL_STATE_INCOMING) {
105 INF("Missed call - Id: %s - time: %s", line_id, tm);
106 elm_genlist_item_append(history->genlist_missed, history->itc,
107 call_info, NULL, ELM_GENLIST_ITEM_NONE,
109 } else if (call_info->state == OFONO_CALL_STATE_DIALING)
110 INF("Call not answered - Id: %s - time: %s", line_id, tm);
112 INF("A call has ended - Id: %s - time: %s", line_id, tm);
114 call_info->end_time = time(NULL);
115 _history_call_log_save(history);
116 elm_genlist_item_append(history->genlist_all, history->itc, call_info,
117 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
120 static void _call_info_free(Call_Info *call_info) {
121 eina_stringshare_del(call_info->line_id);
122 eina_stringshare_del(call_info->name);
126 static void _on_del(void *data, Evas *e __UNUSED__,
127 Evas_Object *obj __UNUSED__, void *event __UNUSED__) {
128 History *history = data;
129 Call_Info *call_info;
130 ofono_call_removed_cb_del(callback_node_call_removed);
131 ofono_call_changed_cb_del(callback_node_call_changed);
132 eet_close(history->log);
133 eet_data_descriptor_free(history->edd);
134 eet_data_descriptor_free(history->edd_list);
135 EINA_LIST_FREE(history->calls->list, call_info) {
136 _call_info_free(call_info);
138 free(history->calls);
139 elm_genlist_item_class_free(history->itc);
144 static void _history_call_info_descriptor_init(Eet_Data_Descriptor **edd,
145 Eet_Data_Descriptor **edd_list) {
146 Eet_Data_Descriptor_Class eddc;
148 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Call_Info);
149 *edd = eet_data_descriptor_stream_new(&eddc);
151 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Call_Info_List);
152 *edd_list = eet_data_descriptor_stream_new(&eddc);
154 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
155 "state", state, EET_T_INT);
156 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
157 "start_time", start_time, EET_T_LONG_LONG);
158 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
159 "end_time", end_time, EET_T_LONG_LONG);
160 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
161 "line_id", line_id, EET_T_STRING);
162 EET_DATA_DESCRIPTOR_ADD_BASIC(*edd, Call_Info,
163 "name", name, EET_T_STRING);
165 EET_DATA_DESCRIPTOR_ADD_LIST(*edd_list, Call_Info_List, "list", list,
169 static void _history_call_log_read(History *history) {
170 Call_Info *call_info;
172 history->calls = eet_data_read(history->log, history->edd_list,
175 EINA_SAFETY_ON_NULL_GOTO(history->calls, calls_list_alloc);
177 EINA_LIST_FOREACH (history->calls->list, l, call_info) {
180 elm_genlist_item_append(history->genlist_all, history->itc,
181 call_info, NULL, ELM_GENLIST_ITEM_NONE,
183 if (call_info->state == OFONO_CALL_STATE_INCOMING)
184 elm_genlist_item_append(history->genlist_missed,
185 history->itc, call_info, NULL,
186 ELM_GENLIST_ITEM_NONE,
192 history->calls = calloc(1, sizeof(Call_Info_List));
195 static char *_item_label_get(void *data, Evas_Object *obj __UNUSED__,
196 const char *part __UNUSED__) {
197 Call_Info *call_info = data;
199 const char *name, *call_state;
202 name = call_info->name;
204 if (!call_info->name || call_info->name[0] == '\0')
205 name = call_info->line_id;
207 if (call_info->state == OFONO_CALL_STATE_INCOMING)
208 call_state = "Missed";
209 else if (call_info->state == OFONO_CALL_STATE_DIALING)
210 call_state = "Not Awnsered";
212 call_state = "Completed";
214 t = date_format(call_info->end_time);
216 if (asprintf(&buf, "%s-%s-%s", name, call_state, t) < 0)
223 static void _btn_naviframe_next_click(void *data, Evas_Object *obj __UNUSED__,
224 void *event_inf __UNUSED__) {
225 History *history = data;
226 elm_naviframe_item_promote(history->missed);
229 static void _btn_naviframe_prev_click(void *data, Evas_Object *obj __UNUSED__,
230 void *event_inf __UNUSED__) {
231 History *history = data;
232 elm_naviframe_item_promote(history->all);
235 Evas_Object *history_add(Evas_Object *parent) {
237 const char *config_path;
239 Elm_Genlist_Item_Class *itc;
240 Evas_Object *obj, *genlist_all, *genlist_missed, *btn;
243 history = calloc(1, sizeof(History));
244 EINA_SAFETY_ON_NULL_RETURN_VAL(history, NULL);
246 obj = elm_naviframe_add(parent);
247 EINA_SAFETY_ON_NULL_GOTO(obj, err_naviframe);
248 elm_naviframe_prev_btn_auto_pushed_set(obj, EINA_FALSE);
250 genlist_all = elm_genlist_add(obj);
251 EINA_SAFETY_ON_NULL_GOTO(genlist_all, err_object_new);
253 genlist_missed = elm_genlist_add(obj);
254 EINA_SAFETY_ON_NULL_GOTO(genlist_missed, err_object_new);
256 itc = elm_genlist_item_class_new();
257 EINA_SAFETY_ON_NULL_GOTO(itc, err_object_new);
258 itc->item_style = "default";
259 itc->func.text_get = _item_label_get;
260 itc->func.content_get = NULL;
261 itc->func.state_get = NULL;
262 itc->func.del = NULL;
263 history->genlist_all = genlist_all;
264 history->genlist_missed = genlist_missed;
266 btn = elm_button_add(obj);
267 EINA_SAFETY_ON_NULL_GOTO(btn, err_item_class);
268 elm_object_text_set(btn, "Missed");
269 evas_object_smart_callback_add(btn, "clicked",
270 _btn_naviframe_next_click, history);
272 Elm_Object_Item *all =
273 elm_naviframe_item_push(obj, "All", NULL, btn, genlist_all,
275 EINA_SAFETY_ON_NULL_GOTO(all, err_item_class);
277 btn = elm_button_add(obj);
278 EINA_SAFETY_ON_NULL_GOTO(btn, err_item_class);
279 elm_object_text_set(btn, "All");
280 evas_object_smart_callback_add(btn, "clicked",
281 _btn_naviframe_prev_click, history);
283 Elm_Object_Item *missed =
284 elm_naviframe_item_push(obj, "Missed", btn, NULL,
285 genlist_missed, NULL);
286 EINA_SAFETY_ON_NULL_GOTO(missed, err_item_class);
287 elm_naviframe_item_promote(all);
290 history->missed = missed;
293 config_path = efreet_config_home_get();
294 snprintf(path, sizeof(path), "%s%s", config_path, PACKAGE_NAME);
295 ecore_file_mkpath(path);
296 snprintf(path, sizeof(path), "%s%s/history.eet", config_path,
298 history->log = eet_open(path, EET_FILE_MODE_READ_WRITE);
299 EINA_SAFETY_ON_NULL_RETURN_VAL(history->log, NULL);
301 _history_call_info_descriptor_init(&history->edd, &history->edd_list);
302 _history_call_log_read(history);
303 EINA_SAFETY_ON_NULL_RETURN_VAL(history->calls, NULL);
304 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _on_del,
306 callback_node_call_changed =
307 ofono_call_changed_cb_add(_history_call_changed, history);
308 callback_node_call_removed =
309 ofono_call_removed_cb_add(_history_call_removed, history);
313 elm_genlist_item_class_free(itc);