#include <sys/inotify.h>
#include <notification.h>
+#include <notification_internal.h>
#include <tzplatform_config.h>
#include "zone/zone.hxx"
#define ZONE_UID_MIN 60001
#define ZONE_UID_MAX 65000
+#define DEFAULT_ZONE_OWNER "owner"
+
#define ZONE_LAUNCHER_APP "org.tizen.kaskit"
+#define NOTIFICATION_SUB_ICON_PATH DATA_PATH "/zone_noti_list_sub_icon.png"
namespace DevicePolicyManager {
const std::string ZONE_GROUP = "users";
+std::vector<std::string> createdZoneList;
+std::unordered_map<std::string, int> notiProxyCallbackMap;
+std::unordered_map<int, notification_h> notiHandleMap;
+
template <typename... Args>
inline void execute(const std::string& path, Args&&... args)
{
}
try {
- runtime::User owner("owner"), pkgUser(target_uid);
+ runtime::User owner(DEFAULT_ZONE_OWNER), pkgUser(target_uid);
if (type == "install" || type == "update") {
PackageInfo pkg(pkgid, pkgUser.getUid());
return 0;
}
+void initializeCreatedZoneList() {
+ try {
+ runtime::Path manifestDir(ZONE_MANIFEST_DIR);
+ runtime::DirectoryIterator iter(manifestDir), end;
+
+ while (iter != end) {
+ const std::string& path = iter->getPath();
+ size_t namePos = path.rfind('/') + 1;
+ size_t extPos = path.rfind(".xml");
+ const std::string& name(path.substr(namePos, extPos - namePos));
+ createdZoneList.push_back(name);
+ ++iter;
+ }
+ } catch (runtime::Exception& e) {}
+}
+
#define NT_TITLE NOTIFICATION_TEXT_TYPE_TITLE
#define NT_CONTENT NOTIFICATION_TEXT_TYPE_CONTENT
#define NT_ICON NOTIFICATION_IMAGE_TYPE_ICON
#define NT_EVENT NOTIFICATION_LY_ONGOING_EVENT
#define NT_APP NOTIFICATION_DISPLAY_APP_INDICATOR
-#define NT_ICON_PATH "/opt/data/dpm/zone-indicator.png"
+#define NT_ICON_PATH DATA_PATH "/zone_indicator_icon.png"
#define NT_TEXT "Container Mode"
#define NT_APPINFO "Zone Application"
const gchar *interface, const gchar *signalName,
GVariant *params, gpointer userData)
{
+ static runtime::User owner(DEFAULT_ZONE_OWNER);
int pid, status;
notification_h noti = reinterpret_cast<notification_h>(userData);
if ((st.st_uid >= ZONE_UID_MIN) && (st.st_uid < ZONE_UID_MAX)) {
notification_set_text(noti, NT_CONTENT, NT_APPINFO, NULL, NT_NONE);
- notification_post(noti);
+ notification_post_for_uid(noti, owner.getUid());
+ } else {
+ notification_delete_for_uid(noti, owner.getUid());
}
}
NULL);
}
+void notiProxyInsert(const runtime::User& owner, const runtime::User& user, int privId, notification_h noti)
+{
+ notification_h newNoti;
+ app_control_h appControl;
+ char zoneLauncherUri[PATH_MAX];
+ char* appId, *pkgId;
+
+ notification_clone(noti, &newNoti);
+
+ notification_get_pkgname(noti, &pkgId);
+ PackageInfo pkg(pkgId, user.getUid());
+ notification_set_image(newNoti, NOTIFICATION_IMAGE_TYPE_ICON, pkg.getIcon().c_str());
+ notification_set_image(newNoti, NOTIFICATION_IMAGE_TYPE_ICON_SUB, NOTIFICATION_SUB_ICON_PATH);
+
+ notification_get_launch_option(newNoti, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, (void *)&appControl);
+ if (appControl != NULL) {
+ app_control_get_app_id(appControl, &appId);
+ snprintf(zoneLauncherUri, PATH_MAX, "zone://launch/%s/%s", user.getName().c_str(), appId);
+ app_control_set_app_id(appControl, ZONE_LAUNCHER_APP);
+ app_control_set_uri(appControl, zoneLauncherUri);
+ notification_set_launch_option(newNoti, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, appControl);
+ }
+
+ notification_post_for_uid(newNoti, owner.getUid());
+ notiHandleMap.insert(std::make_pair(privId, newNoti));
+}
+
+void notiProxyDelete(const runtime::User& owner, int privId)
+{
+ std::unordered_map<int, notification_h>::iterator it;
+
+ it = notiHandleMap.find(privId);
+ if (it == notiHandleMap.end()) {
+ return;
+ }
+ notification_delete_for_uid(it->second, owner.getUid());
+ notification_free(it->second);
+ notiHandleMap.erase(it);
+}
+
+void notiProxyUpdate(const runtime::User& owner, const runtime::User& user, int privId, notification_h noti) {
+ std::unordered_map<int, notification_h>::iterator it;
+ double progress;
+ char *str;
+
+ it = notiHandleMap.find(privId);
+ if (it == notiHandleMap.end()) {
+ return;
+ }
+
+ notification_image_type_e imageTypes[] = {
+ NOTIFICATION_IMAGE_TYPE_ICON,
+ NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR,
+ NOTIFICATION_IMAGE_TYPE_ICON_FOR_LOCK,
+ NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
+ NOTIFICATION_IMAGE_TYPE_THUMBNAIL_FOR_LOCK,
+ NOTIFICATION_IMAGE_TYPE_ICON_SUB,
+ NOTIFICATION_IMAGE_TYPE_BACKGROUND,
+ NOTIFICATION_IMAGE_TYPE_LIST_1,
+ NOTIFICATION_IMAGE_TYPE_LIST_2,
+ NOTIFICATION_IMAGE_TYPE_LIST_3,
+ NOTIFICATION_IMAGE_TYPE_LIST_4,
+ NOTIFICATION_IMAGE_TYPE_LIST_5,
+ NOTIFICATION_IMAGE_TYPE_BUTTON_1,
+ NOTIFICATION_IMAGE_TYPE_BUTTON_2,
+ NOTIFICATION_IMAGE_TYPE_BUTTON_3,
+ NOTIFICATION_IMAGE_TYPE_BUTTON_4,
+ NOTIFICATION_IMAGE_TYPE_BUTTON_5,
+ NOTIFICATION_IMAGE_TYPE_BUTTON_6
+ };
+
+ for (notification_image_type_e type : imageTypes) {
+ notification_get_image(noti, type, &str);
+ notification_set_image(it->second, type, str);
+ }
+
+ notification_text_type_e textTypes[] = {
+ NOTIFICATION_TEXT_TYPE_TITLE,
+ NOTIFICATION_TEXT_TYPE_CONTENT,
+ NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
+ NOTIFICATION_TEXT_TYPE_EVENT_COUNT,
+ NOTIFICATION_TEXT_TYPE_INFO_1,
+ NOTIFICATION_TEXT_TYPE_INFO_SUB_1,
+ NOTIFICATION_TEXT_TYPE_INFO_2,
+ NOTIFICATION_TEXT_TYPE_INFO_SUB_2,
+ NOTIFICATION_TEXT_TYPE_INFO_3,
+ NOTIFICATION_TEXT_TYPE_INFO_SUB_3,
+ NOTIFICATION_TEXT_TYPE_GROUP_TITLE,
+ NOTIFICATION_TEXT_TYPE_GROUP_CONTENT,
+ NOTIFICATION_TEXT_TYPE_GROUP_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
+ NOTIFICATION_TEXT_TYPE_BUTTON_1,
+ NOTIFICATION_TEXT_TYPE_BUTTON_2,
+ NOTIFICATION_TEXT_TYPE_BUTTON_3,
+ NOTIFICATION_TEXT_TYPE_BUTTON_4,
+ NOTIFICATION_TEXT_TYPE_BUTTON_5,
+ NOTIFICATION_TEXT_TYPE_BUTTON_6,
+ };
+
+ for (notification_text_type_e type : textTypes) {
+ notification_get_text(noti, type, &str);
+ notification_set_text(it->second, type, str, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ }
+
+ notification_get_size(noti, &progress);
+ notification_set_size(it->second, progress);
+
+ notification_get_progress(noti, &progress);
+ notification_set_progress(it->second, progress);
+
+ notification_update_for_uid(it->second, owner.getUid());
+}
+
+void notiProxyCallback(void *data, notification_type_e type, notification_op *op_list, int num_op)
+{
+ static runtime::User owner(DEFAULT_ZONE_OWNER);
+ runtime::User user(*reinterpret_cast<std::string*>(data));
+
+ // TODO : should remove noti in the zone when related-zone is removed
+ // This will be imlemented when notification bug is fixed
+
+ for (int i = 0; i < num_op; i++) {
+ notification_h noti = NULL;
+ int opType, privId;
+
+ notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_TYPE, &opType);
+ notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_PRIV_ID, &privId);
+
+ switch (opType) {
+ case NOTIFICATION_OP_INSERT:
+ notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_NOTI, ¬i);
+ notiProxyInsert(owner, user, privId, noti);
+ break;
+ case NOTIFICATION_OP_DELETE:
+ notiProxyDelete(owner, privId);
+ break;
+ case NOTIFICATION_OP_UPDATE:
+ notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_NOTI, ¬i);
+ notiProxyUpdate(owner, user, privId, noti);
+ break;
+ }
+ }
+}
+
} // namespace
ZoneManager::ZoneManager(PolicyControlContext& ctx)
packageManager.setEventCallback(packageEventHandler, this);
zoneProcessMonitor();
+
+ initializeCreatedZoneList();
+ for (std::string& name : createdZoneList) {
+ if (name == DEFAULT_ZONE_OWNER) {
+ continue;
+ }
+
+ runtime::User zone(name);
+ int noti = notification_register_detailed_changed_cb_for_uid(notiProxyCallback, &name, zone.getUid());
+ notiProxyCallbackMap.insert(std::make_pair(name, noti));
+ }
}
ZoneManager::~ZoneManager()
//unlock the user
setZoneState(user.getUid(), 1);
+ auto it = createdZoneList.insert(createdZoneList.begin(), name);
+ int noti = notification_register_detailed_changed_cb_for_uid(notiProxyCallback, &(*it), user.getUid());
+ notiProxyCallbackMap.insert(std::make_pair(name, noti));
context.notify("ZoneManager::created", name, std::string());
// Running launch app and add a shorcut
//remove zone user
user.remove();
+ for (std::vector<std::string>::iterator it = createdZoneList.begin();
+ it != createdZoneList.end(); it++) {
+ createdZoneList.erase(it);
+ }
+ notiProxyCallbackMap.erase(name);
context.notify("ZoneManager::removed", name, std::string());
} catch (runtime::Exception& e) {
ERROR(e.what());
{
runtime::File manifest(ZONE_MANIFEST_DIR + name + ".xml");
if (!manifest.exists()) {
- return -1;
+ return 0;
}
try {
}
} catch (runtime::Exception& e) {
ERROR(e.what());
- return -1;
+ return 0;
}
return 0;
std::vector<std::string> ZoneManager::getZoneList(int state)
{
std::vector<std::string> list;
- try {
- runtime::Path manifestDir(ZONE_MANIFEST_DIR);
- runtime::DirectoryIterator iter(manifestDir), end;
- while (iter != end) {
- const std::string& path = iter->getPath();
- size_t namePos = path.rfind('/') + 1;
- size_t extPos = path.rfind(".xml");
- const std::string& name(path.substr(namePos, extPos - namePos));
- if (getZoneState(name) & state) {
- list.push_back(name);
- }
- ++iter;
+ for (const std::string& name : createdZoneList) {
+ if (getZoneState(name) & state) {
+ list.push_back(name);
}
- } catch (runtime::Exception& e) {}
-
+ }
return list;
}
{
char new_uri[PATH_MAX];
- snprintf(new_uri, sizeof(new_uri), "zone://launch/%s", zone_name);
+ snprintf(new_uri, sizeof(new_uri), "zone://home/%s", zone_name);
shortcut_add_to_home(zone_name, LAUNCH_BY_URI, new_uri, "", 0, __shortcut_result_cb, NULL);
}
ecore_thread_run(__create_icon_thread, NULL, NULL, NULL);
}
+static void __launch_zone_app(const char *zone_name, const char *app_id)
+{
+ zone_app_proxy_create(__zone_mgr, zone_name, &__zone_app);
+ zone_package_proxy_create(__zone_mgr, zone_name, &__zone_pkg);
+ zone_app_proxy_launch(__zone_app, app_id);
+ ui_app_exit();
+}
+
static bool __app_create(void *data)
{
zone_manager_create(&__zone_mgr);
static void __app_control(app_control_h app_control, void *data)
{
- char* zone_uri, *zone_name = "";
+ char* zone_uri, *tmp, *zone_name, *app_id;
int ret = 0;
ret = app_control_get_uri(app_control, &zone_uri);
if (ret != APP_CONTROL_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "No URI");
ui_app_exit();
+ return;
}
if (strncmp(zone_uri, "zone://", sizeof("zone://") - 1) != 0) {
dlog_print(DLOG_ERROR, LOG_TAG, "Mismatched URI");
+ free(zone_uri);
ui_app_exit();
+ return;
}
- zone_uri = zone_uri + sizeof("zone://") - 1;
+ tmp = zone_uri + sizeof("zone://") - 1;
- if (strncmp(zone_uri, "setup/", sizeof("setup/") - 1) == 0) {
- zone_name = zone_uri + sizeof("setup/") - 1;
+ if (strncmp(tmp, "setup/", sizeof("setup/") - 1) == 0) {
+ zone_name = tmp + sizeof("setup/") - 1;
__add_shortcut(zone_name);
__show_launcher(zone_name);
- } else if (strncmp(zone_uri, "launch/", sizeof("launch/") - 1) == 0) {
- zone_name = zone_uri + sizeof("launch/") - 1;
+ } else if (strncmp(tmp, "home/", sizeof("home/") - 1) == 0) {
+ zone_name = tmp + sizeof("home/") - 1;
__show_launcher(zone_name);
+ } else if (strncmp(tmp, "launch/", sizeof("launch/") - 1) == 0) {
+ zone_name = tmp + sizeof("launch/") - 1;
+ app_id = strchr(zone_name, '/');
+ *(app_id++) = '\0';
+ __launch_zone_app(zone_name, app_id);
} else {
dlog_print(DLOG_ERROR, LOG_TAG, "Invalid URI");
ui_app_exit();
}
+ free(zone_uri);
}
static void __app_pause(void *data)