Tizen Content API - Part 1
authorSakari Poussa <sakari.poussa@intel.com>
Tue, 25 Feb 2014 09:31:41 +0000 (11:31 +0200)
committerSakari Poussa <sakari.poussa@intel.com>
Tue, 25 Mar 2014 06:19:54 +0000 (08:19 +0200)
First part of the Tizen Device API called Content API

https://developer.tizen.org/dev-guide/2.2.1/org.tizen.web.device.apireference/tizen/content.html

This part implements only the following methods in basic mode (only success and error callback parameters supported)

  - getDirectories
  - find

Also, sample test page is included for the above methods.

content/content.gyp [new file with mode: 0644]
content/content_api.js [new file with mode: 0644]
content/content_extension.cc [new file with mode: 0644]
content/content_extension.h [new file with mode: 0644]
content/content_instance.cc [new file with mode: 0644]
content/content_instance.h [new file with mode: 0644]
examples/content.html [new file with mode: 0644]
examples/index.html
packaging/tizen-extensions-crosswalk.spec
tizen-wrt.gyp

diff --git a/content/content.gyp b/content/content.gyp
new file mode 100644 (file)
index 0000000..d51592a
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  'includes':[
+    '../common/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'tizen_content',
+      'type': 'loadable_module',
+      'variables': {
+        'packages': [
+          'capi-content-media-content'
+        ],
+      },
+      'sources': [
+        'content_api.js',
+        'content_extension.h',
+        'content_extension.cc',
+        'content_instance.h',
+        'content_instance.cc',
+        '../common/extension.h',
+        '../common/extension.cc',
+      ],
+      'includes': [
+        '../common/pkg-config.gypi',
+      ],
+    }
+  ]
+}
diff --git a/content/content_api.js b/content/content_api.js
new file mode 100644 (file)
index 0000000..ab1fcf0
--- /dev/null
@@ -0,0 +1,136 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var _callbacks = {};
+var _nextReplyId = 0;
+
+function getNextReplyId() {
+  return _nextReplyId++;
+};
+
+function postMessage(msg, callback) {
+  var replyId = getNextReplyId();
+  _callbacks[replyId] = callback;
+  msg.replyId = replyId;
+  extension.postMessage(JSON.stringify(msg));
+};
+
+function sendSyncMessage(msg) {
+  return extension.internal.sendSyncMessage(JSON.stringify(msg));
+};
+
+extension.setMessageListener(function(msg) {
+  var m = JSON.parse(msg);
+  var replyId = m.replyId;
+  var callback = _callbacks[replyId];
+  
+  if (typeof(callback) === 'function') {
+    callback(m);
+    delete m.replyId;
+    delete _callbacks[replyId];
+  } else {
+    console.log('Invalid replyId from Tizen Content API: ' + replyId);
+  }
+});
+
+function Folder(uri, id, type, title) {
+  Object.defineProperties(this, {
+    'directoryURI': { writable: false, value: uri, enumerable: true },
+    'id': { writable: false, value: id, enumerable: true },
+    'storageType': { writable: false, value: type, enumerable: true },
+    'title': { writable: false, value: title, enumerable: true }
+  });
+}
+
+function Content(id, name, type, mimeType, title, contentURI, thumnailURIs, releaseDate, modifiedDate, size, description, rating) {
+  Object.defineProperties(this, {
+    'id': { writable: false, value: id, enumerable: true },
+    'name': { writable: false, value: name, enumerable: true },
+    'type': { writable: false, value: type, enumerable: true },
+    'mimeType': { writable: false, value: mimeType, enumerable: true },
+    'title': { writable: false, value: title, enumerable: true },
+    'contentURI': { writable: false, value: contentURI, enumerable: true },
+    'thumnailURIs': { writable: false, value: thumnailURIs, enumerable: true },
+    'releaseDate': { writable: false, value: releaseDate, enumerable: true },
+    'modifiedDate': { writable: false, value: modifiedDate, enumerable: true },
+    'size': { writable: false, value: size, enumerable: true },
+    'description': { writable: false, value: description, enumerable: true },
+    'rating': { writable: false, value: rating, enumerable: true },
+  });
+}
+
+function ContentManager() {
+}
+
+ContentManager.prototype.update = function(content) {
+}
+
+ContentManager.prototype.updateBatch = function(content, onsuccess, onerror) {
+}
+
+ContentManager.prototype.getDirectories = function(onsuccess, onerror) {
+  postMessage({
+      cmd: 'ContentManager.getDirectories',
+    }, function(result) {
+      if (result.isError) {
+        if (onerror)
+          onerror(new tizen.WebAPIError(result.errorCode));
+      } else if (onsuccess) {
+        var folders = [];
+
+        for (var i = 0; i < result.value.length; i++) {
+          var folder = result.value[i];
+          var jsonFolder = new Folder(folder.directoryURI, folder.id, folder.storageType, folder.title);
+          folders.push(jsonFolder)
+        }
+        onsuccess(folders);
+      }
+  });
+}
+
+ContentManager.prototype.find = function(onsuccess, onerror, directoryId, filter, sortMode, count, offset) {
+  postMessage({
+      cmd: 'ContentManager.find',
+      directoryId: directoryId,
+      filter: filter,
+      sortMode: sortMode,
+      count: count,
+      offset: offset,
+    }, function(result) {
+      if (result.isError) {
+        if (onerror)
+          onerror(new tizen.WebAPIError(result.errorCode));
+      } else if (onsuccess) {
+        var contents = [];
+        for (var i = 0; i < result.value.length; i++) {
+          var content = result.value[i];
+          var jsonContent = new Content(content.id, 
+                  content.name, 
+                  content.type, 
+                  content.mimeType, 
+                  content.title, 
+                  content.contentURI, 
+                  content.thumnailURIs, 
+                  content.releaseDate, 
+                  content.modifiedDate, 
+                  content.size, 
+                  content.description, 
+                  content.rating);
+          contents.push(jsonContent);
+        }     
+        onsuccess(contents);
+      }
+  });
+}
+
+ContentManager.prototype.scanFile = function(contentURI, onsuccess, onerror) {
+}
+
+ContentManager.prototype.setChangeListener = function(onchange) {
+}
+
+ContentManager.prototype.unsetChangeLIstener = function() {
+}
+
+exports = new ContentManager();
diff --git a/content/content_extension.cc b/content/content_extension.cc
new file mode 100644 (file)
index 0000000..c4366a1
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iostream>
+
+#include "content/content_extension.h"
+#include "content/content_instance.h"
+
+common::Extension* CreateExtension() {
+  return new ContentExtension;
+}
+
+// JS source code for the API
+extern const char kSource_content_api[];
+
+ContentExtension::ContentExtension() {
+  SetExtensionName("tizen.content");
+  SetJavaScriptAPI(kSource_content_api);
+}
+
+ContentExtension::~ContentExtension() {}
+
+common::Instance* ContentExtension::CreateInstance() {
+  return new ContentInstance;
+}
diff --git a/content/content_extension.h b/content/content_extension.h
new file mode 100644 (file)
index 0000000..fb80a4e
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_CONTENT_EXTENSION_H_
+#define CONTENT_CONTENT_EXTENSION_H_
+
+#include "common/extension.h"
+
+class ContentExtension : public common::Extension {
+ public:
+  ContentExtension();
+  virtual ~ContentExtension();
+
+ private:
+  virtual common::Instance* CreateInstance();
+};
+
+#endif  // CONTENT_CONTENT_EXTENSION_H_
diff --git a/content/content_instance.cc b/content/content_instance.cc
new file mode 100644 (file)
index 0000000..740cc43
--- /dev/null
@@ -0,0 +1,347 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/content_instance.h"
+
+#include <media_content.h>
+#include <assert.h>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include "common/picojson.h"
+
+namespace {
+
+std::string pathToURI(const std::string path) {
+  static std::string scheme("file://");
+
+  return scheme + path;
+}
+}
+
+unsigned ContentInstance::m_instanceCount = 0;
+
+ContentInstance::ContentInstance() {
+  if (media_content_connect() != MEDIA_CONTENT_ERROR_NONE) {
+    std::cerr << "media_content_connect: error\n";
+    return;
+  }
+  m_instanceCount++;
+}
+
+ContentInstance::~ContentInstance() {
+  assert(m_instanceCount > 0);
+  if (--m_instanceCount > 0)
+    return;
+  if (media_content_disconnect() != MEDIA_CONTENT_ERROR_NONE)
+    std::cerr << "media_discontent_connect: error\n";
+}
+
+void ContentInstance::HandleMessage(const char* message) {
+  picojson::value v;
+  picojson::value::object o;
+
+  std::string err;
+  picojson::parse(v, message, message + strlen(message), &err);
+  if (!err.empty()) {
+    std::cerr << "Ignoring message.\n";
+    return;
+  }
+  std::string cmd = v.get("cmd").to_str();
+  if (cmd == "ContentManager.getDirectories") {
+    HandleGetDirectoriesRequest(v);
+  } else if (cmd == "ContentManager.find") {
+    HandleFindRequest(v);
+  } else {
+    std::cerr << "Message " + cmd + " is not supported.\n";
+  }
+}
+
+void ContentInstance::PostAsyncErrorReply(const picojson::value& msg,
+    WebApiAPIErrors error_code) {
+  picojson::value::object o;
+  o["isError"] = picojson::value(true);
+  o["errorCode"] = picojson::value(static_cast<double>(error_code));
+  o["replyId"] = picojson::value(msg.get("replyId").get<double>());
+
+  picojson::value v(o);
+  PostMessage(v.serialize().c_str());
+}
+
+void ContentInstance::PostAsyncSuccessReply(const picojson::value& msg,
+    picojson::value::object& reply) {
+  reply["isError"] = picojson::value(false);
+  reply["replyId"] = picojson::value(msg.get("replyId").get<double>());
+
+  picojson::value v(reply);
+  PostMessage(v.serialize().c_str());
+}
+
+void ContentInstance::PostAsyncSuccessReply(const picojson::value& msg) {
+  picojson::value::object reply;
+  PostAsyncSuccessReply(msg, reply);
+}
+
+void ContentInstance::PostAsyncSuccessReply(const picojson::value& msg,
+    picojson::value& value) {
+  picojson::value::object reply;
+  reply["value"] = value;
+  PostAsyncSuccessReply(msg, reply);
+}
+
+void ContentInstance::HandleSyncMessage(const char* message) {
+}
+
+void ContentInstance::HandleGetDirectoriesRequest(const picojson::value& msg) {
+  ContentFolderList folderList;
+  if (media_folder_foreach_folder_from_db(NULL,
+          mediaFolderCallback,
+          reinterpret_cast<void *>(&folderList)) != MEDIA_CONTENT_ERROR_NONE) {
+    std::cerr << "media_folder_get_folder_count_from_db: error\n";
+  } else {
+    HandleGetDirectoriesReply(msg, &folderList);
+  }
+}
+
+void ContentInstance::HandleGetDirectoriesReply(const picojson::value& msg,
+    ContentFolderList* folderList) {
+  const std::vector<ContentFolder *> &results = folderList->getAllItems();
+  picojson::value::array folders;
+
+  for (unsigned int i = 0; i < results.size(); i++) {
+    ContentFolder* folder = results[i];
+
+    picojson::value::object o;
+
+    o["id"] = picojson::value(folder->id());
+    o["directoryURI"] = picojson::value(folder->directoryURI());
+    o["title"] = picojson::value(folder->title());
+    o["storageType"] = picojson::value(folder->storageType());
+    o["modifiedDate"] =
+      picojson::value(static_cast<double>(folder->modifiedDate()));
+
+    folders.push_back(picojson::value(o));
+  }
+  picojson::value value(folders);
+  PostAsyncSuccessReply(msg, value);
+}
+
+bool ContentInstance::mediaFolderCallback(media_folder_h handle,
+    void* user_data) {
+  if (!user_data)
+    return false;
+
+  ContentFolderList* folderList =
+    reinterpret_cast<ContentFolderList *>(user_data);
+
+  ContentFolder* folder = new ContentFolder;
+  folder->init(handle);
+  folderList->addFolder(folder);
+#ifdef DEBUG
+  folder->print();
+#endif
+  return true;
+}
+
+void ContentInstance::HandleFindRequest(const picojson::value& msg) {
+  ContentItemList itemList;
+  if (media_info_foreach_media_from_db(NULL,
+      mediaInfoCallback,
+      reinterpret_cast<ContentFolderList *>(&itemList))
+      != MEDIA_CONTENT_ERROR_NONE) {
+    std::cerr << "media_info_foreach_media_from_db: error\n";
+  } else {
+    HandleFindReply(msg, &itemList);
+  }
+}
+
+void ContentInstance::HandleFindReply(
+    const picojson::value& msg,
+    ContentItemList* itemList) {
+  const std::vector<ContentItem *> &results = itemList->getAllItems();
+
+  picojson::value::array items;
+
+  for (unsigned i = 0; i < results.size(); i++) {
+    ContentItem* item = results[i];
+
+    picojson::value::object o;
+
+    o["id"] = picojson::value(item->id());
+    o["name"] = picojson::value(item->name());
+    o["type"] = picojson::value(item->type());
+    o["mimeType"] = picojson::value(item->mimeType());
+    o["title"] = picojson::value(item->title());
+    o["contentURI"] = picojson::value(item->contentURI());
+    o["thumbnailURIs"] = picojson::value(item->thumbnailURIs());
+    o["releaseDate"] =
+      picojson::value(static_cast<double>(item->releaseDate()));
+    o["modifiedDate"] =
+      picojson::value(static_cast<double>(item->modifiedDate()));
+    o["size"] = picojson::value(static_cast<double>(item->size()));
+    o["description"] = picojson::value(item->description());
+    o["rating"] = picojson::value(static_cast<double>(item->rating()));
+
+    items.push_back(picojson::value(o));
+  }
+  picojson::value value(items);
+  PostAsyncSuccessReply(msg, value);
+}
+
+bool ContentInstance::mediaInfoCallback(media_info_h handle, void* user_data) {
+  if (!user_data)
+    return false;
+
+  ContentItemList* itemList = reinterpret_cast<ContentItemList*>(user_data);
+
+  ContentItem* item = new ContentItem;
+  item->init(handle);
+  itemList->addItem(item);
+#ifdef DEBUG
+  item->print();
+#endif
+  return true;
+}
+
+void ContentFolder::init(media_folder_h handle) {
+  char* str = NULL;
+  time_t date;
+  media_content_storage_e storageType;
+
+  if (media_folder_get_folder_id(handle, &str) == MEDIA_CONTENT_ERROR_NONE) {
+    setID(str);
+    free(str);
+  }
+
+  if (media_folder_get_path(handle, &str) == MEDIA_CONTENT_ERROR_NONE) {
+    setDirectoryURI(pathToURI(str));
+    free(str);
+  }
+
+  if (media_folder_get_name(handle, &str) == MEDIA_CONTENT_ERROR_NONE) {
+    setTitle(str);
+    free(str);
+  }
+
+  if (media_folder_get_storage_type(
+      handle, &storageType) == MEDIA_CONTENT_ERROR_NONE) {
+    std::string type;
+    if (storageType == MEDIA_CONTENT_STORAGE_INTERNAL) {
+      type = "INTERNAL";
+    } else if (storageType == MEDIA_CONTENT_STORAGE_EXTERNAL) {
+      type = "EXTERNAL";
+    } else {
+      type = "UNKNOWN";
+    }
+    setStorageType(type);
+  }
+
+  if (media_folder_get_modified_time(
+      handle, &date) == MEDIA_CONTENT_ERROR_NONE) {
+    setModifiedDate(date);
+  }
+}
+
+#ifdef DEBUG
+void ContentFolder::print(void) {
+  std::cout << "ID: " << getID() << std::endl;
+  std::cout << "URI: " << getDirectoryURI() << std::endl;
+  std::cout << "Title: " << getTitle() << std::endl;
+  std::cout << "Type: " << getStorageType() << std::endl;
+  char pc[26];
+  time_t time = getModifiedDate();
+  std::cout << "Date: " << ctime_r(&time, pc) << std::endl;
+}
+#endif
+
+void ContentItem::init(media_info_h handle) {
+  char* pc = NULL;
+
+  // NOTE: the Tizen CAPI media_info_* functions assumes
+  // the caller frees the char**. The CAPI can also return NULL char**
+  // even the return code is MEDIA_CONTENT_ERROR_NONE.
+
+  if (media_info_get_media_id(handle, &pc) == MEDIA_CONTENT_ERROR_NONE && pc) {
+    setID(pc);
+    free(pc);
+  }
+
+  if (media_info_get_mime_type(handle, &pc) == MEDIA_CONTENT_ERROR_NONE && pc) {
+    setMimeType(pc);
+    free(pc);
+  }
+
+  if (media_info_get_title(handle, &pc) == MEDIA_CONTENT_ERROR_NONE && pc) {
+    setTitle(pc);
+    free(pc);
+  }
+
+  if (media_info_get_display_name(handle,
+      &pc) == MEDIA_CONTENT_ERROR_NONE && pc) {
+    setName(pc);
+    free(pc);
+  }
+
+  if (media_info_get_file_path(handle, &pc) == MEDIA_CONTENT_ERROR_NONE && pc) {
+    setContentURI(pathToURI(pc));
+    free(pc);
+  }
+
+  if (media_info_get_thumbnail_path(handle,
+      &pc) == MEDIA_CONTENT_ERROR_NONE && pc) {
+    setThumbnailURIs(pc);
+    free(pc);
+  }
+
+  if (media_info_get_description(handle,
+      &pc) == MEDIA_CONTENT_ERROR_NONE && pc) {
+    setDescription(pc);
+    free(pc);
+  }
+
+  time_t date;
+  if (media_info_get_modified_time(handle, &date) == MEDIA_CONTENT_ERROR_NONE) {
+    setModifiedDate(date);
+  }
+
+  int i = 0;
+  if (media_info_get_rating(handle, &i) == MEDIA_CONTENT_ERROR_NONE)
+    setRating(i);
+
+  uint64_t ll;
+  if (media_info_get_size(handle, &ll) == MEDIA_CONTENT_ERROR_NONE)
+    setSize(ll);
+
+  media_content_type_e type;
+  if (media_info_get_media_type(handle, &type) == MEDIA_CONTENT_ERROR_NONE) {
+    if (type == MEDIA_CONTENT_TYPE_IMAGE)
+      setType("IMAGE");
+    else if (type == MEDIA_CONTENT_TYPE_VIDEO)
+      setType("VIDEO");
+    else if (type == MEDIA_CONTENT_TYPE_MUSIC)
+      setType("AUDIO");
+    else if (type == MEDIA_CONTENT_TYPE_OTHERS)
+      setType("OTHER");
+  }
+}
+
+#ifdef DEBUG
+void ContentItem::print(void) {
+  std::cout << "----" << std::endl;
+  std::cout << "ID: " << getID() << std::endl;
+  std::cout << "Name: " << getName() << std::endl;
+  std::cout << "Type: " << getType() << std::endl;
+  std::cout << "MIME: " << getMimeType() << std::endl;
+  std::cout << "Title: " << getTitle() << std::endl;
+  std::cout << "URI: " << getContentURI() << std::endl;
+  std::cout << "ThumbnailURIs: " << getThumbnailURIs() << std::endl;
+  char pc[26];
+  time_t time = getModifiedDate();
+  std::cout << "Modified: " << ctime_r(&time, pc);
+  std::cout << "Size: " << getSize() << std::endl;
+  std::cout << "Description: " << getDescription() << std::endl;
+  std::cout << "Rating: " << getRating() << std::endl;
+}
+#endif
diff --git a/content/content_instance.h b/content/content_instance.h
new file mode 100644 (file)
index 0000000..1edcc86
--- /dev/null
@@ -0,0 +1,179 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_CONTENT_INSTANCE_H_
+#define CONTENT_CONTENT_INSTANCE_H_
+
+#include <media_content.h>
+
+#include <string>
+#include <algorithm>
+#include <vector>
+
+#include "common/extension.h"
+#include "common/picojson.h"
+#include "tizen/tizen.h"
+
+namespace picojson {
+class value;
+}
+
+class ContentFolderList;
+class ContentItemList;
+
+class ContentInstance : public common::Instance {
+ public:
+  ContentInstance();
+  virtual ~ContentInstance();
+
+ private:
+  // common::Instance implementation.
+  virtual void HandleMessage(const char* msg);
+  virtual void HandleSyncMessage(const char* msg);
+
+  void HandleGetDirectoriesRequest(const picojson::value& json);
+  void HandleGetDirectoriesReply(const picojson::value& json,
+    ContentFolderList *);
+  void HandleFindRequest(const picojson::value& json);
+  void HandleFindReply(const picojson::value& json, ContentItemList *);
+
+  // Asynchronous message helpers
+  void PostAsyncErrorReply(const picojson::value&, WebApiAPIErrors);
+  void PostAsyncSuccessReply(const picojson::value&, picojson::value::object&);
+  void PostAsyncSuccessReply(const picojson::value&, picojson::value&);
+  void PostAsyncSuccessReply(const picojson::value&, WebApiAPIErrors);
+  void PostAsyncSuccessReply(const picojson::value&);
+
+  // Tizen CAPI helpers
+  static bool mediaFolderCallback(media_folder_h handle, void *user_data);
+  static bool mediaInfoCallback(media_info_h handle, void *user_data);
+
+  static unsigned m_instanceCount;
+};
+
+class ContentFolder {
+ public:
+  ContentFolder() {
+    modifiedDate_ = { 0 };
+  }
+  ~ContentFolder() {}
+
+  void init(media_folder_h handle);
+
+  // Getters & Getters
+  std::string id() const { return id_; }
+  void setID(const std::string& id) { id_ = id; }
+  std::string directoryURI() const { return directoryURI_; }
+  void setDirectoryURI(const std::string& uri) { directoryURI_ = uri; }
+  std::string title() const { return title_; }
+  void setTitle(const std::string& title) { title_ = title; }
+  std::string storageType() const { return storageType_; }
+  void setStorageType(const std::string& type) { storageType_ = type; }
+  time_t modifiedDate() const { return modifiedDate_; }
+  void setModifiedDate(time_t modifiedDate) { modifiedDate_ = modifiedDate; }
+
+#ifdef DEBUG
+  void print(void);
+#endif
+
+ protected:
+  std::string id_;
+  std::string directoryURI_;
+  std::string title_;
+  std::string storageType_;
+  time_t modifiedDate_;
+};
+
+class ContentItem {
+ public:
+  ContentItem() {
+    releaseDate_ = { 0 };
+    modifiedDate_ = { 0 };
+    size_ = 0;
+    rating_ = 0;
+  }
+  ~ContentItem() {}
+
+  void init(media_info_h handle);
+
+  // Getters & Setters
+  std::string id() const { return id_; }
+  void setID(const std::string& id) { id_ = id; }
+  const std::string name() const { return name_; }
+  void setName(const std::string& name) { name_ = name; }
+  std::string type() const { return type_; }
+  void setType(const std::string& type) { type_ = type;}
+  std::string mimeType() const { return mimeType_; }
+  void setMimeType(const std::string& mimeType) { mimeType_ = mimeType; }
+  std::string title() const { return title_; }
+  void setTitle(const std::string& title) { title_ = title;}
+  std::string contentURI() const { return contentURI_; }
+  void setContentURI(const std::string& uri) { contentURI_ = uri; }
+  std::string thumbnailURIs() const { return thumbnailURIs_; }
+  void setThumbnailURIs(const std::string& uris) { thumbnailURIs_ = uris; }
+  time_t releaseDate() const { return releaseDate_; }
+  void setReleaseDate(time_t releaseDate) { releaseDate_ = releaseDate; }
+  time_t modifiedDate() const { return modifiedDate_; }
+  void setModifiedDate(time_t modifiedDate) { modifiedDate_ = modifiedDate; }
+  uint64_t size() const { return size_; }
+  void setSize(const uint64_t size) { size_ = size; }
+  std::string description() const { return description_; }
+  void setDescription(const std::string& desc) { description_ = desc; }
+  uint64_t rating() const { return rating_; }
+  void setRating(uint64_t rating) { rating_ = rating; }
+
+#ifdef DEBUG
+  void print(void);
+#endif
+
+ protected:
+  std::string id_;
+  std::string name_;
+  std::string type_;
+  std::string mimeType_;
+  std::string title_;
+  std::string contentURI_;
+  std::string thumbnailURIs_;
+  time_t releaseDate_;
+  time_t modifiedDate_;
+  uint64_t size_;
+  std::string description_;
+  uint64_t rating_;
+};
+
+class ContentFolderList {
+ public:
+  ~ContentFolderList() {
+    for (unsigned i = 0; i < m_folders.size(); i++)
+      delete m_folders[i];
+  }
+  void addFolder(ContentFolder* folder) {
+    m_folders.push_back(folder);
+  }
+  const std::vector<ContentFolder*>& getAllItems() {
+    return m_folders;
+  }
+
+ private:
+  std::vector<ContentFolder*> m_folders;
+};
+
+class ContentItemList {
+ public:
+  ~ContentItemList() {
+    for (unsigned i = 0; i < m_items.size(); i++)
+      delete m_items[i];
+  }
+  void addItem(ContentItem* item) {
+    m_items.push_back(item);
+  }
+  const std::vector<ContentItem*>& getAllItems() {
+    return m_items;
+  }
+
+ private:
+  std::vector<ContentItem*> m_items;
+};
+
+#endif  // CONTENT_CONTENT_INSTANCE_H_
diff --git a/examples/content.html b/examples/content.html
new file mode 100644 (file)
index 0000000..60d2ab6
--- /dev/null
@@ -0,0 +1,86 @@
+<html>
+<head>
+  <meta name="viewport" content="width=device-width">
+</head>
+
+<h1>Tizen Content API</h1>
+<body>
+<button onClick="handleUpdate()">Update</button>
+<button onClick="handleUpdateBatch()">Update Batch</button>
+<button onClick="handleGetDirectories()">Get Directories</button>
+<button onClick="handleFind()">Find</button>
+<button onClick="handleScanFile()">Scan File</button>
+
+<pre id="console"></pre>
+<script src="js/js-test-pre.js"></script>
+<script>
+
+function handleUpdate()
+{
+  try {
+    debug('tizen.content.update:');
+    tizen.content.update();
+  }
+  catch (err) {
+    debug(err.name);
+  }
+}
+
+function handleUpdateBatch()
+{
+  try {
+    debug('tizen.content.updateBatch:');
+    tizen.content.updateBatch();
+  }
+  catch (err) {
+    debug(err.name);
+  }
+}
+function handleGetDirectories()
+{
+  try {
+    debug('tizen.content.getDirectories:');
+    tizen.content.getDirectories(function(folders) {
+    for (var i = 0; i < folders.length; i++) {
+        debug(folders[i].title + ', ' + folders[i].directoryURI);
+      }    
+    }, 
+    function(err) {
+      debug(err.name);
+    });
+  }
+  catch (err) {
+    debug(err.name);
+  }
+}
+function handleFind()
+{
+  try {
+    debug('tizen.content.find:');
+    tizen.content.find(function(items) {
+      for (var i = 0; i < items.length; i++) {
+        debug(items[i].title + ', ' + items[i].mimeType + ', ' + items[i].contentURI);
+      }    
+    }, 
+    function(err) {
+      debug('find: error');
+    });
+  }
+  catch (err) {
+    debug(err.name);
+  }
+}
+function handleScanFile()
+{
+  try {
+    debug('tizen.content.scanFile:');
+    tizen.content.scanFile();
+  }
+  catch (err) {
+    debug(err.name);
+  }
+}
+
+</script>
+</body>
+</html>
index 5618563..35c1a6e 100644 (file)
@@ -32,5 +32,6 @@ div.block {
 <a href="application.html"><div class="block">application</div></a>
 <a href="callhistory.html"><div class="block">Call History</div></a>
 <a href="mediaserver.html"><div class="block">mediaserver</div></a>
+<a href="content.html"><div class="block">content</div></a>
 </body>
 </html>
index a2c3c31..528a970 100644 (file)
@@ -44,6 +44,7 @@ BuildRequires: pkgconfig(libpcrecpp)
 %endif
 BuildRequires: pkgconfig(capi-web-favorites)
 BuildRequires: pkgconfig(capi-web-url-download)
+BuildRequires: pkgconfig(capi-content-media-content)
 BuildRequires: pkgconfig(dbus-glib-1)
 # Evas.h is required by capi-web-favorites.
 BuildRequires: pkgconfig(evas)
index dfad2ba..4a3f725 100644 (file)
@@ -9,6 +9,7 @@
       'type': 'none',
       'dependencies': [
         'bluetooth/bluetooth.gyp:*',
+        'content/content.gyp:*',
         'filesystem/filesystem.gyp:*',
         'mediaserver/mediaserver.gyp:*',
         'network_bearer_selection/network_bearer_selection.gyp:*',