From: Sungbae Yoo Date: Tue, 21 Jun 2016 07:07:14 +0000 (+0900) Subject: Add a callback for proxy to show notification from zone X-Git-Tag: accepted/tizen/common/20160628.141418~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dac24a124c027c9bffda9a171e21475d877f1e95;p=platform%2Fcore%2Fsecurity%2Fdevice-policy-manager.git Add a callback for proxy to show notification from zone Signed-off-by: Sungbae Yoo Change-Id: Ib91d0ea99de3c2b3e27a7d1ca98efad3e7fbb4a9 --- diff --git a/packaging/device-policy-manager.spec b/packaging/device-policy-manager.spec index 4dc369e..1944a41 100755 --- a/packaging/device-policy-manager.spec +++ b/packaging/device-policy-manager.spec @@ -338,7 +338,8 @@ mv /etc/pam.d/systemd-user.keep /etc/pam.d/systemd-user %attr(700,root,root) %{_sbindir}/zone-volume-manager %attr(700,root,root) %dir %{TZ_SYS_ETC}/dpm/zone %attr(600,root,root) %config %{TZ_SYS_ETC}/dpm/zone/owner.xml -%attr(644,root,root) /opt/data/dpm/zone-indicator.png +%attr(644,root,root) %{TZ_SYS_DATA}/dpm/zone_indicator_icon.png +%attr(644,root,root) %{TZ_SYS_DATA}/dpm/zone_noti_list_sub_icon.png %config /etc/pam.d/* %endif diff --git a/server/zone.cpp b/server/zone.cpp index 2ea5ecf..0614d95 100755 --- a/server/zone.cpp +++ b/server/zone.cpp @@ -106,7 +106,7 @@ int ZonePolicy::createZone(const std::string& name, const std::string& setupWizA int ZonePolicy::removeZone(const std::string& name) { - if (getZoneState(name) < 0) { + if (getZoneState(name) == 0) { return -1; } diff --git a/server/zone/zone.cpp b/server/zone/zone.cpp index a753da5..d1ae9d6 100644 --- a/server/zone/zone.cpp +++ b/server/zone/zone.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include "zone/zone.hxx" @@ -39,7 +40,10 @@ #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 { @@ -71,6 +75,10 @@ const std::string APP_SMACKLABEL = "User::Pkg::"; const std::string ZONE_GROUP = "users"; +std::vector createdZoneList; +std::unordered_map notiProxyCallbackMap; +std::unordered_map notiHandleMap; + template inline void execute(const std::string& path, Args&&... args) { @@ -255,7 +263,7 @@ int packageEventHandler(uid_t target_uid, int req_id, } 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()); @@ -282,6 +290,22 @@ int packageEventHandler(uid_t target_uid, int req_id, 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 @@ -290,7 +314,7 @@ int packageEventHandler(uid_t target_uid, int req_id, #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" @@ -301,6 +325,7 @@ void zoneProcessCallback(GDBusConnection *connection, 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(userData); @@ -320,7 +345,9 @@ void zoneProcessCallback(GDBusConnection *connection, 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()); } } @@ -387,6 +414,149 @@ void zoneProcessMonitor() 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::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::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(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) @@ -406,6 +576,17 @@ 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() @@ -460,6 +641,9 @@ int ZoneManager::createZone(const std::string& name, const std::string& manifest //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 @@ -514,6 +698,11 @@ int ZoneManager::removeZone(const std::string& name) //remove zone user user.remove(); + for (std::vector::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()); @@ -557,7 +746,7 @@ int ZoneManager::getZoneState(const std::string& name) { runtime::File manifest(ZONE_MANIFEST_DIR + name + ".xml"); if (!manifest.exists()) { - return -1; + return 0; } try { @@ -576,7 +765,7 @@ int ZoneManager::getZoneState(const std::string& name) } } catch (runtime::Exception& e) { ERROR(e.what()); - return -1; + return 0; } return 0; @@ -585,22 +774,12 @@ int ZoneManager::getZoneState(const std::string& name) std::vector ZoneManager::getZoneList(int state) { std::vector 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; } diff --git a/zone/kaskit/src/main.c b/zone/kaskit/src/main.c index 8a1fd9f..77dfbf9 100644 --- a/zone/kaskit/src/main.c +++ b/zone/kaskit/src/main.c @@ -153,7 +153,7 @@ static void __add_shortcut(const char *zone_name) { 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); } @@ -172,6 +172,14 @@ static void __show_launcher(const char *zone_name) 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); @@ -183,33 +191,42 @@ static bool __app_create(void *data) 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) diff --git a/zone/module/CMakeLists.txt b/zone/module/CMakeLists.txt index 18aba37..d7ef612 100644 --- a/zone/module/CMakeLists.txt +++ b/zone/module/CMakeLists.txt @@ -47,5 +47,6 @@ TARGET_COMPILE_DEFINITIONS(${ZONE_PAM_NAME} PRIVATE INSTALL(TARGETS ${ZONE_PAM_NAME} DESTINATION ${LIB_INSTALL_DIR}/security) INSTALL(FILES data/DefaultZoneManifest.xml DESTINATION ${CONF_INSTALL_DIR}/zone RENAME owner.xml) -INSTALL(FILES data/zone-indicator.png DESTINATION /opt/data/dpm) +INSTALL(FILES data/zone_indicator_icon.png DESTINATION /opt/data/dpm) +INSTALL(FILES data/zone_noti_list_sub_icon.png DESTINATION /opt/data/dpm) INSTALL(FILES pam.d/systemd-user-zone DESTINATION ${PAMD_INSTALL_DIR}) diff --git a/zone/module/data/zone-indicator.png b/zone/module/data/zone_indicator_icon.png similarity index 100% rename from zone/module/data/zone-indicator.png rename to zone/module/data/zone_indicator_icon.png diff --git a/zone/module/data/zone_noti_list_sub_icon.png b/zone/module/data/zone_noti_list_sub_icon.png new file mode 100755 index 0000000..ad08f64 Binary files /dev/null and b/zone/module/data/zone_noti_list_sub_icon.png differ