BuildRequires: pkgconfig(capi-appfw-app-manager)
BuildRequires: pkgconfig(capi-appfw-package-manager)
BuildRequires: pkgconfig(wrt-plugins-ipc-message)
+BuildRequires: pkgconfig(capi-content-media-content)
+BuildRequires: pkgconfig(capi-media-metadata-extractor)
%if 0%{?tizen_feature_account_support}
BuildRequires: pkgconfig(accounts-svc)
--- /dev/null
+{
+ 'includes':[
+ '../common/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'tizen_content',
+ 'type': 'loadable_module',
+ 'sources': [
+ 'content_api.js',
+ 'content_extension.cc',
+ 'content_extension.h',
+ 'content_instance.cc',
+ 'content_instance.h',
+ 'content_manager.h',
+ 'content_manager.cc',
+ ],
+ 'conditions': [
+ ['tizen == 1', {
+ 'variables': {
+ 'packages': [
+ 'capi-content-media-content',
+ 'capi-media-metadata-extractor',
+ 'capi-base-common',
+ 'dlog',
+ ]
+ },
+ }],
+ ],
+ },
+ ],
+}
--- /dev/null
+// Content
+
+var validator_ = xwalk.utils.validator;
+var types_ = validator_.Types;
+
+
+var callbackId = 0;
+var callbacks = {};
+
+extension.setMessageListener(function(json) {
+ var result = JSON.parse(json);
+ var callback = callbacks[result['callbackId']];
+ callback(result);
+});
+
+function nextCallbackId() {
+ return callbackId++;
+}
+
+
+var ExceptionMap = {
+ 'UnknownError' : tizen.WebAPIException.UNKNOWN_ERR ,
+ 'TypeMismatchError' : tizen.WebAPIException.TYPE_MISMATCH_ERR ,
+ 'InvalidValuesError' : tizen.WebAPIException.INVALID_VALUES_ERR ,
+ 'IOError' : tizen.WebAPIException.IO_ERR ,
+ 'ServiceNotAvailableError' : tizen.WebAPIException.SERVICE_NOT_AVAILABLE_ERR ,
+ 'SecurityError' : tizen.WebAPIException.SECURITY_ERR ,
+ 'NetworkError' : tizen.WebAPIException.NETWORK_ERR ,
+ 'NotSupportedError' : tizen.WebAPIException.NOT_SUPPORTED_ERR ,
+ 'NotFoundError' : tizen.WebAPIException.NOT_FOUND_ERR ,
+ 'InvalidAccessError' : tizen.WebAPIException.INVALID_ACCESS_ERR ,
+ 'AbortError' : tizen.WebAPIException.ABORT_ERR ,
+ 'QuotaExceededError' : tizen.WebAPIException.QUOTA_EXCEEDED_ERR ,
+}
+
+function callNative(cmd, args) {
+ var json = {'cmd':cmd, 'args':args};
+ var argjson = JSON.stringify(json);
+ var resultString = extension.internal.sendSyncMessage(argjson)
+ var result = JSON.parse(resultString);
+
+ if (typeof result !== 'object') {
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+ }
+
+ if (result['status'] == 'success') {
+ if(result['result']) {
+ return result['result'];
+ }
+ return true;
+ } else if (result['status'] == 'error') {
+ var err = result['error'];
+ if(err) {
+ if(ExceptionMap[err.name]) {
+ throw new tizen.WebAPIException(ExceptionMap[err.name], err.message);
+ } else {
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR, err.message);
+ }
+ }
+ return false;
+ }
+}
+
+
+function callNativeWithCallback(cmd, args, callback) {
+ if(callback) {
+ var id = nextCallbackId();
+ args['callbackId'] = id;
+ callbacks[id] = callback;
+ }
+ return callNative(cmd, args);
+}
+
+function SetReadOnlyProperty(obj, n, v){
+ Object.defineProperty(obj, n, {value:v, writable: false});
+}
+
+function Playlist(id, name, numberOfTracks, thumbnailURI) {
+ var name_ = name;
+ Object.defineProperties(this, {
+ 'id': { writable: false, value: id, enumerable: true },
+ 'name': { writable: true, value: name, enumerable: true },
+ 'numberOfTracks': { writable: false, value: numberOfTracks, enumerable: true },
+ 'thumbnailURI': {writable: true, value: thumbnailURI, enumerable: true }
+ });
+}
+
+function PlaylistItem(content,playlist_member_id) {
+ var content_ = content;
+ var member_id = playlist_member_id;
+ Object.defineProperties(this, {
+ 'content': { writable: false, value: content, enumerable: true },
+ 'member_id': {
+ set: function(v) { if (v != null) member_id = v},
+ get: function() { return member_id; }
+ }
+ });
+}
+
+
+Playlist.prototype.add = function(item) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'item', 'type': types_.PLATFORM_OBJECT, 'values': Content, 'optional' : false, 'nullable' : false}
+ ]);
+ console.log("[dykim]Playlist add entered1");
+ var nativeParam = {
+ 'playlist_id': this.id
+ };
+
+ if (args['item']) {
+ nativeParam['content_id'] = args.item.id;
+ }
+ try {
+ var syncResult = callNative('ContentPlaylist_add', nativeParam);
+ } catch(e) {
+ throw e;
+ }
+}
+
+Playlist.prototype.remove = function(item) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'item', 'type': types_.PLATFORM_OBJECT, 'values': PlaylistItem, 'optional' : false, 'nullable' : false}
+ ]);
+ var nativeParam = {
+ 'playlist_id': this.id,
+ 'member_id' : args.item.member_id
+ };
+
+ try {
+ var syncResult = callNative('ContentPlaylist_remove', nativeParam);
+ } catch(e) {
+ throw e;
+ }
+}
+
+
+Playlist.prototype.removeBatch = function(items) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'items', 'type': types_.ARRAY},
+ {'name' : 'successCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'playlist_id': this.id,
+ };
+
+ nativeParam["members"] = [];
+ if (args['items']) {
+ for (var i = 0; i < args.items.length; i++) {
+ var c = args.items[i];
+ console.log("member_id:" + c.member_id);
+ nativeParam.members.push(c.member_id);
+ }
+ console.log("nativeParam['members']:" + nativeParam["members"]);
+ }
+
+ try {
+ var syncResult = callNativeWithCallback('ContentPlaylist_removeBatch', nativeParam, function(result) {
+ if (result.status == 'success') {
+ console.log("[dykim]ContentPlaylist_removeBatch successCallback entered");
+ args.successCallback();
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+}
+
+
+Playlist.prototype.get = function() {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'successCallback', 'type': types_.FUNCTION},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'count', 'type': types_.LONG, optional : true, nullable : true},
+ {'name' : 'offset', 'type': types_.LONG, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'playlist_id': this.id
+ };
+
+ if (args['count']) {
+ nativeParam['count'] = args.count;
+ }
+ else {
+ nativeParam['count'] = -1;
+ }
+ if (args['offset']) {
+ nativeParam['offset'] = args.offset;
+ }
+ else {
+ nativeParam['offset'] = -1;
+ }
+
+ try {
+ var syncResult = callNativeWithCallback('ContentPlaylist_get', nativeParam, function(result) {
+ if (result.status == 'success') {
+ var items = [];
+ console.log("successCallback Playlist get:%d",result.value.length);
+ for (var i = 0; i < result.value.length; i++) {
+ var c = result.value[i];
+ console.log("name:" + c.name);
+ console.log("playlist_member_id:" + c.playlist_member_id);
+ var content = new Content(c.id, c.name);
+ var item = new PlaylistItem(content,c.playlist_member_id);
+ console.log("item :" + item.member_id);
+ items.push(item);
+ }
+ args.successCallback(items);
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ }
+ catch(e) {
+ throw e;
+ }
+}
+
+Playlist.prototype.addBatch = function() {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'items', 'type': types_.ARRAY},
+ {'name' : 'successCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'playlist_id': this.id,
+ 'contents' : args.items
+ };
+
+ try {
+ var syncResult = callNativeWithCallback('ContentPlaylist_addBatch', nativeParam, function(result) {
+ if (result.status == 'success') {
+ args.successCallback();
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+}
+
+
+Playlist.prototype.setOrder = function() {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'items', 'type': types_.ARRAY},
+ {'name' : 'successCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'playlist_id': this.id,
+ };
+
+ nativeParam["members"] = [];
+ if (args['items']) {
+ for (var i = 0; i < args.items.length; i++) {
+ var c = args.items[i];
+ console.log("member_id:" + c.member_id);
+ nativeParam.members.push(c.member_id);
+ }
+ }
+
+ try {
+ var syncResult = callNativeWithCallback('ContentPlaylist_setOrder', nativeParam, function(result) {
+ if (result.status == 'success') {
+ args.successCallback();
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+}
+
+Playlist.prototype.move = function(item, delta) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'item', 'type': types_.PLATFORM_OBJECT, 'values': PlaylistItem},
+ {'name' : 'delta', 'type': types_.LONG},
+ {'name' : 'successCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'playlist_id': this.id,
+ 'member_id': args.item.member_id
+ };
+
+ if (args['delta']) {
+ nativeParam['delta'] = delta;
+ }
+
+ try {
+ var syncResult = callNativeWithCallback('ContentPlaylist_move', nativeParam, function(result) {
+ if (result.status == 'success') {
+ console.log("[dykim]ContentPlaylist_move successCallback entered");
+ args.successCallback();
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+}
+
+
+function ContentDirectory(id, uri, type, title, date) {
+ Object.defineProperties(this, {
+ 'id': { writable: false, value: id, enumerable: true },
+ 'directoryURI': { writable: false, value: uri, enumerable: true },
+ 'title': { writable: false, value: title, enumerable: true },
+ 'storageType': { writable: false, value: type, enumerable: true },
+ 'date': { writable: false, value: date, enumerable: true },
+ });
+}
+
+
+function Content(id, name,type, mimeType, title, contentURI, thumbnailURIs,
+ releaseDate, modifiedDate, size, description, rating, isFavorite) {
+ var name_ = name;
+ var rating_ = rating;
+ var editableAttributes_= ["name", "description", "rating", "isFavorite"];
+
+ if (type === "IMAGE") {
+ editableAttributes_.push("geolocation");
+ editableAttributes_.push("orientation");
+ }
+ else if(type === "VIDEO") {
+ editableAttributes_.push("geolocation");
+ }
+ Object.defineProperties(this, {
+ 'editableAttributes':
+ { enumerable: true,
+ get: function() { return editableAttributes_; }
+ },
+ 'id':
+ { writable: false, value: id, enumerable: true },
+ 'name':
+ { enumerable: true,
+ set: function(v) { if (v != null) name_ = v},
+ get: function() { return name_; }
+ },
+ '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 },
+ 'thumbnailURIs':
+ { writable: false, value: thumbnailURIs, 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: true, value: description, enumerable: true },
+ 'rating':
+ { enumerable: true,
+ set: function(v) { if (v != null && v >= 0 && v <= 10) rating_ = v; },
+ get: function() { return rating_; }
+ },
+ 'isFavorite':
+ { writable: true, value: isFavorite, enumerable: true }
+ });
+}
+
+function ImageContent(obj, width, height, orientation, geolocation) {
+ Object.defineProperties(obj, {
+ 'width':
+ { writable: false, value: width, enumerable: true },
+ 'height':
+ { writable: false, value: height, enumerable: true },
+ 'orientation':
+ { writable: true, value: orientation, enumerable: true },
+ 'geolocation':
+ { writable: true, value: geolocation, enumerable: true }
+ });
+}
+
+function VideoContent(obj, geolocation, album, artists, duration, width, height) {
+ Object.defineProperties(obj, {
+ 'geolocation':
+ { writable: true, value: geolocation, enumerable: true },
+ 'album':
+ { writable: false, value: album, enumerable: true },
+ 'artists':
+ { writable: false, value: artists, enumerable: true },
+ 'duration':
+ { writable: false, value: duration, enumerable: true },
+ 'width':
+ { writable: false, value: width, enumerable: true },
+ 'height':
+ { writable: false, value: height, enumerable: true }
+ });
+}
+
+function AudioContentLyrics(type, timestamps, texts) {
+ Object.defineProperties(this, {
+ 'type':
+ { writable: false, value: type, enumerable: true },
+ 'timestamps':
+ { writable: false, value: timestamps, enumerable: true },
+ 'texts':
+ { writable: false, value: texts, enumerable: true }
+ });
+}
+
+function AudioContent(obj, album, genres, artists, composers, copyright,
+ bitrate, trackNumber, duration) {
+ var lyrics_ = undefined;
+ function getLyrics(contentURI) {
+ var nativeParam = {
+ 'contentURI': contentURI
+ };
+
+ var syncResult = callNative('ContentManager_getLyrics', nativeParam);
+
+ if (syncResult.status == 'success') {
+ var l = syncResult['result'];
+ lyrics_ = new AudioContentLyrics(l.type, l.timestamps, l.texts);
+ }
+ else {
+ console.log("Getting the lyrics is failed.");
+ }
+ }
+ Object.defineProperties(obj, {
+ 'album':
+ { writable: false, value: album, enumerable: true },
+ 'genres':
+ { writable: false, value: genres, enumerable: true },
+ 'artists':
+ { writable: false, value: artists, enumerable: true },
+ 'composers':
+ { writable: false, value: composers, enumerable: true },
+ 'copyright':
+ { writable: false, value: copyright, enumerable: true },
+ 'bitrate':
+ { writable: false, value: bitrate, enumerable: true },
+ 'trackNumber':
+ { writable: false, value: trackNumber, enumerable: true },
+ 'duration':
+ { writable: false, value: duration, enumerable: true },
+ 'lyrics':
+ { enumerable: true,
+ get: function() {
+ if(lyrics_ === undefined) {
+ getLyrics(obj.contentURI);
+ }
+ return lyrics_;
+ }
+ }
+ });
+}
+
+function createContent(c) {
+ var content = new Content(c.id,
+ c.name,
+ c.type,
+ c.mimeType,
+ c.title,
+ c.contentURI,
+ c.thumbnailURIs,
+ c.releaseDate,
+ c.modifiedDate,
+ c.size,
+ c.description,
+ c.rating,
+ c.isFavorite
+ );
+ if (c.type === "IMAGE") {
+ var image = new ImageContent(content,
+ c.width,
+ c.height,
+ c.orientation,
+ c.geolocation
+ );
+ }
+ else if (c.type === "VIDEO") {
+ var video = new VideoContent(content,
+ c.geo,
+ c.album,
+ c.artists,
+ c.duration,
+ c.width,
+ c.height
+ );
+ }
+ else if(c.type === "AUDIO") {
+ var audio = new AudioContent(content,
+ c.album,
+ c.genres,
+ c.artists,
+ c.composers,
+ c.copyright,
+ c.bitrate,
+ c.trackNumber,
+ c.duration
+ );
+ }
+ return content;
+}
+
+
+function ContentManager() {
+ // constructor of ContentManager
+}
+
+
+ContentManager.prototype.update = function(content) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'content', 'type': types_.PLATFORM_OBJECT}
+ ]);
+ console.log("[dykim]update entered1 id:" + content.id);
+ var nativeParam = {
+ };
+ if (args['content']) {
+ nativeParam['content'] = args.content;
+ }
+ try {
+ var syncResult = callNative('ContentManager_update', nativeParam);
+ } catch(e) {
+ throw e;
+ }
+}
+
+ContentManager.prototype.updateBatch = function(contents) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'contents', 'type': types_.ARRAY},
+ {'name' : 'successCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'contents' : args.contents
+ };
+
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_updateBatch', nativeParam, function(result) {
+ if (result.status == 'success') {
+ args.successCallback();
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+}
+
+ContentManager.prototype.getDirectories = function(successCallback) {
+ console.log("[dykim]getDirectories entered");
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'successCallback', 'type': types_.FUNCTION, optional : false, nullable : false},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ };
+
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_getDirectories', nativeParam, function(result) {
+ if (result.status == 'success') {
+ console.log("[dykim]getDirectories successCallback entered");
+ var dirs = [];
+
+ for (var i = 0; i < result.value.length; i++) {
+ var res = result.value[i];
+ var dir = new ContentDirectory(
+ res.id,
+ res.directoryURI,
+ res.title,
+ res.storageType,
+ res.modifiedDate
+ );
+
+ dirs.push(dir);
+ }
+ args.successCallback(dirs);
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ // if you need synchronous result from native function using 'syncResult'.
+ }
+ catch(e) {
+ throw e;
+ }
+}
+
+ContentManager.prototype.find = function(successCallback) {
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'successCallback', 'type': types_.FUNCTION, 'values' : ['onsuccess']},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'directoryId', 'type': types_.STRING, optional : true, nullable : true},
+ {'name' : 'filter', 'type': types_.DICTIONARY, optional : true, nullable : true},
+ {'name' : 'sortMode', 'type': types_.DICTIONARY, optional : true, nullable : true},
+ {'name' : 'count', 'type': types_.LONG, optional : true},
+ {'name' : 'offset', 'type': types_.LONG, optional : true}
+ ]);
+
+ var nativeParam = {
+ };
+
+ if (args['directoryId']) {
+ nativeParam['directoryId'] = args.directoryId;
+ }
+ if (args['filter']) {
+ nativeParam['filter'] = args.filter;
+ }
+ if (args['sortMode']) {
+ nativeParam['sortMode'] = args.sortMode;
+ }
+ if (args['count']) {
+ nativeParam['count'] = args.count;
+ }
+ if (args['offset']) {
+ nativeParam['offset'] = args.offset;
+ }
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_find', nativeParam, function(result) {
+ if (result.status == 'success') {
+ var contents = [];
+ console.log("successCallback find:%d",result.value.length);
+ for ( var i = 0; i < result.value.length; i++) {
+ var c = result.value[i];
+
+ var content = createContent(c);
+
+ contents.push(content);
+ }
+ args.successCallback(contents);
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ // if you need synchronous result from native function using 'syncResult'.
+ } catch(e) {
+ throw e;
+ }
+
+}
+
+ContentManager.prototype.scanFile = function(contentURI) {
+ console.log("[dykim]scanFile entered");
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'contentURI', 'type': types_.STRING},
+ {'name' : 'successCallback', 'type': types_.FUNCTION, 'values' : ['onsuccess'], optional : true, nullable : true},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'contentURI': args.contentURI
+ };
+
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_scanFile', nativeParam, function(result) {
+ if (result.status == 'success') {
+ if (args.successCallback) {
+ var uri = result['contentURI'];
+ args.successCallback(uri);
+ }
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+
+}
+
+ContentManager.prototype.setChangeListener = function(changeCallback) {
+ console.log("[dykim]setChangeListener entered");
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'changeCallback', 'type': types_.LISTENER, 'values' : ['oncontentadded', 'oncontentupdated', 'oncontentremoved']}
+ ]);
+
+ var nativeParam = {
+ };
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_setChangeListener', nativeParam, function(result) {
+ if (result.status == 'oncontentadded') {
+ console.log("[dykim]setChangeListener oncontentadded");
+ var c = result['value'];
+ var content = createContent(c);
+ args.changeCallback.oncontentadded(content);
+ }
+ if (result.status == 'oncontentupdated') {
+ console.log("[dykim]setChangeListener oncontentupdated");
+ var c = result['value'];
+ var content = createContent(c);
+ args.changeCallback.oncontentupdated(content);
+ }
+ if (result.status == 'oncontentremoved') {
+ console.log("[dykim]setChangeListener oncontentremoved");
+ var contentId = result['value'];
+ args.changeCallback.oncontentremoved(contentId);
+ }
+ });
+ // if you need synchronous result from native function using 'syncResult'.
+ } catch(e) {
+ throw e;
+ }
+ console.log("[dykim]setChangeListener ended");
+}
+
+ContentManager.prototype.unsetChangeListener = function() {
+ var nativeParam = {};
+ try {
+ var syncResult = callNative('ContentManager_unsetChangeListener', nativeParam);
+ } catch(e) {
+ throw e;
+ }
+
+}
+
+ContentManager.prototype.getPlaylists = function(successCallback) {
+ console.log("[dykim]getPlaylists start");
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'successCallback', 'type': types_.FUNCTION},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ };
+
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_getPlaylists', nativeParam, function(result) {
+ if (result.status == 'success') {
+ var playlists = [];
+ for ( var i = 0; i < result.value.length; i++) {
+ var p = result.value[i];
+ var playlist = new Playlist(p.id, p.name, p.numberOfTracks, p.thumbnailURI);
+ playlists.push(playlist);
+ }
+ args.successCallback(playlists);
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+ console.log("[dykim]getPlaylists end");
+}
+
+ContentManager.prototype.createPlaylist = function(name, successCallback) {
+ console.log("[dykim]createPlaylist start");
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'name', 'type': types_.STRING},
+ {'name' : 'successCallback', 'type': types_.FUNCTION},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'sourcePlaylist', 'type': types_.PLATFORM_OBJECT, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'name': args.name
+ };
+
+ if (args['sourcePlaylist']) {
+ nativeParam['sourcePlaylist'] = args.sourcePlaylist;
+ }
+
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_createPlaylist', nativeParam, function(result) {
+ if (result.status == 'success') {
+ var p = result['value'];
+ var ret = new Playlist(p.id, p.name, p.numberOfTracks, p.thumbnailURI);
+ args.successCallback(ret);
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+}
+
+ContentManager.prototype.removePlaylist = function(id) {
+ console.log("[dykim]removePlaylist start");
+ var args = validator_.validateArgs(arguments, [
+ {'name' : 'id', 'type': types_.STRING},
+ {'name' : 'successCallback', 'type': types_.FUNCTION, optional : true, nullable : true},
+ {'name' : 'errorCallback', 'type': types_.FUNCTION, optional : true, nullable : true}
+ ]);
+
+ var nativeParam = {
+ 'id': args.id
+ };
+
+ try {
+ var syncResult = callNativeWithCallback('ContentManager_removePlaylist', nativeParam, function(result) {
+ if (result.status == 'success') {
+ args.successCallback();
+ }
+ else if(result.status == 'error') {
+ var err = result['value'];
+ args.errorCallback(err);
+ }
+ });
+ } catch(e) {
+ throw e;
+ }
+
+ console.log("[dykim]removePlaylist end");
+}
+
+
+
+exports = new ContentManager();
+
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. 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_extension.h"
+
+#include "content/content_instance.h"
+
+// This will be generated from content_api.js
+extern const char kSource_content_api[];
+
+common::Extension* CreateExtension() {
+ return new ContentExtension;
+}
+
+ContentExtension::ContentExtension() {
+ SetExtensionName("tizen.content");
+ SetJavaScriptAPI(kSource_content_api);
+}
+
+ContentExtension::~ContentExtension() {}
+
+common::Instance* ContentExtension::CreateInstance() {
+ return new extension::content::ContentInstance;
+}
\ No newline at end of file
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. 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_
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <amp>
+
+#include "content_filter.h"
+
+#define __DEBUG__ 1
+
+
+namespace extension {
+namespace content {
+
+const std::map<std::string, std::string>& attributeNameMap = {
+ {"id", "MEDIA_ID"},
+ {"type", "MEDIA_TYPE"},
+ {"mimeType", "MEDIA_MIME_TYPE"},
+ {"name", "MEDIA_DISPLAY_NAME"},
+ {"title", "MEDIA_TITLE"},
+ {"contentURI", "MEDIA_PATH"},
+ {"thumbnailURIs", "MEDIA_THUMBNAIL_PATH"},
+ {"description", "MEDIA_DESCRIPTION"},
+ {"rating", "MEDIA_RATING"},
+ {"createdDate", "MEDIA_ADDED_TIME"},
+ {"releaseDate", "MEDIA_DATETAKEN"},
+ {"modifiedDate", "MEDIA_MODIFIED_TIME"},
+ {"geolocation.latitude", "MEDIA_LATITUDE"},
+ {"geolocation.longitude", "MEDIA_LONGITUDE"},
+ {"duration", "MEDIA_DURATION"},
+ {"album", "MEDIA_ALBUM"},
+ {"artists", "MEDIA_ARTIST"},
+ {"width", "MEDIA_WIDTH"},
+ {"height", "MEDIA_HEIGHT"},
+ {"genres", "MEDIA_GENRE"},
+ {"size", "MEDIA_SIZE"},
+};
+
+const std::map<std::string, std::string>& opMap = {
+ {"EXACTLY", " = "},
+ {"FULLSTRING", " = "},
+ {"CONTAINS", " LIKE "},
+ {"STARTSWITH", " LIKE "},
+ {"ENDSWITH", " LIKE "},
+ {"EXISTS", " IS NOT NULL "},
+};
+
+std::string ContentFilter::convert(const picojson::value& jsFilter) {
+ std::string attributeName = jsFilter.get("attributeName").to_str();
+ std::string matchFlag = jsFilter.get("matchFlag").to_str();
+ std::string matchValue = jsFilter.get("matchValue").to_str();
+
+#ifdef DEBUG
+ std::cout << "Filter IN: " << attributeName << " " << matchFlag << " " << matchValue << std::endl;
+#endif
+
+ std::string query;
+ if (attributeName.empty() || matchFlag.empty()) {
+ std::cerr <<
+ "Filter ERR: attribute or match flag missing" << std::endl;
+ return query;
+ }
+
+ std::map<std::string, std::string>::const_iterator it;
+ it = attributeNameMap.find(attributeName);
+ if (it == attributeNameMap.end()) {
+ std::cerr << "Filter ERR: unknown attributeName " <<
+ attributeName << std::endl;
+ return query;
+ }
+ std::string lValue = it->second;
+
+ it = opMap.find(matchFlag);
+ if (it == attributeNameMap.end()) {
+ std::cerr << "Filter ERR: unknown matchFlag " << matchFlag << std::endl;
+ return query;
+ }
+ std::string op = it->second;
+
+ // Tizen requires this weird mapping on type
+ if (attributeName == "type") {
+ if (matchValue == "IMAGE") {
+ matchValue = "0";
+ } else if (matchValue == "VIDEO") {
+ matchValue = "1";
+ } else if (matchValue == "AUDIO") {
+ matchValue = "3";
+ } else if (matchValue == "OTHER") {
+ matchValue = "4";
+ } else {
+ std::cerr << "Filter ERR: unknown media type " << matchValue << std::endl;
+ return query;
+ }
+ }
+
+ const std::string STR_QUOTE("'");
+ const std::string STR_PERCENT("%");
+ std::string rValue;
+ if (matchFlag == "CONTAINS")
+ rValue = STR_QUOTE + STR_PERCENT + matchValue + STR_PERCENT + STR_QUOTE;
+ else if (matchFlag == "STARTSWITH")
+ rValue = STR_QUOTE + matchValue + STR_PERCENT + STR_QUOTE;
+ else if (matchFlag == "ENDSWITH")
+ rValue = STR_QUOTE + STR_PERCENT + matchValue + STR_QUOTE;
+ else if (matchFlag == "FULLSTRING")
+ rValue = STR_QUOTE + matchValue + STR_QUOTE + " COLLATE NOCASE ";
+ else if (matchFlag == "EXISTS")
+ rValue = "";
+ else
+ rValue = STR_QUOTE + matchValue + STR_QUOTE;
+
+ query = lValue + op + rValue;
+#ifdef DEBUG
+ std::cout << "Filter OUT: " << query << std::endl;
+#endif
+ return query;
+}
+
+
+
+
+} // namespace content
+} // namespace extension
+
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. 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_FILTER_H_
+#define CONTENT_FILTER_H_
+
+#include "common/picojson.h"
+
+#include <string>
+#include <media_content.h>
+
+
+namespace extension {
+namespace content {
+
+class ContentFilter {
+ public:
+ std::string convert(const picojson::value &jsFilter);
+
+ private:
+
+
+};
+
+}
+}
+
+#endif
+
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. 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 <functional>
+#include <string>
+#include <dlog.h>
+#include <glib.h>
+#include <memory>
+#include <media_content.h>
+
+#include "common/picojson.h"
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "common/task-queue.h"
+
+#include "content_manager.h"
+
+namespace extension {
+namespace content {
+
+namespace {
+// The privileges that required in Content API
+const std::string kPrivilegeContent = "";
+
+} // namespace
+
+using namespace common;
+using namespace extension::content;
+
+ContentInstance::ContentInstance() {
+ using namespace std::placeholders;
+ #define REGISTER_SYNC(c,x) \
+ RegisterSyncHandler(c, std::bind(&ContentInstance::x, this, _1, _2));
+ REGISTER_SYNC("ContentManager_find", ContentManagerFind);
+ REGISTER_SYNC("ContentManager_update", ContentManagerUpdate);
+ REGISTER_SYNC("ContentManager_scanFile", ContentManagerScanfile);
+ REGISTER_SYNC("ContentManager_unsetChangeListener", ContentManagerUnsetchangelistener);
+ REGISTER_SYNC("ContentManager_setChangeListener", ContentManagerSetchangelistener);
+ REGISTER_SYNC("ContentManager_getDirectories", ContentManagerGetdirectories);
+ REGISTER_SYNC("ContentManager_updateBatch", ContentManagerUpdatebatch);
+ REGISTER_SYNC("ContentManager_removePlaylist", ContentManagerRemoveplaylist);
+ REGISTER_SYNC("ContentManager_createPlaylist", ContentManagerCreateplaylist);
+ REGISTER_SYNC("ContentManager_getPlaylists", ContentManagerGetplaylists);
+ REGISTER_SYNC("ContentPlaylist_add", ContentManagerPlaylistAdd);
+ REGISTER_SYNC("ContentPlaylist_addBatch", ContentManagerPlaylistAddbatch);
+ REGISTER_SYNC("ContentPlaylist_get", ContentManagerPlaylistGet);
+ REGISTER_SYNC("ContentPlaylist_remove", ContentManagerPlaylistRemove);
+ REGISTER_SYNC("ContentPlaylist_removeBatch", ContentManagerPlaylistRemovebatch);
+ REGISTER_SYNC("ContentPlaylist_setOrder", ContentManagerPlaylistSetorder);
+ REGISTER_SYNC("ContentPlaylist_move", ContentManagerPlaylistMove);
+ REGISTER_SYNC("ContentManager_getLyrics", ContentManagerAudioGetLyrics);
+
+ //
+ #undef REGISTER_SYNC
+}
+
+ContentInstance::~ContentInstance() {
+ LoggerE("<<endterd>>");
+}
+
+static void ReplyAsync(ContentInstance* instance, ContentCallbacks cbfunc,
+ double callbackId, bool isSuccess, picojson::object& param) {
+ LoggerE("<<endterd>>");
+ param["callbackId"] = picojson::value(static_cast<double>(callbackId));
+ param["status"] = picojson::value(isSuccess ? "success" : "error");
+
+ picojson::value result = picojson::value(param);
+
+ instance->PostMessage(result.serialize().c_str());
+}
+
+static gboolean CompletedCallback(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ LoggerE("<<endterd>>");
+
+ picojson::value::object reply;
+ reply["value"] = user_data->result;
+ LoggerE("CompletedCallback...(%d)" , user_data->isSuccess);
+ ReplyAsync(user_data->instance,user_data->cbType,user_data->callbackId,user_data->isSuccess,reply);
+
+ return false;
+}
+
+static void* WorkThread(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ LoggerE("<<endterd>>");
+ user_data->isSuccess = true;
+ ContentCallbacks cbType = user_data->cbType;
+ switch(cbType) {
+ case ContentManagerUpdatebatchCallback: {
+ LoggerE("ContentManagerUpdatebatchCallback...");
+ ContentManager::getInstance()->updateBatch(user_data->args);
+ break;
+ }
+ case ContentManagerGetdirectoriesCallback: {
+ LoggerE("ContentManagerGetdirectoriesCallback...");
+ ContentManager::getInstance()->getDirectories(user_data);
+ break;
+ }
+ case ContentManagerFindCallback: {
+ ContentManager::getInstance()->find(user_data);
+ LoggerE("ContentManagerFindCallback...:%s", user_data->result.serialize().c_str());
+ break;
+ }
+ case ContentManagerScanfileCallback: {
+ std::string contentURI = user_data->args.get("contentURI").get<std::string>();
+ ContentManager::getInstance()->scanFile(contentURI);
+ break;
+ }
+ case ContentManagerGetplaylistsCallback: {
+ LoggerE("ContentManagerGetplaylistsCallback...");
+ ContentManager::getInstance()->getPlaylists(user_data);
+ break;
+ }
+ case ContentManagerCreateplaylistCallback: {
+ LoggerE("ContentManagerCreateplaylistCallback...");
+ if (user_data->args.contains("sourcePlaylist")) {
+ picojson::object playlist = user_data->args.get("sourcePlaylist").get<picojson::object>();
+ user_data->isSuccess = true;
+ user_data->result = picojson::value(playlist);
+ }
+ else{
+ std::string name = user_data->args.get("name").get<std::string>();
+ ContentManager::getInstance()->createPlaylist(name, user_data);
+ }
+ break;
+ }
+ case ContentManagerRemoveplaylistCallback: {
+ LoggerE("ContentManagerRemoveplaylistCallback...");
+ std::string id = user_data->args.get("id").get<std::string>();
+ ContentManager::getInstance()->removePlaylist(id, user_data);
+ // do something...
+ break;
+ }
+ case ContentManagerPlaylistAddbatchCallback: {
+ LoggerE("ContentManagerPlaylistAddBatchCallback...");
+ ContentManager::getInstance()->playlistAddbatch(user_data);
+ break;
+ }
+ case ContentManagerPlaylistGetCallback: {
+ LoggerE("ContentManagerPlaylistGetCallback...");
+ ContentManager::getInstance()->playlistGet(user_data);
+ break;
+ }
+ case ContentManagerPlaylistRemovebatchCallback: {
+ LoggerE("ContentManagerPlaylistGetCallback...");
+ ContentManager::getInstance()->playlistRemovebatch(user_data);
+ break;
+ }
+ case ContentManagerPlaylistSetOrderCallback: {
+ LoggerE("ContentManagerPlaylistSetOrderCallback...");
+ ContentManager::getInstance()->playlistSetOrder(user_data);
+ break;
+ //ContentManagerPlaylistSetOrderCallback
+ }
+ case ContentManagerPlaylistMoveCallback: {
+ LoggerE("ContentManagerPlaylistMove...");
+ ContentManager::getInstance()->playlistMove(user_data);
+ break;
+ }
+ case ContentManagerErrorCallback: {
+ UnknownException err("DB Connection is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ break;
+ }
+ default: {
+ LoggerE("Invalid Callback Type");
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+static void changedContentCallback(media_content_error_e error, int pid, media_content_db_update_item_type_e update_item,
+ media_content_db_update_type_e update_type, media_content_type_e media_type,
+ char *uuid, char *path, char *mime_type, void* user_data) {
+
+ int ret;
+ std::shared_ptr<ReplyCallbackData> *cbData = (std::shared_ptr<ReplyCallbackData>*)(user_data);
+ LoggerE("ContentInstance::ContentManagerScanfile");
+ picojson::object reply;
+
+ picojson::object o;
+ if( error == MEDIA_CONTENT_ERROR_NONE) {
+ if( update_item == MEDIA_ITEM_FILE) {
+ if(update_type == MEDIA_CONTENT_INSERT || update_type == MEDIA_CONTENT_UPDATE) {
+ media_info_h media = NULL;
+ std::string id(uuid);
+ ret = media_info_get_media_from_db(id.c_str(), &media);
+ if (ret == MEDIA_CONTENT_ERROR_NONE && media != NULL) {
+ ContentManager::getInstance()->contentToJson(media, o);
+ reply["value"] = picojson::value(o);
+ if (update_type == MEDIA_CONTENT_INSERT) {
+ reply["status"] = picojson::value("oncontentadded");
+ }
+ else if (update_type == MEDIA_CONTENT_UPDATE) {
+ reply["status"] = picojson::value("oncontentupdated");
+ }
+ }
+ }
+ else {
+ reply["value"] = picojson::value(std::string(uuid));
+ reply["status"] = picojson::value("oncontentremoved");
+ }
+ }
+ }
+ else {
+ return;
+ }
+ reply["callbackId"] = picojson::value(static_cast<double>((*cbData)->callbackId));
+ picojson::value result = picojson::value(reply);
+ (*cbData)->instance->PostMessage(result.serialize().c_str());
+}
+
+
+#define CHECK_EXIST(args, name, out) \
+ if (!args.contains(name)) {\
+ ReportError(TypeMismatchException(name" is required argument"), out);\
+ return;\
+ }
+
+
+void ContentInstance::ContentManagerUpdate(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerUpdate");
+ int ret;
+ if(ContentManager::getInstance()->isConnected()) {
+ ret = ContentManager::getInstance()->update(args);
+ if(ret != 0) {
+ ReportError(ContentManager::getInstance()->convertError(ret),out);
+ }
+ }
+ else {
+ ReportError(UnknownException("DB connection is failed."),out);
+ }
+}
+void ContentInstance::ContentManagerUpdatebatch(const picojson::value& args, picojson::object& out) {
+ LoggerE("entered");
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerUpdatebatchCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+}
+void ContentInstance::ContentManagerGetdirectories(const picojson::value& args, picojson::object& out) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentInstance::getDirectories started");
+ CHECK_EXIST(args, "callbackId", out)
+
+ double callbackId = args.get("callbackId").get<double>();
+ // implement it
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerGetdirectoriesCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+
+ // call ReplyAsync in later (Asynchronously)
+
+ // if success
+ //ReportSuccess(out);
+ // if error
+ // ReportError(out);
+}
+void ContentInstance::ContentManagerFind(const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "callbackId", out)
+
+ //double count = args.get("count").get<double>();
+ //double offset = args.get("offset").get<double>();
+
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerFindCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+ // implement it
+
+ // call ReplyAsync in later (Asynchronously)
+
+ // if success
+ // ReportSuccess(out);
+ // if error
+ // ReportError(out);
+}
+void ContentInstance::ContentManagerScanfile(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerScanfile");
+ CHECK_EXIST(args, "callbackId", out)
+ CHECK_EXIST(args, "contentURI", out)
+
+ double callbackId = args.get("callbackId").get<double>();
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerScanfileCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+ // implement it
+ // call ReplyAsync in later (Asynchronously)
+
+ // if success
+ // ReportSuccess(out);
+ // if error
+ // ReportError(out);
+}
+void ContentInstance::ContentManagerSetchangelistener(const picojson::value& args, picojson::object& out) {
+ CHECK_EXIST(args, "callbackId", out)
+
+ double callbackId = args.get("callbackId").get<double>();
+
+ std::shared_ptr<ReplyCallbackData>cbData(new ReplyCallbackData);
+
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerSetchangelistenerCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+
+ ContentManager::getInstance()->setChangeListener(changedContentCallback,static_cast<void*>(&cbData));
+
+ // implement it
+
+ // call ReplyAsync in later (Asynchronously)
+
+ // if success
+ // ReportSuccess(out);
+ // if error
+ // ReportError(out);
+}
+void ContentInstance::ContentManagerUnsetchangelistener(const picojson::value& args, picojson::object& out) {
+
+ ContentManager::getInstance()->unSetChangeListener();
+
+ // if success
+ // ReportSuccess(out);
+ // if error
+ // ReportError(out);
+}
+void ContentInstance::ContentManagerGetplaylists(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerGetplaylists");
+ CHECK_EXIST(args, "callbackId", out)
+
+ double callbackId = args.get("callbackId").get<double>();
+
+ // implement it
+ std::shared_ptr<ReplyCallbackData>cbData(new ReplyCallbackData);
+
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerGetplaylistsCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+
+}
+void ContentInstance::ContentManagerCreateplaylist(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerCreateplaylist");
+ CHECK_EXIST(args, "callbackId", out)
+ CHECK_EXIST(args, "name", out)
+
+ double callbackId = args.get("callbackId").get<double>();
+ const std::string& name = args.get("name").get<std::string>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerCreateplaylistCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+}
+void ContentInstance::ContentManagerRemoveplaylist(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerRemoveplaylist");
+
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerRemoveplaylistCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+
+ // implement it
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+
+
+ // if success
+ // ReportSuccess(out);
+ // if error
+ // ReportError(out);
+}
+
+void ContentInstance::ContentManagerPlaylistAdd(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerPlaylistAdd");
+ int ret;
+ if(ContentManager::getInstance()->isConnected()) {
+ std::string playlist_id = args.get("playlist_id").get<std::string>();
+ std::string content_id = args.get("content_id").get<std::string>();
+ LoggerE("playlist:%s / content:%s", playlist_id.c_str() , content_id.c_str());
+ ret = ContentManager::getInstance()->playlistAdd(playlist_id, content_id);
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ ReportError(ContentManager::getInstance()->convertError(ret),out);
+ }
+ }
+ else {
+ ReportError(UnknownException("DB connection is failed."),out);
+ }
+}
+
+void ContentInstance::ContentManagerPlaylistAddbatch(const picojson::value& args, picojson::object& out) {
+ LoggerE("entered");
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerPlaylistAddbatchCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+}
+
+
+void ContentInstance::ContentManagerPlaylistGet(const picojson::value& args, picojson::object& out) {
+ LoggerE("entered");
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerPlaylistGetCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+}
+
+void ContentInstance::ContentManagerPlaylistRemove(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerPlaylistRemove");
+ int ret;
+ if(ContentManager::getInstance()->isConnected()) {
+ std::string playlist_id = args.get("playlist_id").get<std::string>();
+ int member_id = args.get("member_id").get<double>();
+ LoggerE("playlist:%s / member_id:%d", playlist_id.c_str() , member_id);
+ ret = ContentManager::getInstance()->playlistRemove(playlist_id, member_id);
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ ReportError(ContentManager::getInstance()->convertError(ret),out);
+ }
+ }
+ else {
+ ReportError(UnknownException("DB connection is failed."),out);
+ }
+}
+
+void ContentInstance::ContentManagerPlaylistRemovebatch(const picojson::value& args, picojson::object& out) {
+ LoggerE("entered");
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerPlaylistRemovebatchCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+}
+
+
+void ContentInstance::ContentManagerPlaylistSetorder(const picojson::value& args, picojson::object& out) {
+ LoggerE("entered");
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerPlaylistSetOrderCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+}
+
+void ContentInstance::ContentManagerPlaylistMove(const picojson::value& args, picojson::object& out) {
+ LoggerE("entered");
+ double callbackId = args.get("callbackId").get<double>();
+
+ auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
+ cbData->callbackId = callbackId;
+ cbData->instance = this;
+ cbData->args = args;
+
+ if(ContentManager::getInstance()->isConnected()) {
+ cbData->cbType = ContentManagerPlaylistMoveCallback;
+ }
+ else {
+ cbData->cbType = ContentManagerErrorCallback;
+ }
+ common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
+}
+
+void ContentInstance::ContentManagerAudioGetLyrics(const picojson::value& args, picojson::object& out) {
+ LoggerE("ContentInstance::ContentManagerAudioGetLyrics");
+ int ret;
+ picojson::object lyrics;
+ if(ContentManager::getInstance()->isConnected()) {
+ ret = ContentManager::getInstance()->getLyrics(args,lyrics);
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ ReportError(ContentManager::getInstance()->convertError(ret),out);
+ }
+ else {
+ ReportSuccess(picojson::value(lyrics),out);
+ }
+ }
+ else {
+ ReportError(UnknownException("DB connection is failed."),out);
+ }
+}
+#undef CHECK_EXIST
+
+} // namespace content
+} // namespace extension
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. 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 "common/extension.h"
+
+namespace extension {
+namespace content {
+
+enum ContentCallbacks {
+ ContentManagerFindCallback,
+ ContentManagerScanfileCallback,
+ ContentManagerUnsetchangelistenerCallback,
+ ContentManagerSetchangelistenerCallback,
+ ContentManagerGetdirectoriesCallback,
+ ContentManagerUpdatebatchCallback,
+ ContentManagerRemoveplaylistCallback,
+ ContentManagerCreateplaylistCallback,
+ ContentManagerGetplaylistsCallback,
+ ContentManagerPlaylistAddbatchCallback,
+ ContentManagerPlaylistGetCallback,
+ ContentManagerPlaylistRemovebatchCallback,
+ ContentManagerPlaylistSetOrderCallback,
+ ContentManagerPlaylistMoveCallback,
+ ContentManagerErrorCallback
+};
+
+
+class ContentInstance : public common::ParsedInstance {
+ public:
+ ContentInstance();
+ virtual ~ContentInstance();
+
+ private:
+ void ContentManagerUpdate(const picojson::value& args, picojson::object& out);
+ void ContentManagerUpdatebatch(const picojson::value& args, picojson::object& out);
+ void ContentManagerGetdirectories(const picojson::value& args, picojson::object& out);
+ void ContentManagerFind(const picojson::value& args, picojson::object& out);
+ void ContentManagerScanfile(const picojson::value& args, picojson::object& out);
+ void ContentManagerSetchangelistener(const picojson::value& args, picojson::object& out);
+ void ContentManagerUnsetchangelistener(const picojson::value& args, picojson::object& out);
+ void ContentManagerGetplaylists(const picojson::value& args, picojson::object& out);
+ void ContentManagerCreateplaylist(const picojson::value& args, picojson::object& out);
+ void ContentManagerRemoveplaylist(const picojson::value& args, picojson::object& out);
+ void ContentManagerPlaylistAdd(const picojson::value& args, picojson::object& out);
+ void ContentManagerPlaylistAddbatch(const picojson::value& args, picojson::object& out);
+ void ContentManagerPlaylistGet(const picojson::value& args, picojson::object& out);
+ void ContentManagerPlaylistRemove(const picojson::value& args, picojson::object& out);
+ void ContentManagerPlaylistRemovebatch(const picojson::value& args, picojson::object& out);
+ void ContentManagerPlaylistSetorder(const picojson::value& args, picojson::object& out);
+ void ContentManagerPlaylistMove(const picojson::value& args, picojson::object& out);
+ void ContentManagerAudioGetLyrics(const picojson::value& args, picojson::object& out);
+
+//
+};
+
+typedef struct _ReplyCallbackData{
+ ContentInstance* instance;
+ ContentCallbacks cbType;
+ double callbackId;
+ bool isSuccess;
+ picojson::value args;
+ picojson::value result;
+}ReplyCallbackData;
+
+
+} // namespace content
+} // namespace extension
+
+#endif // CONTENT_CONTENT_INSTANCE_H_
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <unistd.h>
+#include <cstring>
+#include <string>
+#include <algorithm>
+#include <dlog.h>
+#include <memory>
+#include <sstream>
+#include <metadata_extractor.h>
+
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "content_manager.h"
+#include "content_filter.h"
+
+using namespace std;
+using namespace common;
+
+namespace extension {
+namespace content {
+
+#define TAG_DELIMETER '/'
+
+static int get_utc_offset()
+{
+ time_t zero = 24*60*60L;
+ struct tm * timeptr;
+ int gmtime_hours;
+
+ /* get the local time for Jan 2, 1900 00:00 UTC */
+ timeptr = localtime( &zero );
+ gmtime_hours = timeptr->tm_hour;
+
+ if( timeptr->tm_mday < 2 )
+ gmtime_hours -= 24;
+
+ return gmtime_hours;
+}
+
+static bool isContentUri(const std::string str) {
+ std::string schema("file://");
+ std::size_t found = str.find(schema);
+
+ if (found == std::string::npos || found != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+static std::string ltrim(const std::string s) {
+ std::string str = s;
+ std::string::iterator i;
+ for (i = str.begin(); i != str.end(); i++) {
+ if (!isspace(*i)) {
+ break;
+ }
+ }
+ if (i == str.end()) {
+ str.clear();
+ } else {
+ str.erase(str.begin(), i);
+ }
+ return str;
+}
+
+
+static std::string convertUriToPath(const string str) {
+ string result;
+ std::string schema ("file://");
+ std::string _str = ltrim(str);
+
+ std::string _schema = _str.substr(0,schema.size());
+
+ if(_schema == schema)
+ {
+ result = _str.substr(schema.size());
+ }
+ else
+ {
+ result = _str;
+ }
+ return result;
+}
+
+static std::string convertPathToUri(const string str) {
+ string result;
+ std::string schema ("file://");
+ std::string _str = ltrim(str);
+
+ std::string _schema = _str.substr(0,schema.size());
+
+ if(_schema == schema)
+ {
+ result = _str;
+ }
+ else
+ {
+ result = schema + _str;
+ }
+ return result;
+}
+
+
+static void contentToJson(media_info_h info, picojson::object& o) {
+ int ret;
+ int tmpInt = 0;
+ bool tmpBool = false;
+ char* tmpStr = NULL;
+ time_t tmpDate;
+ double tmpDouble;
+ long long unsigned int tmpLong;
+
+ media_content_type_e type;
+ ret == media_info_get_media_type(info, &type);
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ if ( type == MEDIA_CONTENT_TYPE_IMAGE ) {
+ o["type"] = picojson::value(std::string("IMAGE"));
+ image_meta_h img;
+ if(MEDIA_CONTENT_ERROR_NONE == media_info_get_image(info, &img)) {
+ if(MEDIA_CONTENT_ERROR_NONE == image_meta_get_date_taken (img, &tmpStr)) {
+ if ( tmpStr ) {
+ struct tm *result = (struct tm *)calloc(1, sizeof(struct tm));
+ if(strptime(tmpStr, "%Y:%m:%d %H:%M:%S", result) == NULL) {
+ LoggerE( "Couldn't convert supplied date.");
+ }
+ else {
+ time_t t = mktime( result );// + get_utc_offset() * 3600;
+ std::stringstream str_date;
+ str_date << t;
+ o["releaseDate"] = picojson::value(str_date.str());
+ free(tmpStr);
+ free(result);
+ tmpStr = NULL;
+ }
+ }
+ }
+ if(MEDIA_CONTENT_ERROR_NONE == image_meta_get_width(img, &tmpInt) ) {
+ o["width"] = picojson::value(static_cast<double>(tmpInt));
+ }
+
+ if(MEDIA_CONTENT_ERROR_NONE == image_meta_get_height(img, &tmpInt) ) {
+ o["height"] = picojson::value(static_cast<double>(tmpInt));
+ }
+ picojson::object geo;
+ std::string str_latitude;
+ if (MEDIA_CONTENT_ERROR_NONE == media_info_get_latitude(info, &tmpDouble) ) {
+ geo["latitude"] = picojson::value(tmpDouble);
+ }
+ std::string str_longitude;
+ if(MEDIA_CONTENT_ERROR_NONE == media_info_get_longitude(info, &tmpDouble) ) {
+ geo["longitude"] = picojson::value(tmpDouble);
+ }
+
+ o["geolocation"] = picojson::value(geo);
+
+ std::string ori;
+ media_content_orientation_e orientation;
+ if(MEDIA_CONTENT_ERROR_NONE == image_meta_get_orientation(img, &orientation) ) {
+ switch (orientation) {
+ case 0:
+ case 1:
+ ori = "NORMAL";
+ break;
+ case 2:
+ ori = "FLIP_HORIZONTAL";
+ break;
+ case 3:
+ ori = "ROTATE_180";
+ break;
+ case 4:
+ ori = "FLIP_VERTICAL";
+ break;
+ case 5:
+ ori = "TRANSPOSE";
+ break;
+ case 6:
+ ori = "ROTATE_90";
+ break;
+ case 7:
+ ori = "TRANSVERSE";
+ break;
+ case 8:
+ ori = "ROTATE_270";
+ break;
+ }
+ o["orientation"] = picojson::value(ori);
+ }
+
+ }
+
+ }
+ else if( type == MEDIA_CONTENT_TYPE_VIDEO ) {
+ o.insert(std::make_pair(std::string("type"), std::string("VIDEO")));
+ video_meta_h video;
+ if(MEDIA_CONTENT_ERROR_NONE == media_info_get_video(info, &video)) {
+ if(MEDIA_CONTENT_ERROR_NONE == video_meta_get_width(video, &tmpInt)) {
+ std::stringstream str_width;
+ str_width << tmpInt;
+ o.insert(std::make_pair(std::string("width"), str_width.str()));
+ }
+
+ if(MEDIA_CONTENT_ERROR_NONE == video_meta_get_height(video, &tmpInt) ) {
+ std::stringstream str_height;
+ str_height << tmpInt;
+ o.insert(std::make_pair(std::string("height"), str_height.str()));
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_artist(video, &tmpStr) ) {
+ picojson::array artists;
+ if (tmpStr) {
+ artists.push_back(picojson::value(std::string(tmpStr)));
+ }
+ o["artists"] = picojson::value(artists);
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_album(video, &tmpStr)) {
+ if (tmpStr) {
+ o.insert(std::make_pair(std::string("album"), tmpStr));
+ }
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_duration(video, &tmpInt) ) {
+ o.insert(std::make_pair(std::string("duration"), std::to_string(tmpInt)));
+ }
+ }
+ picojson::object geo;
+ if (MEDIA_CONTENT_ERROR_NONE == media_info_get_latitude(info, &tmpDouble) ) {
+ geo["latitude"] = picojson::value(tmpDouble);
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == media_info_get_longitude(info, &tmpDouble) ) {
+ geo["longitude"] = picojson::value(tmpDouble);
+ }
+ o["geolocation"] = picojson::value(geo);
+ }
+ else if( type == MEDIA_CONTENT_TYPE_SOUND || type == MEDIA_CONTENT_TYPE_MUSIC ) {
+ o["type"] = picojson::value(std::string("AUDIO"));
+ audio_meta_h audio;
+ if(MEDIA_CONTENT_ERROR_NONE == media_info_get_audio(info, &audio)) {
+ if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_recorded_date(audio, &tmpStr) ) {
+ if (tmpStr) {
+ struct tm *result = (struct tm *)calloc(1, sizeof(struct tm));
+
+ if (strptime(tmpStr, "%Y:%m:%d %H:%M:%S", result) == NULL) {
+ LoggerD( "Couldn't convert supplied date.");
+ }
+ time_t t = mktime( result ) + get_utc_offset() * 3600;
+ std::stringstream str_date;
+ str_date << t;
+ o["releaseDate"] = picojson::value(str_date.str());
+ free(tmpStr);
+ free(result);
+ tmpStr = NULL;
+ }
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_album(audio, &tmpStr)) {
+ if(tmpStr) {
+ o["album"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ if(MEDIA_CONTENT_ERROR_NONE == audio_meta_get_artist(audio, &tmpStr)) {
+ if(tmpStr) {
+ picojson::array artists;
+ if (tmpStr) {
+ artists.push_back(picojson::value(std::string(tmpStr)));
+ }
+ o["artists"] = picojson::value(artists);
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ if(MEDIA_CONTENT_ERROR_NONE == audio_meta_get_genre(audio, &tmpStr)) {
+ if(tmpStr) {
+ picojson::array genres;
+ if (tmpStr) {
+ genres.push_back(picojson::value(std::string(tmpStr)));
+ }
+ o["genres"] = picojson::value(genres);
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ if(MEDIA_CONTENT_ERROR_NONE == audio_meta_get_composer(audio, &tmpStr)) {
+ if(tmpStr) {
+ picojson::array composers;
+ if (tmpStr) {
+ composers.push_back(picojson::value(std::string(tmpStr)));
+ }
+ o["composers"] = picojson::value(composers);
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_copyright(audio, &tmpStr)) {
+ if(tmpStr) {
+ o["copyright"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_bit_rate(audio, &tmpInt)){
+ o["bitrate"] = picojson::value(static_cast<double>(tmpInt));
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_track_num (audio, &tmpStr)){
+ if(tmpStr) {
+ o["trackNumber"] = picojson::value(static_cast<double>(std::stoi(tmpStr)));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_duration(audio, &tmpInt) ) {
+ o["duration"] = picojson::value(static_cast<double>(tmpInt));
+ }
+
+ }
+ }
+ else {
+ o["type"] = picojson::value(std::string("OTHER"));
+ }
+ }
+
+ ret = media_info_get_media_id(info, &tmpStr);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ if(tmpStr) {
+ o["id"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+
+ ret = media_info_get_display_name(info, &tmpStr);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ if(tmpStr) {
+ o["name"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+
+ ret = media_info_get_mime_type(info, &tmpStr);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ if(tmpStr) {
+ o["mimeType"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+
+ ret = media_info_get_title(info, &tmpStr);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ if(tmpStr) {
+ o["title"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ ret = media_info_get_file_path(info, &tmpStr);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ if(tmpStr) {
+ o["contentURI"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+ //dykim. thumbnailURIs
+ ret = media_info_get_thumbnail_path(info, &tmpStr);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ if(tmpStr) {
+ picojson::array thumbnails;
+ thumbnails.push_back(picojson::value(std::string(tmpStr)));
+ o["thumbnailURIs"] = picojson::value(thumbnails);
+ tmpStr = NULL;
+ }
+ }
+
+ ret = media_info_get_description(info, &tmpStr);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ if(tmpStr) {
+ o["description"] = picojson::value(std::string(tmpStr));
+ free(tmpStr);
+ tmpStr = NULL;
+ }
+ }
+
+ ret = media_info_get_rating(info, &tmpInt);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ o["rating"] = picojson::value(static_cast<double>(tmpInt));
+ }
+
+ ret = media_info_get_size(info, &tmpLong);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ o["size"] = picojson::value(static_cast<double>(tmpLong));
+ }
+
+ ret = media_info_get_favorite(info, &tmpBool);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ o["isFavorite"] = picojson::value(tmpBool);
+ }
+
+ ret = media_info_get_modified_time(info, &tmpDate);
+ if(ret == MEDIA_CONTENT_ERROR_NONE) {
+ std::stringstream str_date;
+ str_date << tmpDate;
+ o.insert(std::make_pair(std::string("modifiedDate"), str_date.str()));
+ }
+}
+
+static int setContent(media_info_h media, picojson::value content) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::setContent start");
+
+ int ret;
+ std::string name = content.get("name").to_str();
+ std::string description = content.get("description").to_str();
+ std::string rating = content.get("rating").to_str();
+ std::string is_fav = content.get("isFavorite").to_str();
+
+ if (media != NULL) {
+ media_content_type_e type;
+ ret = media_info_get_media_type(media, &type);
+ if (ret != MEDIA_CONTENT_ERROR_NONE ) {
+ return ret;
+ }
+ ret = media_info_set_display_name(media, name.c_str());
+ if ( ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Updating name is failed.");
+ }
+ ret = media_info_set_description(media, description.c_str());
+ if ( ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Updating description is failed.");
+ }
+ ret = media_info_set_rating(media, std::stoi(rating));
+ if ( ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Updating rating is failed.");
+ }
+
+ if (is_fav == "true") {
+ ret = media_info_set_favorite(media, true);
+ }
+ else if (is_fav == "false") {
+ ret = media_info_set_favorite(media, false);
+ }
+
+ if ( ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Updating favorite is failed.");
+ }
+ if (type == MEDIA_CONTENT_TYPE_IMAGE || type == MEDIA_CONTENT_TYPE_VIDEO) {
+ picojson::value geo = content.get("geolocation");
+
+ double latitude = atof(geo.get("latitude").to_str().c_str());
+ double longitude = atof(geo.get("longitude ").to_str().c_str());
+ ret = media_info_set_latitude(media, latitude);
+ if ( ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Updating geolocation is failed.");
+ }
+ ret = media_info_set_longitude(media, longitude);
+ if ( ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Updating geolocation is failed.");
+ }
+ }
+ ret = MEDIA_CONTENT_ERROR_NONE;
+ }
+ else {
+ ret = MEDIA_CONTENT_ERROR_DB_FAILED;
+ }
+ return ret;
+}
+
+static bool media_foreach_directory_cb(media_folder_h folder, void *user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::media_foreach_directory_cb start");
+ std::vector<media_folder_h> *dir = static_cast<std::vector<media_folder_h>*>(user_data);
+ media_folder_h nfolder = NULL;
+ media_folder_clone (&nfolder, folder);
+ dir->push_back(nfolder);
+
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::media_foreach_directory_cb end");
+}
+
+static bool media_foreach_content_cb(media_info_h media, void *user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::media_foreach_content_cb start.");
+ picojson::value::array *contents = static_cast<picojson::value::array*>(user_data);
+ picojson::value::object o;
+
+ contentToJson(media, o);
+ contents->push_back(picojson::value(o));
+ return true;
+}
+
+static bool playlist_foreach_cb(media_playlist_h playlist, void *user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlist_foreach_cb start");
+
+ picojson::value::array *playlists = static_cast<picojson::value::array*>(user_data);
+ picojson::value::object o;
+ if (playlist != NULL) {
+ int id,cnt;
+ char* thumb_path = NULL;
+ char* name = NULL;
+ filter_h filter = NULL;
+ if( media_playlist_get_playlist_id(playlist, &id) == MEDIA_CONTENT_ERROR_NONE) {
+ std::stringstream str_id;
+ str_id << id;
+ o["id"] = picojson::value(std::to_string(id));
+ }
+ else {
+ dlog_print(DLOG_INFO, "DYKIM", "Invalid ID for playlist.");
+ }
+ if( media_playlist_get_thumbnail_path(playlist, &thumb_path) == MEDIA_CONTENT_ERROR_NONE) {
+ if (thumb_path != NULL) {
+ o["thumbnailURI"] = picojson::value(std::string(thumb_path));
+ free(thumb_path);
+ }
+ else {
+ o["thumbnailURI"] = picojson::value();//picojson::value(std::string(""));
+ }
+ }
+ else {
+ dlog_print(DLOG_INFO, "DYKIM", "Invalid thumbnail path for playlist.");
+ }
+ if( media_playlist_get_name(playlist, &name) == MEDIA_CONTENT_ERROR_NONE) {
+ o.insert(std::make_pair(std::string("name"), std::string(name)));
+ free(name);
+ }
+ else {
+ dlog_print(DLOG_INFO, "DYKIM", "Invalid name for playlist.");
+ }
+
+// media_filter_create(&filter);
+// if( media_playlist_get_media_count_from_db(id, filter, &cnt) == MEDIA_CONTENT_ERROR_NONE) {
+// std::stringstream str_cnd;
+// str_cnd << cnt;
+ o.insert(std::make_pair(std::string("numberOfTracks"), std::to_string(0)));
+// }
+// else {
+// dlog_print(DLOG_INFO, "DYKIM", "Invalid count for playlist.");
+// }
+ playlists->push_back(picojson::value(o));
+
+ }
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlist_foreach_cb end.");
+ return true;
+}
+
+static bool playlist_content_member_cb(int playlist_member_id, media_info_h media, void *user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlist_content_member_cb start.");
+
+ picojson::value::array *contents = static_cast<picojson::value::array*>(user_data);
+ picojson::value::object o;
+ char *name = NULL;
+
+ media_info_get_display_name(media, &name);
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlist_content_member_cb %s.",name);
+ o["playlist_member_id"] = picojson::value(static_cast<double>(playlist_member_id));
+ contentToJson(media, o);
+ contents->push_back(picojson::value(o));
+ return true;
+}
+
+
+ContentManager::ContentManager() {
+ LoggerE("ContentManager called");
+ if(media_content_connect() == MEDIA_CONTENT_ERROR_NONE) {
+ m_dbConnected = true;
+ }
+ else
+ m_dbConnected = false;
+}
+
+ContentManager::~ContentManager() {
+ if(m_dbConnected) {
+ if(media_content_disconnect() == MEDIA_CONTENT_ERROR_NONE) {
+ m_dbConnected = false;
+ }
+ }
+}
+
+ContentManager* ContentManager::getInstance() {
+ static ContentManager instance;
+ return &instance;
+}
+
+bool ContentManager::isConnected() {
+ return m_dbConnected;
+}
+
+void ContentManager::getDirectories(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::getDirectories start");
+
+ picojson::value::array pico_dirs;
+
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+ filter_h filter = NULL;
+ std::vector<media_folder_h> dirs;
+
+ ret = media_folder_foreach_folder_from_db(filter, media_foreach_directory_cb, &dirs);
+
+ if (ret == MEDIA_CONTENT_ERROR_NONE) {
+ for(std::vector<media_folder_h>::iterator it = dirs.begin(); it != dirs.end(); ++it) {
+ char *name = NULL;
+ char *id = NULL;
+ char *path = NULL;
+ time_t date;
+ media_content_storage_e storageType;
+ picojson::value::object o;
+
+ media_folder_get_folder_id(*it, &id);
+ media_folder_get_name(*it, &name);
+ media_folder_get_path(*it, &path);
+ media_folder_get_modified_time(*it, &date);
+ media_folder_get_storage_type(*it, &storageType);
+
+ o["id"] = picojson::value(std::string(id));
+ o["directoryURI"] = picojson::value(std::string(path));
+ o["title"] = picojson::value(std::string(name));
+
+ if (storageType == MEDIA_CONTENT_STORAGE_INTERNAL) {
+ o["storageType"] = picojson::value(std::string("INTERNAL"));
+ } else if (storageType == MEDIA_CONTENT_STORAGE_EXTERNAL) {
+ o["storageType"] = picojson::value(std::string("EXTERNAL"));
+ }
+
+ char tmp[128];
+ ctime_r(&date, tmp);
+ o["modifiedDate"] = picojson::value(std::string(tmp));
+ pico_dirs.push_back(picojson::value(o));
+
+ free(name);
+ free(id);
+ free(path);
+ }
+ user_data->isSuccess = true;
+ user_data->result = picojson::value(pico_dirs);
+ }
+ else {
+ UnknownException err("Getting the directories is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+
+}
+
+void ContentManager::find(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::find start");
+ int ret;
+ double count, offset;
+ std::string dirId, attributeName, matchFlag, matchValue;
+ std::string sortModeName, sortModeOrder;
+ media_content_order_e order;
+
+ picojson::value::array arrayContent;
+ filter_h filter = NULL;
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::find start1");
+ ret = media_filter_create(&filter);
+
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("Memory allcation for filter is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+ if(user_data->args.contains("filter")) {
+ //dykim. filter
+ picojson::value vfilter = user_data->args.get("filter");
+ if (!vfilter.is<picojson::null>() && vfilter.is<picojson::object>()) {
+ attributeName = vfilter.get("attributeName").to_str();
+ matchFlag = vfilter.get("matchFlag").to_str();
+ matchValue = vfilter.get("matchValue").to_str();
+ }
+ }
+ if(user_data->args.contains("sortMode")) {
+ picojson::value vSortMode = user_data->args.get("sortMode");
+ if (!vSortMode.is<picojson::null>() && vSortMode.is<picojson::object>()) {
+ sortModeName = vSortMode.get("attributeName").to_str();
+ sortModeOrder = vSortMode.get("order").to_str();
+ if ( !sortModeOrder.empty() ) {
+ if( sortModeOrder == "ASC" ) {
+ order = MEDIA_CONTENT_ORDER_ASC;
+ }
+ else if( sortModeOrder == "DESC" ) {
+ order = MEDIA_CONTENT_ORDER_DESC;
+ }
+ ret = media_filter_set_order(filter, order, sortModeName.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT );
+ if (MEDIA_CONTENT_ERROR_NONE != ret )
+ {
+ LoggerD("Platform SortMode setting is failed.");
+ }
+ }
+ }
+ }
+ if(user_data->args.contains("count")) {
+ count = user_data->args.get("count").get<double>();
+ }
+ else {
+ count = -1;
+ }
+ if(user_data->args.contains("offset")) {
+ offset = user_data->args.get("offset").get<double>();
+ }
+ else {
+ offset = -1;
+ }
+ ret = media_filter_set_offset(filter, offset, count);
+ if ( MEDIA_CONTENT_ERROR_NONE != ret) {
+ LoggerD("A platform error occurs in media_filter_set_offset.");
+ }
+ if(user_data->args.contains("directoryId")) {
+ dirId = user_data->args.get("directoryId").get<std::string>();
+ ret = media_folder_foreach_media_from_db(dirId.c_str(), filter, media_foreach_content_cb, static_cast<void*>(&arrayContent));
+ }
+ else {
+ ret = media_info_foreach_media_from_db(filter, media_foreach_content_cb, static_cast<void*>(&arrayContent));
+ }
+ media_filter_destroy(filter);
+
+ if (ret == MEDIA_CONTENT_ERROR_NONE) {
+ user_data->isSuccess = true;
+ user_data->result = picojson::value(arrayContent);
+ }
+ else {
+ UnknownException err("The iteration is failed in platform.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+}
+
+int ContentManager::scanFile(std::string& uri) {
+ return media_content_scan_file(uri.c_str());
+}
+
+int ContentManager::setChangeListener(media_content_db_update_cb callback, void *user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::setChangeListener start");
+
+ int ret = media_content_set_db_updated_cb(callback, user_data);
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ throw UnknownException("registering the listener is failed.");
+ }
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::media_content_db_update_cb end");
+}
+
+void ContentManager::unSetChangeListener() {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::unSetChangeListener start");
+ int ret = media_content_unset_db_updated_cb();
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ throw UnknownException("unSetChangeListener is failed.");
+ }
+}
+
+void ContentManager::createPlaylist(std::string name,
+ const std::shared_ptr<ReplyCallbackData>& user_data) {
+
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::createPlaylist start");
+ media_playlist_h playlist = NULL;
+
+ int ret = media_playlist_insert_to_db(name.c_str(),&playlist);
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("creation of playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+ picojson::value::object o;
+
+ if( playlist != NULL) {
+ int id,cnt;
+ char* thumb_path = NULL;
+ char* name = NULL;
+ filter_h filter = NULL;
+ if( media_playlist_get_playlist_id(playlist, &id) == MEDIA_CONTENT_ERROR_NONE) {
+ o.insert(std::make_pair(std::string("id"), std::to_string(id)));
+ }
+ else {
+ UnknownException err("loading of playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+ if( media_playlist_get_thumbnail_path(playlist, &thumb_path) == MEDIA_CONTENT_ERROR_NONE) {
+ if (thumb_path != NULL) {
+ o["thumbnailURI"] = picojson::value(std::string(thumb_path));
+ free(thumb_path);
+ }
+ else {
+ o["thumbnailURI"] = picojson::value();
+ }
+ }
+ else {
+ dlog_print(DLOG_INFO, "DYKIM", "Invalid thumbnail path for playlist.");
+ }
+ if( media_playlist_get_name(playlist, &name) == MEDIA_CONTENT_ERROR_NONE) {
+ o["name"] = picojson::value(std::string(name));
+ free(name);
+ }
+ else {
+ dlog_print(DLOG_INFO, "DYKIM", "Invalid name for playlist.");
+ }
+ media_filter_create(&filter);
+ if( media_playlist_get_media_count_from_db(id, filter, &cnt) == MEDIA_CONTENT_ERROR_NONE) {
+ o["numberOfTracks"] = picojson::value(static_cast<double>(cnt));
+ }
+ else {
+ dlog_print(DLOG_INFO, "DYKIM", "Invalid count for playlist.");
+ }
+ }
+ user_data->isSuccess = true;
+ user_data->result = picojson::value(o);
+
+}
+
+void ContentManager::getPlaylists(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::getPlaylist start");
+ int ret;
+ filter_h filter;
+ media_filter_create(&filter);
+ picojson::value::array playlists;
+
+ ret = media_playlist_foreach_playlist_from_db(filter, playlist_foreach_cb, static_cast<void*>(&playlists));
+
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("Getting playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+ user_data->isSuccess = true;
+ user_data->result = picojson::value(playlists);
+}
+
+void ContentManager::removePlaylist(std::string playlistId,
+ const std::shared_ptr<ReplyCallbackData>& user_data) {
+
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::removePlaylist start");
+ int id = std::stoi(playlistId);
+ int ret = media_playlist_delete_from_db(id);
+
+ if(ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("Removal of playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+}
+
+int ContentManager::update(picojson::value args) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::update start");
+
+ int ret;
+ picojson::value content = args.get("content");
+ std::string id = content.get("id").to_str();
+
+ media_info_h media = NULL;
+ ret = media_info_get_media_from_db (id.c_str(), &media);
+ if (media != NULL) {
+ setContent(media, content);
+ ret = media_info_update_to_db(media);
+ }
+ else {
+ LoggerD("There is no content(%s)",id.c_str());
+ ret = MEDIA_CONTENT_ERROR_NONE;
+ }
+ return ret;
+}
+
+
+int ContentManager::updateBatch(picojson::value args) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::updateBatch start");
+
+ int ret;
+ std::vector<picojson::value> contents = args.get("contents").get<picojson::array>();
+ for (picojson::value::array::iterator it = contents.begin(); it != contents.end(); it++) {
+ picojson::value content = *it;
+ std::string id = content.get("id").to_str();
+ media_info_h media = NULL;
+ ret = media_info_get_media_from_db (id.c_str(), &media);
+ if (media != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
+ setContent(media, content);
+ ret = media_info_update_to_db(media);
+ }
+ else {
+ return ret;
+ }
+ }
+ return ret;
+}
+
+
+
+int ContentManager::playlistAdd(std::string playlist_id, std::string content_id) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistAdd start");
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+
+ media_playlist_h playlist = NULL;
+ ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
+
+ if (playlist != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
+ ret = media_playlist_add_media(playlist, content_id.c_str());
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("The content(id:%s) can't add to playlist",content_id.c_str());
+ }
+
+ ret = media_playlist_update_to_db(playlist);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("The content(id:%s) can't add to playlist",content_id.c_str());
+ }
+ }
+ else {
+ LoggerD("Playlist(id:%s) is not exist",playlist_id.c_str());
+ }
+
+ media_playlist_destroy(playlist);
+ return ret;
+}
+
+int ContentManager::playlistRemove(std::string playlist_id, int member_id) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistRemove start");
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+
+ media_playlist_h playlist = NULL;
+ ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistRemove member_id(%d)", member_id);
+ if (playlist != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
+ ret = media_playlist_remove_media(playlist, member_id);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("The content can't remove to playlist");
+ }
+
+ ret = media_playlist_update_to_db(playlist);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("The content can't remove to playlist");
+ }
+ }
+ else {
+ LoggerD("Playlist(id:%s) is not exist",playlist_id.c_str());
+ }
+ media_playlist_destroy(playlist);
+
+ return ret;
+}
+
+
+void ContentManager::playlistAddbatch(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistAddbatch start");
+
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+ std::string playlist_id = user_data->args.get("playlist_id").get<std::string>();
+
+ media_playlist_h playlist = NULL;
+ ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
+
+ if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
+ UnknownException err("Getting playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ std::vector<picojson::value> contents = user_data->args.get("contents").get<picojson::array>();
+ for (picojson::value::array::iterator it = contents.begin(); it != contents.end(); it++) {
+ picojson::value content = *it;
+ std::string id = content.get("id").to_str();
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistAddbatch id(%s)",id.c_str());
+ ret = media_playlist_add_media(playlist, id.c_str());
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ dlog_print(DLOG_INFO, "DYKIM", "Adding Content(id:%s) is failed.", id.c_str());
+ }
+ }
+
+ ret = media_playlist_update_to_db(playlist);
+ if(ret != MEDIA_CONTENT_ERROR_NONE ) {
+ UnknownException err("Adding playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+ media_playlist_destroy(playlist);
+}
+
+void ContentManager::playlistGet(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistGet start");
+
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+ media_playlist_h playlist = NULL;
+
+ std::string playlist_id = user_data->args.get("playlist_id").get<std::string>();
+ ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
+ if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
+ UnknownException err("Getting playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ filter_h filter = NULL;
+ ret = media_filter_create(&filter);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("Creating a filter is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ int count = user_data->args.get("count").get<double>();
+ int offset = user_data->args.get("offset").get<double>();
+ ret = media_filter_set_offset(filter, offset, count);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Setting a offset/count is failed.");
+ }
+ picojson::value::array arrayContent;
+ ret = media_playlist_foreach_media_from_db(std::stoi(playlist_id),
+ filter, playlist_content_member_cb, static_cast<void*>(&arrayContent));
+
+ media_filter_destroy(filter);
+ if (ret == MEDIA_CONTENT_ERROR_NONE) {
+ user_data->isSuccess = true;
+ user_data->result = picojson::value(arrayContent);
+ }
+ else {
+ UnknownException err("Creating a filter is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistGet start7");
+}
+
+void ContentManager::playlistRemovebatch(const std::shared_ptr<ReplyCallbackData>& user_data) {
+
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistRemovebatch start");
+
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+ media_playlist_h playlist = NULL;
+
+ std::string playlist_id = user_data->args.get("playlist_id").get<std::string>();
+ ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
+ if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
+ UnknownException err("Getting playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ std::vector<picojson::value> members = user_data->args.get("members").get<picojson::array>();
+ for( int i = 0; i < members.size(); i++ ) {
+ int member_id = static_cast<int>(members.at(i).get<double>());
+ ret = media_playlist_remove_media(playlist, member_id);
+
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Removing a content is failed.");
+ }
+ }
+
+ ret = media_playlist_update_to_db(playlist);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("Removing the contents is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+ else {
+ user_data->isSuccess = true;
+ }
+}
+
+void ContentManager::playlistSetOrder(const std::shared_ptr<ReplyCallbackData>& user_data) {
+
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistSetOrder start");
+
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+ media_playlist_h playlist = NULL;
+
+ std::string playlist_id = user_data->args.get("playlist_id").get<std::string>();
+ ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
+ if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
+ UnknownException err("Getting playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ int cnt;
+ std::vector<picojson::value> members = user_data->args.get("members").get<picojson::array>();
+
+ ret = media_playlist_get_media_count_from_db(std::stoi(playlist_id), NULL, &cnt);
+
+ if ( cnt != members.size() ) {
+ InvalidValuesException err("The items array does not contain all items from the playlist.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ for( int i = 0; i < members.size(); i++ ) {
+ int member_id = static_cast<int>(members.at(i).get<double>());
+ ret = media_playlist_set_play_order(playlist, member_id, i);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ LoggerD("Removing a content is failed.");
+ }
+ }
+
+ ret = media_playlist_update_to_db(playlist);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("Removing the contents is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+ else {
+ user_data->isSuccess = true;
+ }
+}
+
+void ContentManager::playlistMove(const std::shared_ptr<ReplyCallbackData>& user_data) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::playlistMove start");
+
+ int ret = MEDIA_CONTENT_ERROR_NONE;
+ media_playlist_h playlist = NULL;
+
+ std::string playlist_id = user_data->args.get("playlist_id").get<std::string>();
+ ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
+ if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
+ UnknownException err("Getting playlist is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+ int old_order;
+ double member_id = user_data->args.get("member_id").get<double>();
+ long delta = user_data->args.get("delta").get<long>();
+ ret = media_playlist_get_play_order(playlist, static_cast<int>(member_id), &old_order);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("The content can't find form playlist.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ int new_order = static_cast<int>(old_order) + static_cast<int>(delta);
+ ret = media_playlist_set_play_order(playlist, static_cast<int>(member_id), new_order);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("The content can't update play_order.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ return;
+ }
+
+ ret = media_playlist_update_to_db(playlist);
+ if (ret != MEDIA_CONTENT_ERROR_NONE) {
+ UnknownException err("Updateing play_order is failed.");
+ user_data->isSuccess = false;
+ user_data->result = err.ToJSON();
+ }
+ else {
+ user_data->isSuccess = true;
+ }
+}
+
+int ContentManager::getLyrics(const picojson::value& args, picojson::object& result) {
+
+ int ret = METADATA_EXTRACTOR_ERROR_NONE;
+ std::string contentURI = convertUriToPath(args.get("contentURI").get<std::string>());
+ metadata_extractor_h extractor;
+
+ if (!(contentURI.empty())) {
+ ret = metadata_extractor_set_path(extractor, contentURI.c_str());
+ if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+ return -1;
+ }
+ picojson::array timestamps;
+ picojson::array texts;
+ char* strSyncTextNum=NULL;
+ metadata_extractor_attr_e attr = METADATA_SYNCLYRICS_NUM;
+ ret = metadata_extractor_get_metadata(extractor, attr, &strSyncTextNum);
+ if (ret = METADATA_EXTRACTOR_ERROR_NONE && strSyncTextNum ) {
+ int nSyncTextNum = atoi(strSyncTextNum);
+ free(strSyncTextNum);
+ strSyncTextNum = NULL;
+ if (nSyncTextNum > 0) {
+ result["type"] = picojson::value(std::string("SYNCHRONIZED"));
+ for(int i=0; i < nSyncTextNum; i++) {
+ unsigned long time_info = 0;
+ char * lyrics = NULL;
+ ret = metadata_extractor_get_synclyrics(extractor, i, &time_info, &lyrics);
+ if (ret == METADATA_EXTRACTOR_ERROR_NONE) {
+ timestamps.push_back(picojson::value(static_cast<double>(time_info)));
+ texts.push_back(picojson::value(std::string(lyrics)));
+ free(lyrics);
+ }
+ }
+ result["texts"] = picojson::value(texts);
+ result["timestamps"] = picojson::value(timestamps);
+ ret = METADATA_EXTRACTOR_ERROR_NONE;
+ }
+ else {
+ char* unSyncText = NULL;
+ attr = METADATA_UNSYNCLYRICS;
+ ret = metadata_extractor_get_metadata(extractor, attr, &unSyncText);
+ if (ret == METADATA_EXTRACTOR_ERROR_NONE) {
+ result["type"] = picojson::value(std::string("UNSYNCHRONIZED"));
+ texts.push_back(picojson::value(std::string(unSyncText)));
+ result["texts"] = picojson::value(texts);
+ free(unSyncText);
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+
+common::PlatformException ContentManager::convertError(int err) {
+ dlog_print(DLOG_INFO, "DYKIM", "ContentManager::convertError start");
+ switch (err) {
+ case MEDIA_CONTENT_ERROR_INVALID_PARAMETER :
+ return common::InvalidValuesException("Invalid parameter.");
+ case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY :
+ return common::UnknownException("Out of memory.");
+ case MEDIA_CONTENT_ERROR_INVALID_OPERATION :
+ return common::UnknownException("Invalid Operation.");
+ case MEDIA_CONTENT_FILE_NO_SPACE_ON_DEVICE :
+ return common::UnknownException("No space left on device.");
+ case MEDIA_CONTENT_ERROR_PERMISSION_DENIED :
+ return common::UnknownException("Permission denied.");
+ case MEDIA_CONTENT_ERROR_DB_FAILED :
+ return common::UnknownException("DB operation failed.");
+ case MEDIA_CONTENT_ERROR_DB_BUSY :
+ return common::UnknownException("DB operation BUSY.");
+ case MEDIA_CONTENT_ERROR_NETWORK :
+ return common::UnknownException("Network Fail.");
+ case MEDIA_CONTENT_ERROR_UNSUPPORTED_CONTENT :
+ return common::UnknownException("Unsupported Content.");
+ default:
+ return common::UnknownException("Unknown error.");
+ }
+}
+
+} // namespace content
+} // namespace extension
+
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. 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_MANAGER_H_
+#define CONTENT_MANAGER_H_
+
+#include "common/extension.h"
+#include "common/picojson.h"
+#include "common/platform_exception.h"
+
+#include <string>
+#include <list>
+#include <media_content.h>
+#include <glib.h>
+
+#include "content_instance.h"
+
+namespace extension {
+namespace content {
+
+class ContentManager {
+ public:
+ virtual ~ContentManager();
+ bool isConnected();
+ static ContentManager* getInstance();
+
+ void getDirectories(const std::shared_ptr<ReplyCallbackData>& user_data);
+ void find(const std::shared_ptr<ReplyCallbackData>& user_data);
+ int update(picojson::value args);
+ int updateBatch(picojson::value args);
+ void contentToJson(media_info_h media, picojson::object& o);
+ //directorytoJson
+
+ int scanFile(std::string& uri);
+ int setChangeListener(media_content_db_update_cb callback, void *user_data);
+ void unSetChangeListener();
+
+//Lyrics
+ int getLyrics(const picojson::value& args,picojson::object& result);
+
+//playlist
+ void createPlaylist(std::string name, const std::shared_ptr<ReplyCallbackData>& user_data);
+ void getPlaylists(const std::shared_ptr<ReplyCallbackData>& user_data);
+ void removePlaylist(std::string playlistId, const std::shared_ptr<ReplyCallbackData>& user_data);
+ int playlistAdd(std::string playlist_id, std::string content_id);
+ int playlistRemove(std::string playlist_id, int member_id);
+ void playlistAddbatch(const std::shared_ptr<ReplyCallbackData>& user_data);
+ void playlistGet(const std::shared_ptr<ReplyCallbackData>& user_data);
+ void playlistRemovebatch(const std::shared_ptr<ReplyCallbackData>& user_data);
+ void playlistSetOrder(const std::shared_ptr<ReplyCallbackData>& user_data);
+ void playlistMove(const std::shared_ptr<ReplyCallbackData>& user_data);
+
+//playlistSetOrder
+ common::PlatformException convertError(int err);
+ private:
+ //int setContent(media_info_h media, picojson::value content);
+ ContentManager();
+
+ private:
+ bool m_dbConnected;
+
+};
+
+} // namespace power
+} // namespace extension
+
+#endif
+
'exif/exif.gyp:*',
'websetting/websetting.gyp:*',
'systemsetting/systemsetting.gyp:*',
+ 'content/content.gyp:*',
],
'conditions': [
[