* 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::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,
}
}
+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) {
+ for (auto& i : langs) {
if (ret.empty())
ret = i;
else
- ret = i + ":" + ret;
+ ret += ":" + i;
}
return ret;
}
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)
}
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();
}
}
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