GROUP: 'GROUP'
};
+var ApplicationUsageMode = {
+ RECENTLY: 'RECENTLY',
+ FREQUENTLY: 'FREQUENTLY'
+};
+
// TODO: Please uncomment below lines when system events is ready
//var SystemEvent = {
// BATTERY_CHARGER_STATUS: 'BATTERY_CHARGER_STATUS',
}
};
+ApplicationManager.prototype.getAppsUsageInfo = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name: 'successCallback',
+ type: AV.Types.FUNCTION
+ },
+ {
+ name: 'errorCallback',
+ type: AV.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'mode',
+ type: AV.Types.ENUM,
+ values: T.getValues(ApplicationUsageMode),
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'filter',
+ type: AV.Types.DICTIONARY,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'limit',
+ type: AV.Types.LONG,
+ optional: true,
+ nullable: true
+ }]);
+
+ var callArgs = {};
+
+ if (!T.isNullOrUndefined(args.mode)) {
+ callArgs.mode = args.mode;
+ }
+
+ if (!T.isNullOrUndefined(args.filter) && typeof args.filter !== 'object') {
+ setTimeout(function() {
+ native.callIfPossible(args.errorCallback,
+ new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+ 'filter must be an object.'));
+ }, 0);
+ return;
+ }
+
+ callArgs.filter = {};
+ if (!T.isNullOrUndefined(args.filter)) {
+ var filter = args.filter;
+ if (!T.isNullOrUndefined(filter.timeSpan)) {
+ callArgs.filter.timeSpan = Converter.toLong(filter.timeSpan);
+ } else {
+ if (!T.isNullOrUndefined(filter.startTime)) {
+ if (filter.startTime instanceof Date) {
+ callArgs.filter.startTime = filter.startTime.getTime() / 1000;
+ } else {
+ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR,
+ 'startTime given with invalid type.');
+ }
+ }
+
+ if (!T.isNullOrUndefined(filter.endTime)) {
+ if (filter.endTime instanceof Date) {
+ callArgs.filter.endTime = filter.endTime.getTime() / 1000;
+ } else {
+ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR,
+ 'endTime given with invalid type.');
+ }
+ }
+ }
+ }
+
+ if (!T.isNullOrUndefined(args.limit)) {
+ callArgs.limit = args.limit;
+ }
+
+ var callback = function(result) {
+ if (native.isFailure(result)) {
+ native.callIfPossible(args.errorCallback, native.getErrorObject(result));
+ } else {
+ var data = native.getResultObject(result);
+ var resultArray = [];
+ data.forEach(function(i) {
+ resultArray.push(new ApplicationUsage(i));
+ });
+ args.successCallback(resultArray);
+ }
+ };
+
+ var result = native.call('ApplicationManager_getAppsUsageInfo', callArgs, callback);
+ if (native.isFailure(result)) {
+ throw native.getErrorObject(result);
+ }
+};
+
function ListenerManager(native, listenerName) {
this.listeners = {};
this.nextId = 1;
});
}
+//class ApplicationUsage ////////////////////////////////////////////////////////
+function ApplicationUsage(data) {
+ Object.defineProperties(this, {
+ appId : {
+ value : data.appId,
+ writable : false,
+ enumerable : true
+ },
+ totalCount : {
+ value : data.totalCount,
+ writable : false,
+ enumerable : true
+ },
+ totalDuration : {
+ value : data.totalDuration,
+ writable : false,
+ enumerable : true
+ },
+ lastTime : {
+ value : new Date(data.lastTime * 1000),
+ writable : false,
+ enumerable : true
+ }
+ });
+}
+
// exports ////////////////////////////////////////////////////
exports = new ApplicationManager();
const std::string kAppId = "appId";
const std::string kListenerId = "listenerId";
const std::string kAppStatusChangeListener = "AppStatusChangeListener";
+const std::string kAppUsageModeFrequently = "FREQUENTLY";
+const std::string kAppUsageModeRecently = "RECENTLY";
const std::map<std::string, std::string> event_map_ = {
{SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
};
#ifdef TIZEN_MOBILE
-const int kMaximumRetrievedObjects = 30;
+const int kMaximumBatteryRetrievedObjects = 30;
+const int kMaximumAppsRetrievedObjects = 10;
+const int kDefaultPeriodOfTime = 30;
#endif
}
context_history_data_e* data_type_out) {
LoggerD("Entered");
int ret = CONTEXT_HISTORY_ERROR_NONE;
- int limit = kMaximumRetrievedObjects;
+ int limit = kMaximumBatteryRetrievedObjects;
if (args.contains("limit")) {
limit = static_cast<int>(args.get("limit").get<double>());
}
return PlatformResult(ErrorCode::NO_ERROR);
}
+
+PlatformResult ApplicationManager::AppsUsageFilter(const picojson::value& args,
+ const context_history_filter_h filter,
+ context_history_data_e* data_type_out) {
+ LoggerD("Entered");
+ int ret = CONTEXT_HISTORY_ERROR_NONE;
+ int limit = kMaximumAppsRetrievedObjects;
+ if (args.contains("limit")) {
+ limit = static_cast<int>(args.get("limit").get<double>());
+ }
+
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
+ ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ context_history_data_e data_type_in = CONTEXT_HISTORY_FREQUENTLY_USED_APP;
+ if (args.contains("mode") && kAppUsageModeRecently == args.get("mode").get<std::string>()) {
+ data_type_in = CONTEXT_HISTORY_RECENTLY_USED_APP;
+ }
+
+ int time_span = kDefaultPeriodOfTime;
+ const picojson::object &JS_filter = args.get("filter").get<picojson::object>();
+ auto time_span_iter = JS_filter.find("timeSpan");
+ if (JS_filter.end() != time_span_iter
+ || (JS_filter.end() == JS_filter.find("startTime")
+ && JS_filter.end() == JS_filter.find("endTime"))) {
+ //In the second case, we treat the filter object just like an empty object.
+ //The default value of filter will be used instead.
+ if (JS_filter.end() != time_span_iter) {
+ time_span = static_cast<int>(time_span_iter->second.get<double>());
+ }
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, time_span);
+ //context_history_filter_set_int may return only success or CONTEXT_HISTORY_ERROR_INVALID_PARAMETER
+ //Although this should never happen, it's better to check ret's value
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::ABORT_ERR, "Error while setting the default TIME_SPAN value.",
+ ("Error while setting the default TIME_SPAN value: %d (%s)", ret, get_error_message(ret)));
+ }
+ } else {
+ auto start_time_iter = JS_filter.find("startTime");
+ auto end_time_iter = JS_filter.find("endTime");
+ if (start_time_iter != JS_filter.end()) {
+ int start_time = static_cast<int>(start_time_iter->second.get<double>());
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_START_TIME, start_time);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "startTime given with invalid value.",
+ ("startTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+ }
+ if (end_time_iter != JS_filter.end()) {
+ int end_time = static_cast<int>(end_time_iter->second.get<double>());
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_END_TIME, end_time);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "endTime given with invalid value.",
+ ("endTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+ }
+ }
+
+ *data_type_out = data_type_in;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_record_h record,
+ picojson::object* object) {
+ LoggerD("Entered");
+
+ int ret = CONTEXT_HISTORY_ERROR_NONE;
+ int total_count = 0;
+ int total_duration = 0;
+ int last_time = 0;
+ char* app_id = nullptr;
+ SCOPE_EXIT {
+ free(app_id);
+ };
+
+ ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
+ ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_COUNT, &total_count);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get total count.",
+ ("Failed to get total count: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_DURATION, &total_duration);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::ABORT_ERR, "Failed to get total duration.",
+ ("Failed to get total duration: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_record_get_int(record, CONTEXT_HISTORY_LAST_TIME, &last_time);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get last time.",
+ ("Failed to get last time: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ object->insert(std::make_pair("appId", picojson::value(app_id)));
+ object->insert(std::make_pair("totalCount", picojson::value(static_cast<double>(total_count))));
+ object->insert(
+ std::make_pair("totalDuration", picojson::value(static_cast<double>(total_duration))));
+ object->insert(std::make_pair("lastTime", picojson::value(static_cast<double>(last_time))));
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
#endif
void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
#endif
}
+void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
+ LoggerD("Entered");
+
+#ifdef TIZEN_MOBILE
+ int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
+
+ auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response)-> void {
+ LoggerD("Entered");
+ PlatformResult result = ApplicationManager::GetContextHistory(args, &response.get()->get<picojson::object>(),
+ &ApplicationManager::AppsUsageFilter,
+ &ApplicationManager::AppsUsageAttributes);
+ if (!result) {
+ LogAndReportError(result, &response.get()->get<picojson::object>());
+ }
+ };
+
+ auto get_apps_usage_response = [this, callback_id](
+ const std::shared_ptr<picojson::value>& response) -> void {
+ LoggerD("Entered");
+ picojson::object& obj = response->get<picojson::object>();
+ obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
+ Instance::PostMessage(&this->instance_, response->serialize().c_str());
+ };
+
+ auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
+ TaskQueue::GetInstance().Queue<picojson::value>(
+ get_apps_usage,
+ get_apps_usage_response,
+ data);
+#else
+ // Context API is supported only for mobile profile, other ones would result with NotSupportedError
+ LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "This feature is not supported on this profile."), out,
+ ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
+#endif
+}
+
void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) {
LoggerD("Entered");