2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include "mf-widget.h"
23 #include "mf-fs-util.h"
24 #include "mf-fm-svc-wrapper.h"
26 void mf_otg_list_clean(void *data, mf_otg_list_e list_type)
29 struct appdata *ap = (struct appdata *)data;
35 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
36 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
37 free(((mf_otg_node *)node)->name);
38 ((mf_otg_node *)node)->name = NULL;
42 if (ap->mf_FileOperation.otg_dev_list) {
43 eina_list_free(ap->mf_FileOperation.otg_dev_list);
44 ap->mf_FileOperation.otg_dev_list = NULL;
47 case MF_OTG_LIST_REMOVED:
48 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_removed_list, l, node) {
49 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
50 free(((mf_otg_node *)node)->name);
51 ((mf_otg_node *)node)->name = NULL;
55 eina_list_free(ap->mf_FileOperation.otg_dev_removed_list);
56 ap->mf_FileOperation.otg_dev_removed_list = NULL;
63 int mf_otg_init(void *data)
66 struct appdata *ap = (struct appdata *)data;
68 if (ap->mf_FileOperation.otg_dev_list != NULL)
69 mf_otg_list_clean(ap, MF_OTG_LIST_DEV);
71 if(ap->mf_FileOperation.otg_dev_removed_list != NULL)
72 mf_otg_list_clean(ap, MF_OTG_LIST_REMOVED);
76 pDir = opendir(OTG_FOLDER);
79 return MYFILE_ERR_DIR_OPEN_FAIL;
82 while ((ent = readdir(pDir)) != NULL) {
83 mf_otg_node *pNode = NULL;
85 if (g_strcmp0(ent->d_name, ".") == 0 || g_strcmp0(ent->d_name, "..") == 0) {
89 if ((ent->d_type & DT_DIR) == 0 && (ent->d_type & DT_REG) == 0) {
93 pNode = (mf_otg_node *) malloc(sizeof(mf_otg_node));
98 memset(pNode, 0, sizeof(mf_otg_node));
100 pNode->name = g_strconcat(OTG_FOLDER, "/", ent->d_name, NULL);
102 pNode->flag_using = false;
103 pNode->flag_editstart = false;
105 ap->mf_FileOperation.otg_dev_list = eina_list_append(ap->mf_FileOperation.otg_dev_list, pNode);
108 return MYFILE_ERR_NONE;
111 bool mf_otg_is_in_list(void *data, const char *dev_name)
114 struct appdata *ap = (struct appdata *)data;
119 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
120 if (node && g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0)
126 int mf_otg_insert_node(void *data, const char *name)
129 struct appdata *ap = (struct appdata *)data;
131 if (mf_otg_is_in_list(ap, name)) {
132 return MYFILE_ERR_NONE;
134 mf_otg_node *pNode = NULL;
135 pNode = (mf_otg_node *)malloc(sizeof(mf_otg_node));
138 return MYFILE_ERR_ALLOCATE_MEMORY_FAIL;
140 memset(pNode, 0, sizeof(mf_otg_node));
143 pNode->name = g_strdup(name);
145 pNode->flag_using = false;
146 pNode->flag_editstart = false;
148 ap->mf_FileOperation.otg_dev_list = eina_list_append(ap->mf_FileOperation.otg_dev_list, pNode);
150 return MYFILE_ERR_NONE;
152 int mf_otg_delete_node(void *data, const char *name)
155 struct appdata *ap = (struct appdata *)data;
157 if (!mf_otg_is_in_list(ap, name)) {
159 return MYFILE_ERR_NONE;
163 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
164 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
165 if (g_strcmp0(((mf_otg_node *)node)->name, name) == 0){
166 free(((mf_otg_node *)node)->name);
167 ((mf_otg_node *)node)->name = NULL;
169 ap->mf_FileOperation.otg_dev_list = eina_list_remove_list(ap->mf_FileOperation.otg_dev_list, l);
174 return MYFILE_ERR_NONE;
182 int mf_otg_list_update(void *data, bool flag_inc_dec)
185 struct appdata *ap = (struct appdata *)data;
188 if (flag_inc_dec == TRUE) {
191 pDir = opendir(OTG_FOLDER);
194 return MYFILE_ERR_DIR_OPEN_FAIL;
197 while ((ent = readdir(pDir)) != NULL) {
198 if (g_strcmp0(ent->d_name, ".") == 0 || g_strcmp0(ent->d_name, "..") == 0) {
202 if ((ent->d_type & DT_DIR) == 0 && (ent->d_type & DT_REG) == 0) {
208 char *test_name = g_strconcat(OTG_FOLDER, "/", ent->d_name, NULL);
209 mf_debug("current test_name is %s", test_name);
210 if (test_name != NULL) {
212 /*we will check if the device is already in the list in mf_otg_insert_node*/
213 if (flag_inc_dec == true) {
214 mf_otg_insert_node(ap, test_name);
227 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
228 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
229 mf_debug("name is %s", ((mf_otg_node *)node)->name);
230 if (ecore_file_exists(((mf_otg_node *)node)->name) == false)
231 mf_otg_delete_node(ap, ((mf_otg_node *)node)->name);
235 return MYFILE_ERR_NONE;
238 bool mf_otg_is_empty(void *data)
240 return ecore_file_exists(OTG_FOLDER) && ecore_file_dir_is_empty(OTG_FOLDER);
243 char *mf_otg_get_node_in_use(void *data)
246 struct appdata *ap = (struct appdata *)data;
251 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
252 if ((mf_otg_node *)node != NULL) {
253 if (((mf_otg_node *)node)->flag_using == true) {
254 return ((mf_otg_node *)node)->name;
261 void mf_otg_set_node_using_flag(void *data, char *dev_name, bool status)
264 /*g_strcmp0 used, no need to check dev_name here*/
265 struct appdata *ap = (struct appdata *)data;
270 mf_debug("dev_name is %s", dev_name);
271 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
273 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
274 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
275 ((mf_otg_node *)node)->flag_using = status;
281 int mf_otg_get_node_using_flag(void *data, char *dev_name, bool *status)
285 /*g_strcmp0 used, no need to check dev_name here*/
286 struct appdata *ap = (struct appdata *)data;
291 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
292 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
293 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
294 *status = ((mf_otg_node *)node)->flag_using;
295 return MYFILE_ERR_NONE;
299 return MYFILE_ERR_GET_STAT_FAIL;
302 void mf_otg_set_node_editstart_flag(void *data, char *dev_name, bool status)
305 /*g_strcmp0 used, no need to check dev_name here*/
306 struct appdata *ap = (struct appdata *)data;
311 mf_debug("dev_name is %s", dev_name);
312 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
314 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
315 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
316 ((mf_otg_node *)node)->flag_editstart = status;
322 int mf_otg_get_node_editstart_flag(void *data, char *dev_name, bool *status)
326 /*g_strcmp0 used, no need to check dev_name here*/
327 struct appdata *ap = (struct appdata *)data;
332 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
334 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
335 if (g_strcmp0(((mf_otg_node *)node)->name, dev_name) == 0) {
336 *status = ((mf_otg_node *)node)->flag_editstart;
337 return MYFILE_ERR_NONE;
341 return MYFILE_ERR_GET_STAT_FAIL;
344 void mf_otg_generate_removed_list(void *data)
347 struct appdata *ap = (struct appdata *)data;
349 if (ap->mf_FileOperation.otg_dev_removed_list != NULL) {
351 mf_otg_list_clean(ap, MF_OTG_LIST_REMOVED);
356 mf_otg_node *pNode = NULL;
357 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
359 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
360 if (ecore_file_exists(((mf_otg_node *)node)->name) == false) {
361 pNode = (mf_otg_node *) malloc(sizeof(mf_otg_node));
366 memset(pNode, 0, sizeof(mf_otg_node));
368 pNode->name = g_strdup(((mf_otg_node *)node)->name);
370 pNode->flag_using = ((mf_otg_node *)node)->flag_using;
371 pNode->flag_editstart = ((mf_otg_node *)node)->flag_editstart;
373 ap->mf_FileOperation.otg_dev_removed_list = eina_list_append(ap->mf_FileOperation.otg_dev_removed_list, pNode);
380 void mf_otg_clear_removed_device(void *data)
383 struct appdata *ap = (struct appdata *)data;
385 const Eina_List *l = NULL;
388 EINA_LIST_FOREACH(ap->mf_FileOperation.otg_dev_list, l, node) {
389 if ((mf_otg_node *)node != NULL && ((mf_otg_node *)node)->name != NULL) {
390 if (ecore_file_exists(((mf_otg_node *)node)->name) == false) {
391 mf_otg_delete_node(ap, ((mf_otg_node *)node)->name);
397 /*do external operation according to the opt*/
398 static void __mf_otg_dev_removed_ex_operation(void *data, mf_otg_ex_opt_e opt)
401 struct appdata *ap = (struct appdata *)data;
403 /* try to remove all the popup and give an notice popup */
404 if (opt & MF_OTG_OPT_REQ_POPUP_DEL) { /*delete request popup in data transmit period*/
405 ap->mf_MainWindow.pMmcRemovedPopup = mf_popup_create_popup(ap, POPMODE_TEXT_NOT_DISABLED, NULL,
406 "OTG device removed...", NULL, NULL, NULL, NULL, NULL);
409 if (opt & MF_OTG_OPT_NOR_POPUP_DEL) { /*delete normal popup*/
410 if (ap->mf_MainWindow.pNormalPopup) {
411 evas_object_del(ap->mf_MainWindow.pNormalPopup);
412 ap->mf_MainWindow.pNormalPopup = NULL;
418 void mf_otg_dev_all_removed_update(void *data, mf_otg_ex_opt_e opt)
422 struct appdata *ap = (struct appdata *)data;
425 Evas_Object *entry = NULL;
426 myfileNaviBar *pNaviToShowStruct = NULL;
427 myfileNaviBar *pNaviOTG = NULL;
428 Evas_Object *pNaviBarStorageView = NULL;
430 /*otg tab destroyed, finalize otg*/
433 MF_STORAGE optStorage = MYFILE_OTG;
435 pNaviBarStorageView = ap->mf_MainWindow.pNaviBar;
436 pNaviOTG = mf_navi_bar_get_struct_by_label(ap, GET_STR(MF_LABEL_OTG));
438 char status = MF_OTG_STATUS_NONE;
440 if (pNaviOTG != NULL && pNaviOTG->naviFlagEditStart == TRUE)
441 status |= MF_OTG_STATUS_EDIT;
443 if (pNaviOTG != NULL && pNaviOTG->naviFlagInUse == TRUE)
444 status |= MF_OTG_STATUS_USING;
446 /*destroy otg navi bar*/
447 mf_debug("navi count is %d", eina_list_count(ap->mf_MainWindow.plistNaviBar));
448 mf_navi_bar_remove_list_item_by_label(ap, GET_STR(MF_LABEL_OTG));
451 if (status & MF_OTG_STATUS_EDIT) {
452 mf_navi_bar_recover_list(ap);
455 pNaviToShowStruct = mf_navi_bar_get_struct_by_label(ap, GET_SYS_STR(MF_LABEL_PHONE));
457 if (ap->mf_Status.view_type == mf_view_root) {
458 mf_callback_storage_remove_view_operation(ap, optStorage);
459 if (status & MF_OTG_STATUS_EDIT) {
460 ap->mf_Status.more = MORE_DEFAULT;
461 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
462 } else if (status & MF_OTG_STATUS_USING){
463 if ( ap->mf_Status.more == MORE_CREATE_FOLDER
464 && (ap->mf_Status.preMore == MORE_INTERNAL_COPY_MOVE || ap->mf_Status.preMore == MORE_INTERNAL_COPY || ap->mf_Status.preMore == MORE_INTERNAL_MOVE)) {
465 ap->mf_Status.more = ap->mf_Status.preMore;
466 } else if (ap->mf_Status.more != MORE_INTERNAL_COPY_MOVE && ap->mf_Status.preMore != MORE_INTERNAL_COPY && ap->mf_Status.preMore != MORE_INTERNAL_MOVE) {
467 ap->mf_Status.more = MORE_DEFAULT;
469 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
471 } else if (ap->mf_Status.view_type == mf_view_root_category) {
472 mf_callback_storage_remove_category_view_items(ap, optStorage);
474 if (status & MF_OTG_STATUS_EDIT) {
475 ap->mf_Status.more = MORE_DEFAULT;
476 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
477 } else if (status & MF_OTG_STATUS_USING){
478 if ( ap->mf_Status.more == MORE_CREATE_FOLDER
479 && (ap->mf_Status.preMore == MORE_INTERNAL_COPY_MOVE || ap->mf_Status.preMore == MORE_INTERNAL_COPY || ap->mf_Status.preMore == MORE_INTERNAL_MOVE)) {
480 ap->mf_Status.more = ap->mf_Status.preMore;
481 } else if (ap->mf_Status.more != MORE_INTERNAL_COPY_MOVE && ap->mf_Status.preMore != MORE_INTERNAL_COPY && ap->mf_Status.preMore != MORE_INTERNAL_MOVE) {
482 ap->mf_Status.more = MORE_DEFAULT;
484 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
489 /*delete external storage from tab bar*/
490 mf_debug("navi count is %d", eina_list_count(ap->mf_MainWindow.plistNaviBar));
491 /*check tab bar item to decide if delete tab bar*/
492 mf_debug("navi count is %d", eina_list_count(ap->mf_MainWindow.plistNaviBar));
494 /*clear some external detail after remove otg device*/
497 __mf_otg_dev_removed_ex_operation(ap, opt);
499 mf_otg_ex_opt_e updated_opt = opt;
500 if (updated_opt & MF_OTG_OPT_NOR_POPUP_DEL)
501 updated_opt ^= MF_OTG_OPT_NOR_POPUP_DEL;
503 if (updated_opt & MF_OTG_OPT_REQ_POPUP_DEL)
504 updated_opt ^= MF_OTG_OPT_REQ_POPUP_DEL;
506 __mf_otg_dev_removed_ex_operation(ap, updated_opt);
509 if (ap->mf_Status.more == MORE_RENAME) {
510 entry = ap->mf_MainWindow.pEntry;
512 elm_object_focus_set(entry, EINA_TRUE);
517 void mf_otg_dev_removed_update(void *data, mf_otg_ex_opt_e opt)
520 struct appdata *ap = (struct appdata *)data;
522 Evas_Object *pNaviBarStorageView = NULL;
523 myfileNaviBar *pNavi_s = NULL;
524 myfileNaviBar *pNaviToShowStruct = NULL;
526 pNaviBarStorageView = ap->mf_MainWindow.pNaviBar;
527 pNavi_s = mf_navi_bar_get_struct_by_label(ap, GET_STR(MF_LABEL_OTG));
528 if (pNavi_s == NULL) {
535 char status = MF_OTG_STATUS_NONE;
536 EINA_LIST_FOREACH (ap->mf_FileOperation.otg_dev_removed_list, l, node) {
538 bool using_status = FALSE;
539 error_code = mf_otg_get_node_using_flag(ap, ((mf_otg_node *)node)->name, &using_status);
540 if (error_code == 0 && using_status == TRUE)
541 status |= MF_OTG_STATUS_USING;
542 bool edit_status = FALSE;
543 error_code = mf_otg_get_node_editstart_flag(ap, ((mf_otg_node *)node)->name, &edit_status);
544 if (error_code == 0 && edit_status == TRUE)
545 status |= MF_OTG_STATUS_EDIT;
550 mf_debug("status is %d", status);
551 mf_debug("status & MF_OTG_STATUS_EDIT is %d", status & MF_OTG_STATUS_EDIT);
553 if (status & MF_OTG_STATUS_EDIT) {
555 /*pop edit related view for each navi bar*/
556 pNaviToShowStruct = mf_navi_bar_recover_list(ap);
558 /*pop to the root view of OTG*/
559 Elm_Object_Item *bottom_it = elm_naviframe_bottom_item_get(pNaviBarStorageView);
561 elm_naviframe_item_pop_to(bottom_it);
563 /* set the navi's currentpath to be root path*/
564 if (pNavi_s->pCurrentPath != NULL) {
565 free(pNavi_s->pCurrentPath);
567 pNavi_s->pCurrentPath = g_strdup(OTG_FOLDER);
568 ap->mf_MainWindow.pNaviLayout = ap->mf_Otg.rootpath_layout;
569 ap->mf_MainWindow.pNaviBox = ap->mf_Otg.rootpath_box;
571 if (pNavi_s->naviFlagInUse == TRUE){
572 if (ap->mf_Status.path != NULL) {
573 g_string_free(ap->mf_Status.path, TRUE);
575 ap->mf_Status.path = g_string_new(OTG_FOLDER);
577 }else if (status & MF_OTG_STATUS_USING) {
578 if (ap->mf_Status.more == MORE_SEARCH) {
579 if (ap->mf_FileOperation.sync_pipe != NULL) {
580 ecore_pipe_del(ap->mf_FileOperation.sync_pipe);
581 ap->mf_FileOperation.sync_pipe = NULL;
584 if (ap->mf_FileOperation.search_IME_hide_timer != NULL) {
585 ecore_timer_del(ap->mf_FileOperation.search_IME_hide_timer);
586 ap->mf_FileOperation.search_IME_hide_timer = NULL;
589 if (ap->mf_Status.search_handler > 0) {
590 mf_search_stop(ap->mf_Status.search_handler);
593 if (ap->mf_Status.search_handler > 0) {
594 mf_search_finalize(&ap->mf_Status.search_handler);
597 if (ap->mf_Status.more == MORE_INTERNAL_COPY_MOVE || ap->mf_Status.more == MORE_INTERNAL_COPY || ap->mf_Status.more == MORE_INTERNAL_MOVE
598 || (ap->mf_Status.more == MORE_CREATE_FOLDER && (ap->mf_Status.preMore == MORE_INTERNAL_COPY_MOVE || ap->mf_Status.more == MORE_INTERNAL_COPY || ap->mf_Status.more == MORE_INTERNAL_MOVE))) {
599 /*pop unused path select view*/
600 /*create and push root view of OTG*/
601 SAFE_FREE_GSTRING(ap->mf_Status.path);
602 ap->mf_Status.path = g_string_new(OTG_FOLDER);
604 SAFE_FREE_CHAR(pNavi_s->pCurrentPath);
605 pNavi_s->pCurrentPath = g_strdup(OTG_FOLDER);
607 if (ap->mf_Status.more == MORE_CREATE_FOLDER)
608 ap->mf_Status.more = ap->mf_Status.preMore;
610 mf_navi_bar_create_path_select_view_otg_root(ap);
611 mf_navi_bar_remove_previous_contents(ap, ap->mf_MainWindow.pNaviBar);
613 ap->mf_Status.more = MORE_DEFAULT;
615 /*pop to the root view of OTG*/
616 Elm_Object_Item *bottom_it = elm_naviframe_bottom_item_get(pNaviBarStorageView);
618 elm_naviframe_item_pop_to(bottom_it);
620 /* set the navi's currentpath to be root path*/
621 if (pNavi_s->pCurrentPath != NULL) {
622 free(pNavi_s->pCurrentPath);
624 pNavi_s->pCurrentPath = g_strdup(OTG_FOLDER);
625 ap->mf_MainWindow.pNaviLayout = ap->mf_Otg.rootpath_layout;
626 ap->mf_MainWindow.pNaviBox = ap->mf_Otg.rootpath_box;
627 ap->mf_MainWindow.pNaviItem = ap->mf_Otg.rootpath_navi_item;
629 if (pNavi_s->naviFlagInUse == TRUE){
630 if (ap->mf_Status.path != NULL) {
631 g_string_free(ap->mf_Status.path, TRUE);
633 ap->mf_Status.path = g_string_new(OTG_FOLDER);
638 if ((status & MF_OTG_STATUS_EDIT)
639 || (pNavi_s && pNavi_s->naviFlagInUse && ((status & MF_OTG_STATUS_USING) || mf_fm_svc_wrapper_is_root_path(ap->mf_Status.path->str) == MYFILE_OTG))) {
640 mf_debug("status is %d", status);
642 mf_debug("status & MF_OTG_STATUS_EDIT is %d", status & MF_OTG_STATUS_EDIT);
643 if (status & MF_OTG_STATUS_USING) {
645 pNaviToShowStruct = pNavi_s;
647 if ( ap->mf_Status.more == MORE_CREATE_FOLDER && (ap->mf_Status.preMore == MORE_INTERNAL_COPY_MOVE
648 || ap->mf_Status.more == MORE_INTERNAL_COPY || ap->mf_Status.more == MORE_INTERNAL_MOVE)) {
649 ap->mf_Status.more = ap->mf_Status.preMore;
650 } else if (ap->mf_Status.more != MORE_INTERNAL_COPY_MOVE && ap->mf_Status.more != MORE_INTERNAL_COPY && ap->mf_Status.more != MORE_INTERNAL_MOVE) {
651 ap->mf_Status.more = MORE_DEFAULT;
654 mf_navi_bar_refresh_recovered_view(ap, pNaviToShowStruct);
657 /*clear some external detail after remove otg device*/
660 __mf_otg_dev_removed_ex_operation(ap, opt);
662 mf_otg_ex_opt_e updated_opt = opt;
663 if (updated_opt & MF_OTG_OPT_NOR_POPUP_DEL)
664 updated_opt ^= MF_OTG_OPT_NOR_POPUP_DEL;
666 if (updated_opt & MF_OTG_OPT_REQ_POPUP_DEL)
667 updated_opt ^= MF_OTG_OPT_REQ_POPUP_DEL;
669 __mf_otg_dev_removed_ex_operation(ap, updated_opt);
671 mf_debug("dev list count is %d", eina_list_count(ap->mf_FileOperation.otg_dev_list));
672 mf_otg_list_update(ap, FALSE);
673 mf_debug("dev list count is %d", eina_list_count(ap->mf_FileOperation.otg_dev_list));
676 void mf_otg_finalize(void *data)
679 struct appdata *ap = (struct appdata *)data;
681 mf_otg_list_clean(ap, MF_OTG_LIST_DEV);
682 mf_otg_list_clean(ap, MF_OTG_LIST_REMOVED);