case CompNotifyDataUpdate :
ret = "__COMP_NOTIFY_DATA_UPDATE__";
break;
+ case CompNotifyListeningStatus :
+ ret = "__COMP_NOTIFY_LISTENING_STATUS__";
+ break;
case EditableEditRequest :
ret = "__EDITABLE_EDIT_REQUEST__";
break;
CompUpdateRequest,
CompUpdated,
CompNotifyDataUpdate,
+ CompNotifyListeningStatus,
EditableEditRequest,
EditableEditComplete,
EditableEditPreview,
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/watchface-complication-provider.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/watchface-complication-provider-internal.h DESTINATION include/${PROJECT_NAME})
int CheckPrivilege(std::list<std::string>& required_privileges,
GDBusConnection* connection);
bool CheckAppid(const std::string& Appid);
+ const std::string& GetAppid() const;
int GetWatcherID();
std::string& GetWatchName();
cynara_result GetPrivilegeResult();
void SetPrivilegeResult(cynara_result result);
+ int GetListeningCount() const;
+ void SetListeningCount(int count);
private:
std::string sender_name_;
std::string watch_name_;
std::list<std::string> sender_privileges_;
cynara_result privilege_result_;
+ int listening_count_ = 0;
};
SenderInfo* GetSenderInfo(std::string sender_name,
GDBusConnection* connection, GVariant* parameters);
return false;
}
+const std::string& ComplicationProvider::Impl::SenderInfo::GetAppid() const {
+ return sender_app_id_;
+}
+
int ComplicationProvider::Impl::SenderInfo::GetWatcherID() {
return watcher_id_;
}
+int ComplicationProvider::Impl::SenderInfo::GetListeningCount() const {
+ return listening_count_;
+}
+
+void ComplicationProvider::Impl::SenderInfo::SetListeningCount(int count) {
+ listening_count_ = count;
+}
+
std::string& ComplicationProvider::Impl::SenderInfo::GetWatchName() {
return watch_name_;
}
for (; iter != sender_info_.end(); iter++) {
SenderInfo* si = iter->second;
if (watch_name.compare(si->GetWatchName()) == 0) {
+ if (si->GetListeningCount() > 0)
+ parent_->OnConsumerStatusChange(si->GetAppid(),
+ WATCHFACE_COMPLICATION_CONSUMER_LISTENING_STOP);
+
gdbus_.get()->UnWatch(si->GetWatcherID());
sender_info_.erase(iter);
delete si;
LOGE("Exception bad_alloc");
return;
}
+ } else if(signal_name.compare(util::GetCmdStr(
+ util::CmdType::CompNotifyListeningStatus)) == 0) {
+ watchface_complication_consumer_status_e state;
+ int type;
+ char* sender_app_id = nullptr;
+ g_variant_get(parameters, "(&sii)", &sender_app_id, &type, &state);
+
+ if (si->CheckAppid(sender_app_id) == false) {
+ LOGE("invaild app id [%s]", sender_app_id);
+ return;
+ }
+
+ if (!util::CheckComplicationType(static_cast<int>(type))) {
+ LOGE("invaild type [%d]", type);
+ return;
+ }
+
+ if ((supported_types_ & type) == 0) {
+ LOGE("Not supported type [%d][%d]", supported_types_, type);
+ return;
+ }
+
+ int listening_count = si->GetListeningCount();
+
+ if (state == WATCHFACE_COMPLICATION_CONSUMER_LISTENING_START)
+ listening_count++;
+ else
+ listening_count--;
+
+ si->SetListeningCount(listening_count);
+
+ if ((state == WATCHFACE_COMPLICATION_CONSUMER_LISTENING_START && listening_count == 1)
+ || (state == WATCHFACE_COMPLICATION_CONSUMER_LISTENING_STOP && listening_count == 0))
+ parent_->OnConsumerStatusChange(sender_app_id, state);
+
}
}
void ComplicationProvider::OnDataUpdateRequest(const std::string& sender_appid,
ComplicationType type, const Bundle& context, Bundle* shared_data) {
}
+
+void ComplicationProvider::OnConsumerStatusChange(const std::string& sender_appid,
+ watchface_complication_consumer_status_e status) {
+}
+
/* LCOV_EXCL_STOP */
const std::string& ComplicationProvider::GetProviderId() const {
ComplicationType type,
const tizen_base::Bundle& context,
tizen_base::Bundle* shared_data) override;
+ void OnConsumerStatusChange(const std::string& sender_appid,
+ watchface_complication_consumer_status_e status) override;
int NotifyDataUpdate();
const std::string& GetProviderId() const;
#include <tizen.h>
#include <bundle.h>
-#include <watchface-complication-provider.h>
+#include <watchface-common.h>
#ifdef __cplusplus
extern "C" {
int watchface_complication_provider_data_set_image_path_with_aod(
bundle *shared_data, const char *image_path, const char *aod_image_path);
+
+typedef enum _watchface_complication_consumer_status {
+ WATCHFACE_COMPLICATION_CONSUMER_LISTENING_START = 0x1,
+ WATCHFACE_COMPLICATION_CONSUMER_LISTENING_STOP = 0x2
+} watchface_complication_consumer_status_e;
+
+typedef void (*watchface_complication_consumer_status_cb)(const char *provider_id,
+ const char *request_appid, watchface_complication_consumer_status_e status, void *user_data);
+
+void watchface_complication_provider_set_consumer_status_cb(
+ watchface_complication_consumer_status_cb callback, void *user_data);
+
#ifdef __cplusplus
}
#endif
#include "watchface-common/watchface-common-internal.h"
#include "watchface-complication-provider/complication-provider.h"
#include "watchface-complication-provider/include/watchface-complication-provider.h"
+#include "watchface-complication-provider/include/watchface-complication-provider-internal.h"
#include "watchface-complication/db-manager.h"
#include "watchface-complication/complication-internal.h"
GetProviderId().c_str(), sender_appid.c_str());
}
+ void OnConsumerStatusChange(const std::string& sender_appid,
+ watchface_complication_consumer_status_e status) override {
+ if (status_cb_ == nullptr)
+ return;
+
+ LOGI("ConsumerStatusChange call done provider(%s) sender(%s) %d ",
+ GetProviderId().c_str(), sender_appid.c_str(), status);
+
+ status_cb_(GetProviderId().c_str(), sender_appid.c_str(), status, user_data_);
+ }
+
int AddCallbackInfo(unique_ptr<CallbackInfo> ci) {
for (auto& i : cb_list_) {
if (i.get()->GetCallback() == ci->GetCallback()) {
return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
}
+ void SetStatusCallback(watchface_complication_consumer_status_cb cb, void* user_data) {
+ status_cb_ = cb;
+ user_data_ = user_data;
+ }
+
private:
std::list<std::unique_ptr<CallbackInfo>> cb_list_;
+ watchface_complication_consumer_status_cb status_cb_ = nullptr;
+ void* user_data_ = nullptr;
};
static std::map<std::string, WatchComplicationProviderStub*> __providers;
+static watchface_complication_consumer_status_cb __status_cb;
+static void* __user_data;
+
extern "C" EXPORT_API int watchface_complication_provider_add_update_requested_cb(
const char* provider_id,
watchface_complication_provider_update_requested_cb cb,
return WATCHFACE_COMPLICATION_ERROR_OUT_OF_MEMORY;
}
+ if (__status_cb != nullptr)
+ ws->SetStatusCallback(__status_cb, __user_data);
+
return ws->AddCallbackInfo(move(ci));
}
return ws->RemoveCallbackInfo(cb);
}
+extern "C" EXPORT_API void watchface_complication_provider_set_consumer_status_cb(
+ watchface_complication_consumer_status_cb callback, void *user_data) {
+ __status_cb = callback;
+ __user_data = user_data;
+
+ for (auto& i : __providers)
+ i.second->SetStatusCallback(callback, user_data);
+}
+
extern "C" EXPORT_API int watchface_complication_provider_notify_update(
const char* updated_provider_id) {
if (!watchface_complication::util::CheckWatchFeatureEnabled())
#include <string>
#include "watchface-complication/complication-internal.h"
+#include "watchface-complication-provider/include/watchface-complication-provider-internal.h"
namespace watchface_complication {
ComplicationType type,
const tizen_base::Bundle& context,
tizen_base::Bundle* shared_data) = 0;
+ virtual void OnConsumerStatusChange(const std::string& sender_appid,
+ watchface_complication_consumer_status_e status) = 0;
};
} // namespace watchface_complication
std::unique_ptr<IPackageManager> package_;
EditablesManager& editables_manager_;
bool mock_ = false;
+ bool is_provider_ready_ = false;
+ int listening_status_ = 0;
};
} // namespace watchface_complication
#include "watchface-common/watchface-util.h"
#include "watchface-common/watchface-common-internal.h"
#include "watchface-complication/complication-internal.h"
+#include "watchface-complication/include/watchface-complication-internal.h"
#include <iostream>
LOGI("It's not mine %s", provider_id);
return;
}
- parent_->SendDataUpdateRequest(false);
+
+ is_provider_ready_ = true;
+
+ if (listening_status_ == WATCHFACE_COMPLICATION_CONSUMER_LISTENING_START)
+ parent_->NotifyListeningStatus(WATCHFACE_COMPLICATION_CONSUMER_LISTENING_START);
+ else
+ LOGI("Not exist registered callback %s", provider_id);
}
void Complication::Impl::OnSignal(GDBusConnection* connection,
LOGI("subscribe signal %d %d ", subscribe_id_, cur_type_);
}
+ is_provider_ready_ = false;
+
return ret;
}
if (ret != WATCHFACE_COMPLICATION_ERROR_NONE)
return ret;
+ if (!cur_provider_id_.empty()) {
+ parent_->NotifyListeningStatus(WATCHFACE_COMPLICATION_CONSUMER_LISTENING_STOP);
+ is_provider_ready_ = false;
+ }
+
cur_type_ = type;
cur_provider_id_ = new_provider_id;
cur_provider_appid_ = appid;
return WATCHFACE_COMPLICATION_ERROR_NONE;
}
+void Complication::SetListeningStatus(
+ watchface_complication_consumer_status_e state) {
+ impl_->listening_status_ = state;
+ NotifyListeningStatus(state);
+}
+
+void Complication::NotifyListeningStatus(
+ watchface_complication_consumer_status_e state) {
+ if (impl_->is_provider_ready_ == false)
+ return;
+
+ LOGI("emit signal comp_id %d, type %d %d",
+ impl_->complication_id_, impl_->cur_type_, state);
+
+ std::string provider_appid = DBManager::GetProviderAppId(
+ impl_->cur_provider_id_.c_str());
+
+ if (provider_appid.empty()) {
+ LOGE("Can not find provider info from DB : provider_id(%s)",
+ impl_->cur_provider_id_.c_str());
+ return;
+ }
+
+ int emit_ret = impl_->gdbus_.get()->EmitSignal(
+ IGDBus::SigType::Complication,
+ provider_appid,
+ impl_->cur_provider_id_,
+ -1,
+ util::GetCmdStr(util::CompNotifyListeningStatus),
+ g_variant_new("(sii)",
+ util::GetAppId().c_str(),
+ impl_->cur_type_,
+ state));
+ if (!emit_ret)
+ LOGE("EmitSignal failed %s: %d",
+ impl_->cur_provider_id_.c_str(), state);
+
+ if (state == WATCHFACE_COMPLICATION_CONSUMER_LISTENING_START)
+ SendDataUpdateRequest(false);
+
+ LOGI("emit signal done");
+}
+
int Complication::SetCurDataIdx(int cur_data_idx) {
int ret = WATCHFACE_COMPLICATION_ERROR_NONE;
if (impl_->cur_data_idx_ == cur_data_idx) {
#include "watchface-complication/editables-manager.h"
#include "watchface-complication/db-manager.h"
#include "watchface-common/watchface-exception.h"
+#include "watchface-complication-provider/include/watchface-complication-provider-internal.h"
namespace watchface_complication {
std::list<std::unique_ptr<ProviderInfo>> allowed_list);
int ClearAllowedList();
int Init();
+ void SetListeningStatus(watchface_complication_consumer_status_e state);
+ void NotifyListeningStatus(watchface_complication_consumer_status_e state);
public:
static const char* GetProviderIdKey();
}
}
cb_list_.emplace_back(move(ci));
+ if (cb_list_.size() == 1)
+ SetListeningStatus(WATCHFACE_COMPLICATION_CONSUMER_LISTENING_START);
+
return WATCHFACE_COMPLICATION_ERROR_NONE;
}
for (auto& i : cb_list_) {
if (i.get()->GetCallback() == cb) {
cb_list_.remove(i);
+
+ if (cb_list_.size() == 0)
+ SetListeningStatus(WATCHFACE_COMPLICATION_CONSUMER_LISTENING_STOP);
+
return WATCHFACE_COMPLICATION_ERROR_NONE;
}
}