Page Example

Service Adaptor Sample Overview

Mobile native

The Service Adaptor sample demonstrates how you can download files from a cloud storage using the Service Adaptor API.

The following figure illustrates the main views of the Service Adaptor application.

Figure: Service Adaptor main views

Service Adaptor main views Service Adaptor main views Service Adaptor main views

Service Adaptor main views Service Adaptor main views Service Adaptor main views

The application opens with the main screen, which lists the plugins available in the system. The sample application contains 10 dummy plugins, and if you install a cloud storage plugin (such as dropbox), it is added at the top of the list.

To use a plugin:

  1. On the main screen, select the plugin you want by clicking it.

    The list of files included in the cloud storage is displayed.

  2. To see the file details, click the file in the file list.
  3. To download a file, click Download on the file details screen.

    On the file download screen, click Start. When the download is complete, click OK.

Implementation

To use the Service Adaptor:

  1. Connect to the Service Adaptor and search for any installed plugins:
    static void 
    foreach_plugin()
    {
       Evas_Object *list = ad.main_list;
    
       int ret = 0;
       service_adaptor_h service_adaptor = NULL;
       ret = service_adaptor_create(&service_adaptor);
       if (SERVICE_ADAPTOR_ERROR_NONE != ret) 
       {
          log_error("Service Adaptor create failed");
    
          return;
       }
    
       ret = service_adaptor_foreach_plugin(service_adaptor, _plugin_iterator_cb, (void *)list);
       if (SERVICE_ADAPTOR_ERROR_NO_DATA == ret) 
       {
          log_info("There is no available plugin");
       } 
       else if (SERVICE_ADAPTOR_ERROR_NONE != ret) 
       {
          log_error("Plugin foreach failed");
          ret = service_adaptor_destroy(service_adaptor);
          service_adaptor = NULL;
       }
    
       g_service_adaptor = service_adaptor;
    
       int i = 0;
    
       while (NULL != fake_plugins[i]) 
       {
          elm_list_item_append(list, fake_plugins[i], NULL, NULL, _show_plugin_view, NULL);
          ++i;
       }
    }
    

    If there are any installed plugins, the _plugin_iterator_cb() callback is called and the plugin is added to the list:

    static bool 
    _plugin_iterator_cb(char *plugin_uri, int service_mask, void *user_data)
    {
       Evas_Object *list = (Evas_Object *)user_data;
       log_debug("plugin uri: %s, masked: <auth(%d), storage(%d)>", plugin_uri,
                 (SERVICE_PLUGIN_SERVICE_AUTH & service_mask), (SERVICE_PLUGIN_SERVICE_STORAGE & service_mask));
       if ((service_mask & SERVICE_PLUGIN_SERVICE_AUTH) && (service_mask & SERVICE_PLUGIN_SERVICE_STORAGE)) 
       {
          elm_list_item_append(list, strdup(plugin_uri), NULL, NULL, _show_plugin_view, strdup(plugin_uri));
       }
    
       return true;
    }
    
  2. Display the plugin file list.

    When a plugin is selected on the list, the cloud storage file list is shown on the next screen:

    static void 
    _show_plugin_view(void* data, Evas_Object* obj, void* event_info)
    {
       char *plugin_uri = (char *)data;
    
       Evas_Object *glist = elm_genlist_add(ad.win);
       ad.file_list = glist;
    
       if (plugin_uri) 
       {
          // Get the file list from the plugin
          if (NULL != ad.plugin)
             service_plugin_destroy(ad.plugin);
    
          ad.plugin = NULL;
          service_adaptor_create_plugin(g_service_adaptor, plugin_uri, &ad.plugin);
    
          // TODO Hide using config file or user input, because this is security information
          service_plugin_add_property(ad.plugin, SERVICE_PLUGIN_PROPERTY_APP_KEY, "enasvv4l8hdbmhn");
    
          // TODO Hide using config file or user input, because this is security information
          service_plugin_add_property(ad.plugin, SERVICE_PLUGIN_PROPERTY_APP_SECRET, "uqhl4pp8mo7hmgn");
          service_plugin_start(ad.plugin, (SERVICE_PLUGIN_SERVICE_AUTH | SERVICE_PLUGIN_SERVICE_STORAGE));
          service_storage_get_file_list(ad.plugin, "/", _service_storage_result_cb, NULL);
       } 
       else 
       {
          int i = 0;
          while (NULL != fake_files[i].filename) 
          {
             file_data_t *m_file = (file_data_t *)calloc(1, sizeof(file_data_t));
    
             m_file->filename = strdup(fake_files[i].filename);
             m_file->type = fake_files[i].type;
             m_file->size = fake_files[i].size;
             m_file->fake = 1;
             m_file->list_item = elm_genlist_item_append(glist, ad.list_class, (void *)&fake_files[i],
                                                         NULL, ELM_GENLIST_ITEM_NONE,
                                                         _show_file_details_view, (const void *)m_file);
             ++i;
          }
       }
    
       evas_object_size_hint_weight_set(glist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
       evas_object_show(glist);
    
       ad.current_plugin_navi_item = elm_naviframe_item_push(ad.navi, "File list", NULL, NULL, glist, NULL);
    
       elm_list_item_selected_set(elm_list_selected_item_get(ad.main_list), EINA_FALSE);
    }
    
    
  3. Display the file details.

    When a file is selected on the file list, its details (filename, file path and file size) are shown on the next screen:

    static bool 
    __file_iterator_cb(service_storage_file_h file, void *user_data)
    {
       // TODO Change logic for defend memory leak
    
       file_data_t *m_file = (file_data_t *)calloc(1, sizeof(file_data_t));
    
       char *name = NULL;
       unsigned long long size = 0;
       bool is_dir = false;
    
       service_storage_file_is_dir(file, &is_dir);
       service_storage_file_get_size(file, &size);
       service_storage_file_get_logical_path(file, &name);
    
       m_file->filename = strdup(name);
       m_file->type = is_dir ? "directory" : "file";
       m_file->size = (int)size;
       m_file->fake = 0;
       m_file->list_item = NULL;
    
       log_info("\nfilename: \"%s\"\ntype: \"%s\"\nsize: %i\nfake: %i\nlist_item: %p\n",
                m_file->filename ? m_file->filename : "", m_file->type,
                m_file->size, m_file->fake,
                m_file->list_item ? m_file->list_item : 0);
    
       ecore_event_add(ad.event_file_info_received, m_file, event_file_info_received_cleanup_cb, NULL);
    
       return true;
    }
    
  4. Download a file:
    static void 
    start_download(void *data)
    {
       if (NULL == data) 
       {
          dlog_print(DLOG_ERROR, LOG_TAG, "Null pointer: data");
    
          return;
       }
    
       file_data_t *file_data = data;
       service_storage_task_h download_task;
       int err = SERVICE_ADAPTOR_ERROR_NONE;
       dlog_print(DLOG_INFO, LOG_TAG, "Download file path: %s", file_data->filename);
    
       GString *dest_file = g_string_new("/tmp/");
       g_string_append(dest_file, file_data->filename);
    
       if (SERVICE_ADAPTOR_ERROR_NONE !=
           (err = service_storage_create_download_task(ad.plugin, file_data->filename, dest_file->str, &download_task))) 
       {
          dlog_print(DLOG_ERROR, LOG_TAG, "Download task creation failed.");
    
          switch (err) 
          {
             case SERVICE_ADAPTOR_ERROR_PERMISSION_DENIED:
                dlog_print(DLOG_ERROR, LOG_TAG, "Permission denied");
                break;
             case SERVICE_ADAPTOR_ERROR_INVALID_STATE:
                dlog_print(DLOG_ERROR, LOG_TAG, "The handle's state is invalid");
                break;
             case SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER:
                dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
                break;
             case SERVICE_ADAPTOR_ERROR_NO_DATA:
                dlog_print(DLOG_ERROR, LOG_TAG, "There is no files");
                break;
             case SERVICE_ADAPTOR_ERROR_TIMED_OUT:
                dlog_print(DLOG_ERROR, LOG_TAG, "Timed out");
                break;
             case SERVICE_ADAPTOR_ERROR_IPC_UNSTABLE:
                dlog_print(DLOG_ERROR, LOG_TAG, "IPC failed with Service Adaptor Daemon");
                break;
             case SERVICE_ADAPTOR_ERROR_NOT_SUPPORTED:
                dlog_print(DLOG_ERROR, LOG_TAG, "Not supported API in this plugin");
                break;
             case SERVICE_ADAPTOR_ERROR_PLUGIN_FAILED:
                dlog_print(DLOG_ERROR, LOG_TAG, "Failed in Plugin internal");
                break;
             case SERVICE_ADAPTOR_ERROR_UNKNOWN:
             default:
                dlog_print(DLOG_ERROR, LOG_TAG, "Unknown error");
                break;
          }
    
          char *msg = NULL;
          service_adaptor_get_last_error_message(&msg);
    
          if (msg) 
          {
             dlog_print(DLOG_ERROR, LOG_TAG, "error msg: %s", msg);
             free(msg);
          }
          g_string_free(dest_file, TRUE);
    
          return;
       }
    
       g_string_free(dest_file, TRUE);
    
       if (SERVICE_ADAPTOR_ERROR_NONE != 
           service_storage_set_task_progress_cb(download_task, download_task_progress_cb, NULL)) 
       {
          dlog_print(DLOG_ERROR, LOG_TAG, "Setting callback for download task failed.");
          service_storage_destroy_task(download_task);
    
          return;
       }
    
       if (SERVICE_ADAPTOR_ERROR_NONE != 
           service_storage_set_task_state_changed_cb(download_task, download_task_state_cb, NULL)) 
       {
          dlog_print(DLOG_ERROR, LOG_TAG, "Setting callback for download task failed.");
          service_storage_destroy_task(download_task);
    
          return;
       }
    
       if (SERVICE_ADAPTOR_ERROR_NONE != service_storage_start_task(download_task)) 
       {
          dlog_print(DLOG_ERROR, LOG_TAG, "Starting download task failed.");
          service_storage_destroy_task(download_task);
    
          return;
       }
    }