* limitations under the License.
*/
+#include "app-core-cpp/app_core_base.hh"
+
#include <aul.h>
#include <aul_app_lifecycle.h>
#include <aul_watchdog.h>
#include <dlfcn.h>
#include <errno.h>
#include <gio/gio.h>
+#include <glib-unix.h>
#include <glib.h>
#include <libintl.h>
#include <linux/limits.h>
#include <locale.h>
#include <malloc.h>
#include <sensor_internal.h>
+#include <signal.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <vconf.h>
+#include <algorithm>
#include <cstring>
#include <list>
#include <map>
+#include <memory>
#include <set>
#include <sstream>
+#include <utility>
+#include <vector>
-#include "app-core-cpp/app_core_base.hh"
+#include "app-core-cpp/app_core_plugin_private.hh"
+#include "app-core-cpp/exit_handler_private.hh"
+#include "app-core-cpp/sigterm_handler_private.hh"
+#include "common/glib_private.hh"
#include "common/log_private.hh"
+#include "common/log_tracer.hh"
extern "C" void aul_finalize();
-
namespace tizen_cpp {
+
+AppCoreBase* AppCoreBase::context_ = nullptr;
+
namespace {
+internal::ExitHandler exit_handler;
+internal::SigtermHandler sigterm_handler;
+
enum TizenProfile {
Unknown = 0x00,
Mobile = 0x01,
void UpdateRegion();
std::list<std::string> SplitLanguage(const std::string& lang);
std::string GetLanguage(std::string lang);
- void AppendDefaultLangs(std::set<std::string>& lang_set);
+ void AppendDefaultLangs(std::vector<std::string>& lang_set);
std::string GetStringBefore(const char* str, const char* delim);
std::map<std::string, std::set<std::string>> GetLangTable();
- void AppendLangs(const std::string& lang, std::set<std::string>& lang_set,
+ void AppendLangs(const std::string& lang, std::vector<std::string>& lang_set,
std::map<std::string, std::set<std::string>>& table);
void ChangeLang();
void OnFreezerSignal();
static void ReceiveSuspendSignalCb(GDBusConnection*, const gchar*,
const gchar*, const gchar*, const gchar*, GVariant*, gpointer);
static void OnLowBatteryCb(keynode_t* key, void* data);
+ static void OnTimeZoneChangedCb(keynode_t* key, void* data);
static void LockCb(keynode_t* node, void* user_data);
static void AutoRotationChangedCb(sensor_t sensor, unsigned int event_type,
sensor_data_t* data, void* user_data);
void VerifyLanguage();
void SetDefaultEvents();
void UnsetDefaultEvents();
+ void PluginInit(int argc, char** argv);
+ void PluginFini();
private:
friend class AppCoreBase;
int feature_ = 0;
IAppCore* core_delegator_ = nullptr;
IMainLoop* loop_delegator_ = nullptr;
+ guint signal_handler_source_ = 0;
+ std::unique_ptr<AppCorePlugin> plugin_;
};
AppCoreBase::EventBase::EventBase(Type type)
impl_->val_ = std::move(val);
}
-AppCoreBase::AppCoreBase() : impl_(std::make_unique<AppCoreBase::Impl>(this)) {}
-AppCoreBase::~AppCoreBase() = default;
+AppCoreBase::AppCoreBase()
+ : impl_(std::make_unique<AppCoreBase::Impl>(this)) {
+ if (context_ != nullptr) {
+ _E("Context is already initialized");
+ }
+
+ context_ = this;
+}
+
+AppCoreBase::~AppCoreBase() {
+ _I("");
+ context_ = nullptr;
+}
+
+AppCoreBase* AppCoreBase::GetContext() {
+ if (context_ == nullptr) {
+ _E("Context is not initialized.");
+ return nullptr;
+ }
+
+ return context_;
+}
void AppCoreBase::Impl::ChangeLang() {
const char* lang = getenv("LANG");
GError* err = nullptr;
__bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
if (__bus == nullptr) {
- _E("Failed to connect to the D-BUS daemon: %s", err->message);
- g_error_free(err);
+ _E("Failed to connect to the D-BUS daemon: %s", err ? err->message : "");
+ if (err)
+ g_error_free(err);
+
return;
}
}
void AppCoreBase::Impl::LanguageChangeCb(keynode_t* key, void* user_data) {
AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
if (base->impl_->sid_) {
- g_source_remove(base->impl_->sid_);
+ GLib::SourceRemove(base->impl_->sid_);
base->impl_->sid_ = 0;
}
void AppCoreBase::Impl::LowMemoryCb(keynode_t* key, void* user_data) {
int val = vconf_keynode_get_int(key);
- if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
- AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
- base->impl_->InvokeCallback(val, IEvent::Type::LOW_MEMORY);
+ AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+ base->impl_->InvokeCallback(val, IEvent::Type::LOW_MEMORY);
+ if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
malloc_trim(0);
- }
}
void AppCoreBase::Impl::ChargerStatusChangedCb(keynode_t* keynode,
if (strcmp(env_lang, lang) != 0) {
_I("LANG(%s), LANGSET(%s)", env_lang, lang);
- sid_ = g_idle_add(InvokeLangChangeCb, parent_);
+ sid_ = GLib::IdleAdd(InvokeLangChangeCb, parent_);
}
}
if (!impl_->allowed_bg_)
RemoveSuspendTimer();
- if (impl_->loop_delegator_)
- impl_->loop_delegator_->OnLoopExit();
- else
- OnLoopExit();
+ Exit();
break;
case AUL_TERMINATE_INST:
case AUL_TERMINATE_BG_INST:
return "";
}
- std::string path = std::string(res_path) + PATH_LOCALE;
- if (access(path.c_str(), R_OK) != 0)
- _W("%s does not exist", path.c_str());
-
- return path;
+ return std::string(res_path) + PATH_LOCALE;
}
int AppCoreBase::OnSetI18n() {
}
}
+void AppCoreBase::Impl::OnTimeZoneChangedCb(keynode_t* key, void* data) {
+ char* time_zone_id = vconf_keynode_get_str(key);
+ if (time_zone_id == nullptr) {
+ return;
+ }
+
+ char* time_zone = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_INT);
+ if (time_zone != nullptr) {
+ AppCoreBase* base = reinterpret_cast<AppCoreBase*>(data);
+ base->impl_->InvokeCallback(std::string(time_zone) + "|" + time_zone_id,
+ IEvent::Type::TIME_ZONE_CHANGED);
+ free(time_zone);
+ }
+}
+
void AppCoreBase::Impl::UnregisterRotationChangedEvent() {
if (!__rotation.ref)
return;
break;
case IEvent::Type::SUSPENDED_STATE_CHANGE:
break;
+ case IEvent::Type::TIME_ZONE_CHANGED:
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_ID,
+ impl_->OnTimeZoneChangedCb, this);
+ break;
default:
break;
}
return li;
}
-void AppCoreBase::Impl::AppendDefaultLangs(std::set<std::string>& lang_set) {
- lang_set.insert({"en_US", "en_GB", "en"});
+void AppCoreBase::Impl::AppendDefaultLangs(std::vector<std::string>& langs) {
+ langs.push_back("en_US");
+ langs.push_back("en_GB");
+ langs.push_back("en");
}
std::string AppCoreBase::Impl::GetStringBefore(const char* cstr,
}
void AppCoreBase::Impl::AppendLangs(const std::string& lang,
- std::set<std::string>& lang_set,
+ std::vector<std::string>& langs,
std::map<std::string, std::set<std::string>>& table) {
if (lang.empty())
return;
- lang_set.insert(lang);
+ langs.push_back(lang);
std::string extract_lang = GetStringBefore(lang.c_str(), ".");
if (extract_lang.empty())
return;
- if (lang_set.find(extract_lang) != lang_set.end())
+ if (std::find(langs.begin(), langs.end(), extract_lang) != langs.end())
return;
std::string parent_lang = GetStringBefore(extract_lang.c_str(), "_");
auto it = table[parent_lang].find(extract_lang);
if (it != table[parent_lang].end()) {
- lang_set.insert(move(*it));
+ std::string value = *it;
+ if (std::find(langs.begin(), langs.end(), value) == langs.end())
+ langs.push_back(std::move(value));
+
table[parent_lang].erase(it);
return;
}
it = table[parent_lang].find(parent_lang);
if (it != table[parent_lang].end()) {
- lang_set.insert(move(*it));
+ std::string value = *it;
+ if (std::find(langs.begin(), langs.end(), value) == langs.end())
+ langs.push_back(std::move(value));
+
table[parent_lang].erase(parent_lang);
return;
}
if (!table[parent_lang].empty()) {
auto i = table[parent_lang].begin();
- lang_set.insert(move(*i));
+ std::string value = *i;
+ if (std::find(langs.begin(), langs.end(), value) == langs.end())
+ langs.push_back(std::move(value));
+
table[parent_lang].erase(i);
}
}
if (table.empty())
return "";
- std::set<std::string> lang_set {};
+ std::vector<std::string> langs;
for (auto& i : l)
- AppendLangs(i, lang_set, table);
+ AppendLangs(i, langs, table);
- AppendDefaultLangs(lang_set);
+ AppendDefaultLangs(langs);
std::string ret;
- for (auto& i : lang_set) {
- if (ret.empty()) {
+ for (auto& i : langs) {
+ if (ret.empty())
ret = i;
- } else {
- ret += ":";
- ret += i;
- }
+ else
+ ret += ":" + i;
}
return ret;
}
void AppCoreBase::AddSuspendTimer() {
- impl_->tid_ = g_timeout_add_seconds(5, [](gpointer data) -> gboolean {
+ impl_->tid_ = GLib::TimeoutAdd(5000, [](gpointer data) -> gboolean {
AppCoreBase* base = reinterpret_cast<AppCoreBase*>(data);
base->FlushMemory();
return FALSE;
void AppCoreBase::RemoveSuspendTimer() {
if (impl_->tid_ > 0) {
- g_source_remove(impl_->tid_);
+ GLib::SourceRemove(impl_->tid_);
impl_->tid_ = 0;
}
}
}
void AppCoreBase::Init(int argc, char** argv) {
+ LogTracer tracer("AppCoreBase::Init()");
impl_->tid_ = 0;
impl_->suspended_state_ = false;
impl_->allowed_bg_ = false;
impl_->argc_ = argc;
impl_->argv_ = argv;
traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:OPS_INIT");
+ sigterm_handler.Restore();
if (impl_->loop_delegator_)
impl_->loop_delegator_->OnLoopInit(argc, argv);
else
OnLoopInit(argc, argv);
+
+ impl_->signal_handler_source_ = g_unix_signal_add(SIGTERM,
+ [](gpointer data) -> gboolean {
+ _W("sigterm handler");
+ if (context_ != nullptr) {
+ context_->Exit();
+ context_->impl_->signal_handler_source_ = 0;
+ }
+
+ return G_SOURCE_REMOVE;
+ }, nullptr);
+
+ if (impl_->signal_handler_source_ == 0)
+ _E("Failed to add sigterm handler.");
+
+ traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+ traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:PLUGIN_INIT");
+ impl_->PluginInit(argc, argv);
traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
if (impl_->feature_ & FEATURE_BACKGROUND_MANAGEMENT)
- g_idle_add(Impl::InitSuspendCb, this);
+ GLib::IdleAdd(Impl::InitSuspendCb, this);
traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:SET_SYSTEM_EVENT");
if (!impl_->dirty_) {
}
void AppCoreBase::Fini() {
+ LogTracer tracer("AppCoreBase::Fini()");
+ if (impl_->signal_handler_source_) {
+ g_source_remove(impl_->signal_handler_source_);
+ impl_->signal_handler_source_ = 0;
+ }
+
Dispose();
}
impl_->UnsetDefaultEvents();
if (impl_->sid_) {
- g_source_remove(impl_->sid_);
+ GLib::SourceRemove(impl_->sid_);
impl_->sid_ = 0;
}
RemoveSuspendTimer();
+ impl_->PluginFini();
impl_->dirty_ = false;
if (impl_->loop_delegator_)
impl_->loop_delegator_->OnLoopFinish();
return impl_->feature_;
}
+void AppCoreBase::Impl::PluginInit(int argc, char** argv) {
+ plugin_.reset(AppCorePlugin::Load());
+ if (!plugin_)
+ return;
+
+ plugin_->Init(argc, argv);
+}
+
+void AppCoreBase::Impl::PluginFini() {
+ if (!plugin_)
+ return;
+
+ plugin_->Fini();
+}
+
} // namespace tizen_cpp