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, const char *part) {
196 Call_Info *call_info = data;
198 const char *name, *call_state;
201 name = call_info->name;
203 if (!call_info->name || call_info->name[0] == '\0')
204 name = call_info->line_id;
206 if (call_info->state == OFONO_CALL_STATE_INCOMING)
207 call_state = "Missed";
208 else if (call_info->state == OFONO_CALL_STATE_DIALING)
209 call_state = "Not Awnsered";
211 call_state = "Completed";
213 t = date_format(call_info->end_time);
215 if (asprintf(&buf, "%s-%s-%s", name, call_state, t) < 0)
222 static void _btn_naviframe_next_click(void *data, Evas_Object *obj,
224 History *history = data;
225 elm_naviframe_item_promote(history->missed);
228 static void _btn_naviframe_prev_click(void *data, Evas_Object *obj,
230 History *history = data;
231 elm_naviframe_item_promote(history->all);
234 Evas_Object *history_add(Evas_Object *parent) {
236 const char *config_path;
238 Elm_Genlist_Item_Class *itc;
239 Evas_Object *obj, *genlist_all, *genlist_missed, *btn;
242 history = calloc(1, sizeof(History));
243 EINA_SAFETY_ON_NULL_RETURN_VAL(history, NULL);
245 obj = elm_naviframe_add(parent);
246 EINA_SAFETY_ON_NULL_GOTO(obj, err_naviframe);
247 elm_naviframe_prev_btn_auto_pushed_set(obj, EINA_FALSE);
249 genlist_all = elm_genlist_add(obj);
250 EINA_SAFETY_ON_NULL_GOTO(genlist_all, err_object_new);
252 genlist_missed = elm_genlist_add(obj);
253 EINA_SAFETY_ON_NULL_GOTO(genlist_missed, err_object_new);
255 itc = elm_genlist_item_class_new();
256 EINA_SAFETY_ON_NULL_GOTO(itc, err_object_new);
257 itc->item_style = "default";
258 itc->func.text_get = _item_label_get;
259 itc->func.content_get = NULL;
260 itc->func.state_get = NULL;
261 itc->func.del = NULL;
262 history->genlist_all = genlist_all;
263 history->genlist_missed = genlist_missed;
265 btn = elm_button_add(obj);
266 EINA_SAFETY_ON_NULL_GOTO(btn, err_item_class);
267 elm_object_text_set(btn, "Missed");
268 evas_object_smart_callback_add(btn, "clicked",
269 _btn_naviframe_next_click, history);
271 Elm_Object_Item *all =
272 elm_naviframe_item_push(obj, "All", NULL, btn, genlist_all,
274 EINA_SAFETY_ON_NULL_GOTO(all, err_item_class);
276 btn = elm_button_add(obj);
277 EINA_SAFETY_ON_NULL_GOTO(btn, err_item_class);
278 elm_object_text_set(btn, "All");
279 evas_object_smart_callback_add(btn, "clicked",
280 _btn_naviframe_prev_click, history);
282 Elm_Object_Item *missed =
283 elm_naviframe_item_push(obj, "Missed", btn, NULL,
284 genlist_missed, NULL);
285 EINA_SAFETY_ON_NULL_GOTO(missed, err_item_class);
286 elm_naviframe_item_promote(all);
289 history->missed = missed;
292 config_path = efreet_config_home_get();
293 snprintf(path, sizeof(path), "%s%s", config_path, PACKAGE_NAME);
294 ecore_file_mkpath(path);
295 snprintf(path, sizeof(path), "%s%s/history.eet", config_path,
297 history->log = eet_open(path, EET_FILE_MODE_READ_WRITE);
298 EINA_SAFETY_ON_NULL_RETURN_VAL(history->log, NULL);
300 _history_call_info_descriptor_init(&history->edd, &history->edd_list);
301 _history_call_log_read(history);
302 EINA_SAFETY_ON_NULL_RETURN_VAL(history->calls, NULL);
303 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _on_del,
305 callback_node_call_changed =
306 ofono_call_changed_cb_add(_history_call_changed, history);
307 callback_node_call_removed =
308 ofono_call_removed_cb_add(_history_call_removed, history);
312 elm_genlist_item_class_free(itc);