Send policy updates independently from askuser agent 73/104573/5
authorZofia Abramowska <z.abramowska@samsung.com>
Tue, 13 Dec 2016 16:27:19 +0000 (17:27 +0100)
committerjooseong lee <jooseong.lee@samsung.com>
Wed, 14 Dec 2016 02:13:10 +0000 (11:13 +0900)
Move policy update to other thread so it doesn't block
other agent requests.

Change-Id: I0b9187b63fe7960c979379737decd521b8fd7eaf

13 files changed:
src/agent/CMakeLists.txt
src/agent/main/Agent.cpp
src/agent/main/Agent.h
src/agent/main/PolicyUpdater.cpp [new file with mode: 0644]
src/agent/main/PolicyUpdater.h [new file with mode: 0644]
src/agent/notification-daemon/AskUserTalker.cpp
src/agent/notification-daemon/CMakeLists.txt
src/agent/notification-daemon/GuiRunner.cpp
src/common/CMakeLists.txt
src/common/policy/Policy.cpp [moved from src/agent/notification-daemon/Policy.cpp with 54% similarity]
src/common/policy/Policy.h [moved from src/agent/notification-daemon/Policy.h with 78% similarity]
src/common/policy/PrivilegeInfo.cpp [moved from src/agent/notification-daemon/PrivilegeInfo.cpp with 85% similarity]
src/common/policy/PrivilegeInfo.h [moved from src/agent/notification-daemon/PrivilegeInfo.h with 100% similarity]

index bb530f0..e65bccc 100644 (file)
@@ -22,8 +22,6 @@ PKG_CHECK_MODULES(AGENT_DEP
     cynara-plugin
     cynara-creds-socket
     libsystemd
-    security-privilege-manager
-    glib-2.0
     )
 
 SET(ASKUSER_AGENT_PATH ${ASKUSER_PATH}/agent)
@@ -32,6 +30,7 @@ SET(ASKUSER_SOURCES
     ${ASKUSER_AGENT_PATH}/main/Agent.cpp
     ${ASKUSER_AGENT_PATH}/main/CynaraTalker.cpp
     ${ASKUSER_AGENT_PATH}/main/main.cpp
+    ${ASKUSER_AGENT_PATH}/main/PolicyUpdater.cpp
     ${ASKUSER_AGENT_PATH}/ui/NotificationBackend.cpp
     ${ASKUSER_AGENT_PATH}/ui/FdNotifyObject.cpp
     )
index 6b0e8bd..8217fbb 100644 (file)
@@ -28,6 +28,7 @@
 #include <utility>
 
 #include <attributes/attributes.h>
+#include <policy/Policy.h>
 #include <translator/Translator.h>
 #include <types/AgentErrorMsg.h>
 #include <types/SupportedTypes.h>
@@ -52,13 +53,12 @@ Agent::~Agent() {
 }
 
 void Agent::init() {
-    // TODO: implement if needed
-
     ALOGD("Agent daemon initialized");
 }
 
 void Agent::run() {
     m_cynaraTalker.start();
+    m_policyUpdater.start();
 
     while (!m_stopFlag) {
         std::unique_lock<std::mutex> lock(m_mutex);
@@ -115,8 +115,9 @@ void Agent::run() {
 }
 
 void Agent::finish() {
+    m_policyUpdater.stop();
     if (!m_cynaraTalker.stop()) {
-        ALOGE("Cynara talker thread could not be stopped. Calling quick_exit()");
+        ALOGE("Threads could not be stopped. Calling quick_exit()");
         quick_exit(EXIT_SUCCESS);
     }
 
@@ -197,6 +198,22 @@ void Agent::processUIResponse(const Response &response) {
                                                                    AgentErrorMsg::NoError);
         }
         m_cynaraTalker.sendResponse(RT_Action, requestIt->second->id(), pluginData);
+        auto data = Translator::Agent::dataToRequest(requestIt->second->data());
+
+        std::string appId, pkgLabel;
+        identifyApp(data.client, data.user, appId, pkgLabel);
+
+        switch (response.type()) {
+        case URT_NO_LIFE:
+            m_policyUpdater.update(appId, data.user, data.privilege, "Deny");
+            break;
+        case URT_YES_LIFE:
+            m_policyUpdater.update(appId, data.user, data.privilege, "Allow");
+            break;
+        default:
+            break;
+        }
+
         delete requestIt->second;
         m_requests.erase(requestIt);
     }
index a1ce240..c85f8c8 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include <condition_variable>
 #include <csignal>
 #include <map>
 #include <mutex>
@@ -29,6 +28,7 @@
 #include <types/PolicyType.h>
 
 #include <main/CynaraTalker.h>
+#include <main/PolicyUpdater.h>
 #include <main/Request.h>
 #include <main/Response.h>
 
@@ -51,6 +51,7 @@ public:
 
 private:
     CynaraTalker m_cynaraTalker;
+    PolicyUpdater m_policyUpdater;
     std::map<RequestId, Request *> m_requests;
     std::queue<Request *> m_incomingRequests;
     std::queue<Response> m_incomingResponses;
diff --git a/src/agent/main/PolicyUpdater.cpp b/src/agent/main/PolicyUpdater.cpp
new file mode 100644 (file)
index 0000000..b7e6d86
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        PolicyUpdater.cpp
+ * @author      Zofia Abramowska <z.abramowska@samsung.com>
+ * @brief       This file implements class of policy updater
+ */
+
+#include <csignal>
+#include <unistd.h>
+
+#include <exception/Exception.h>
+#include <log/alog.h>
+#include <policy/Policy.h>
+#include <policy/PrivilegeInfo.h>
+
+#include "PolicyUpdater.h"
+
+namespace AskUser {
+
+namespace Agent {
+
+PolicyUpdater::PolicyUpdater() : m_running(false)
+{}
+
+void PolicyUpdater::start() {
+    m_thread = std::thread(&PolicyUpdater::run, this);
+    m_running = true;
+}
+
+void PolicyUpdater::stop() {
+    if (!m_running || !m_thread.joinable())
+        return;
+    m_running = false;
+
+    m_thread.join();
+    ALOGD("PolicyUpdater thread finished.");
+}
+
+void PolicyUpdater::run() {
+    int ret;
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, SIGTERM);
+    if ((ret = pthread_sigmask(SIG_BLOCK, &mask, nullptr)) < 0) {
+        ALOGE("sigprocmask failed [<<" << ret << "]");
+    }
+
+    while (m_running) {
+        try {
+            std::unique_lock<std::mutex> lock(m_mutex);
+            m_event.wait(lock, [&](){ return !m_events.empty() || !m_running;});
+
+            if (m_events.empty()) {
+                continue;
+            }
+
+            ALOGD("Got " << m_events.size() << " policies to update");
+            m_eventsInternal = std::move(m_events);
+            lock.unlock();
+
+            PolicyRequest req;
+            ALOGD("Updating " << m_eventsInternal.size() << " policies");
+            for (auto &policyInfo : m_eventsInternal) {
+                std::string privacyName = PrivilegeInfo::getPrivacyName(policyInfo.priv);
+                if (privacyName.empty()) {
+                    ALOGE("Unable to get privacy name for privilege " << policyInfo.priv);
+                    throw Exception("Unable to get privacy name for " + policyInfo.priv);
+                }
+                auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacyName);
+                if (privacyPrivs.empty()) {
+                    ALOGE("Unable to get privacy privileges for privacy " << privacyName);
+                    throw Exception("Unable to get privacy privileges for privacy " + privacyName);
+                }
+                ALOGD("Adding policy entry for : app: " << policyInfo.appId << ", privilege: "
+                      << policyInfo.priv  << ", user:" << policyInfo.user << ", level: "
+                      << policyInfo.level);
+                for (auto &priv : privacyPrivs) {
+                    PolicyEntry entry;
+                    entry.setApp(policyInfo.appId);
+                    entry.setUser(policyInfo.user);
+                    entry.setPrivilege(priv);
+                    entry.setLevel(policyInfo.level);
+                    req.addEntry(std::move(entry));
+                }
+            }
+            req.updatePolicy();
+            ALOGD("Policy update sent");
+
+            m_eventsInternal.clear();
+        } catch (const std::exception &e) {
+            ALOGC("Unexpected exception: <" << e.what() << ">");
+        } catch (...) {
+            ALOGE("Unexpected unknown exception caught!");
+        }
+    }
+}
+
+void PolicyUpdater::update(const std::string &appId, const std::string &user,
+                           const std::string &privilege, const std::string &level)
+{
+    ALOGD("Queueing policy update for: app: " << appId << ", privilege: " << privilege
+          << ", user:" << user << ", level: " << level);
+    if (!m_running) {
+        ALOGE("PolicyUpdater not running, cannot update policy for " << appId << " " << user << " "
+              << privilege << " " << level);
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(m_mutex);
+        m_events.push_back({appId, user, privilege, level});
+    }
+    m_event.notify_one();
+}
+
+} // namespace Agent
+
+} // namespace AskUser
diff --git a/src/agent/main/PolicyUpdater.h b/src/agent/main/PolicyUpdater.h
new file mode 100644 (file)
index 0000000..1cfff28
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        PolicyUpdater.h
+ * @author      Zofia Abramowska <z.abramowska@samsung.com>
+ * @brief       This file declares class of policy updater
+ */
+
+#pragma once
+
+#include <atomic>
+#include <mutex>
+#include <string>
+#include <vector>
+#include <thread>
+#include <condition_variable>
+
+namespace AskUser {
+
+namespace Agent {
+
+class PolicyUpdater {
+public:
+    PolicyUpdater();
+    ~PolicyUpdater() { stop(); }
+
+    void start();
+    void stop();
+
+    void update(const std::string &appId, const std::string &user, const std::string &privilege,
+                const std::string &level);
+private:
+    struct PolicyInfo {
+        std::string appId;
+        std::string user;
+        std::string priv;
+        std::string level;
+    };
+    std::atomic<bool> m_running;
+    std::thread m_thread;
+
+    std::mutex m_mutex;
+    std::condition_variable m_event;
+    std::vector<PolicyInfo> m_events;
+    std::vector<PolicyInfo> m_eventsInternal;
+
+    void run();
+};
+
+} // namespace Agent
+
+} // namespace AskUser
index 8aeb5a0..9efbfb0 100644 (file)
@@ -26,9 +26,8 @@
 #include <string>
 #include <sys/signalfd.h>
 
-#include "Policy.h"
-#include "PrivilegeInfo.h"
-
+#include <policy/Policy.h>
+#include <policy/PrivilegeInfo.h>
 #include <socket/Socket.h>
 #include <socket/Poll.h>
 #include <types/NotificationResponse.h>
@@ -38,8 +37,6 @@
 #include <translator/Translator.h>
 #include <config/Path.h>
 
-#include <security-manager.h>
-
 #ifdef BUILD_WITH_SYSTEMD_DAEMON
 #include <systemd/sd-daemon.h>
 #endif
@@ -50,48 +47,6 @@ namespace Notification {
 
 namespace {
 
-void setSecurityLevel(const std::string &app, const std::string &perm, const std::string &level)
-{
-    try {
-        if (level != "Allow" && level != "Deny")
-            throw std::invalid_argument("Not allowed security level <" + level + ">");
-
-        ALOGD("SecurityManager: Setting security level to " << level);
-        std::string appName;
-        std::string pkgLabel;
-        identifyApp(app, appName, pkgLabel);
-        if (appName.empty()) {
-            ALOGE("Couldn't fetch appName from cynara client. Cannot set policy");
-            return;
-        }
-
-        std::string privacyName = PrivilegeInfo::getPrivacyName(perm);
-        if (privacyName.empty()) {
-            ALOGE("Unablte to get privacy name for privilege " << perm);
-            throw Exception("Unable to get privacy name for " + perm);
-        }
-
-        auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacyName);
-        if (privacyPrivs.empty()) {
-            ALOGE("Unablte to get privacy privileges for privacy " << privacyName);
-            throw Exception("Unablte to get privacy privileges for privacy " + privacyName);
-        }
-        PolicyRequest updateRequest;
-
-        std::vector<PolicyEntry> entryVector(privacyPrivs.size());
-        for (size_t i=0; i < privacyPrivs.size(); ++i) {
-            entryVector[i].setApp(appName);
-            entryVector[i].setPrivilege(privacyPrivs[i]);
-            entryVector[i].setLevel(level);
-            updateRequest.addEntry(entryVector[i]);
-        }
-        updateRequest.updatePolicy();
-        ALOGD("SecurityManager: Setting level succeeded");
-    } catch (std::exception &e) {
-        ALOGE("SecurityManager: Failed <" << e.what() << ">");
-    }
-}
-
 } /* namespace */
 
 void AskUserTalker::dissmissCb(int fd, void *data) {
@@ -221,23 +176,16 @@ void AskUserTalker::handlePeer() {
     switch (response.response) {
     case NResponseType::Error:
        ALOGE("Error in user interface : " << m_gui.getErrorMsg());
-       break;
     case NResponseType::AllowAlways:
-        setSecurityLevel(request.data.client, request.data.privilege,
-                         "Allow");
-        break;
     case NResponseType::DenyAlways:
-       setSecurityLevel(request.data.client, request.data.privilege,
-                        "Deny");
-       break;
     case NResponseType::Deny:
     case NResponseType::None:
+        ALOGD("Sending response " << static_cast<int>(response.response));
         break;
     default:
        ALOGW("Unknown response type returned");
        break;
     }
-
    return;
 }
 
index 574eaf3..32e34a4 100644 (file)
@@ -5,9 +5,6 @@ PKG_CHECK_MODULES(ASKUSER_NOTIFICATION_DEP
     elementary
     cynara-agent
     libsystemd
-    security-manager
-    security-privilege-manager
-    pkgmgr-info
     vconf
     capi-ui-efl-util
 )
@@ -24,8 +21,6 @@ SET(ASKUSER_NOTIFICATION_SOURCES
     ${NOTIF_PATH}/main.cpp
     ${NOTIF_PATH}/GuiRunner.cpp
     ${NOTIF_PATH}/AskUserTalker.cpp
-    ${NOTIF_PATH}/Policy.cpp
-    ${NOTIF_PATH}/PrivilegeInfo.cpp
    )
 
 
index 5b3be20..39e6860 100644 (file)
 
 #include <exception/ErrnoException.h>
 #include <exception/Exception.h>
+#include <policy/Policy.h>
 #include <translator/Translator.h>
 #include <libintl.h>
 #include <vconf.h>
 #include <efl_util.h>
-#include "Policy.h"
+
+#include <unistd.h>
 
 namespace AskUser {
 
@@ -307,7 +309,7 @@ NResponseType GuiRunner::popupRun(const std::string &app, const std::string &per
 
         std::string appId;
         std::string pkgLabel;
-        identifyApp(app, appId, pkgLabel);
+        identifyApp(app, std::to_string(getuid()), appId, pkgLabel);
 
         // create message
         char *messageFormat = dgettext(PROJECT_NAME, "IDS_IDLE_POP_ALLOW_P1SS_TO_ACCESS_YOUR_P2SS_Q");
index adcae22..193868c 100644 (file)
@@ -19,7 +19,11 @@ PKG_CHECK_MODULES(COMMON_DEP
     REQUIRED
     cynara-plugin
     cynara-agent
+    glib-2.0
     libsystemd
+    pkgmgr-info
+    security-manager
+    security-privilege-manager
     )
 
 SET(ASKUSER_COMMON_VERSION_MAJOR 0)
@@ -37,6 +41,8 @@ INCLUDE_DIRECTORIES(
 
 SET(COMMON_SOURCES
     ${COMMON_PATH}/log/alog.cpp
+    ${COMMON_PATH}/policy/Policy.cpp
+    ${COMMON_PATH}/policy/PrivilegeInfo.cpp
     ${COMMON_PATH}/socket/Socket.cpp
     ${COMMON_PATH}/socket/Poll.cpp
     ${COMMON_PATH}/translator/Translator.cpp
similarity index 54%
rename from src/agent/notification-daemon/Policy.cpp
rename to src/common/policy/Policy.cpp
index de6d642..73145d6 100644 (file)
@@ -22,6 +22,8 @@
 #include <memory>
 
 #include <pkgmgr-info.h>
+#include <security-manager.h>
+
 #include <exception/Exception.h>
 #include <log/alog.h>
 
@@ -34,76 +36,70 @@ inline void throwOnSMError(std::string err, int ret)
         throw AskUser::Exception(err + " : " + std::to_string(ret));
 }
 
-char * toAppId(const char *pkgId) {
-    int ret = 0;
-    char *mainappid = 0;
-    pkgmgrinfo_pkginfo_h handle = NULL;
-    ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId, &handle);
-    if (ret != PMINFO_R_OK)
-        return NULL;
-    ret = pkgmgrinfo_pkginfo_get_mainappid(handle, &mainappid);
-    if (ret != PMINFO_R_OK) {
-        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-        return NULL;
+struct PkgInfo {
+    PkgInfo(const std::string &pkgId, uid_t uid) : m_handle(nullptr) {
+        int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &m_handle);
+        if (ret != PMINFO_R_OK) {
+            ALOGE("pkgmgrinfo_pkginfo_get_usr_pkginfo failed for " << pkgId  << " with " << ret);
+            m_handle = nullptr;
+        }
     }
-    printf("main app id: %s\n", mainappid);
-    char *result = strdup(mainappid);
-    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-    return result;
-}
-
-char * toPkgLabel(const char *pkgId) {
-    int ret = 0;
-    char *pkgLabel = 0;
-    pkgmgrinfo_pkginfo_h handle = NULL;
-    ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId, &handle);
-    if (ret != PMINFO_R_OK)
-        return NULL;
-    ret = pkgmgrinfo_pkginfo_get_label(handle, &pkgLabel);
-    if (ret != PMINFO_R_OK) {
-        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-        return NULL;
+    ~PkgInfo() {
+        if (m_handle)
+            pkgmgrinfo_pkginfo_destroy_pkginfo(m_handle);
     }
-    printf("pkg label: %s\n", pkgLabel);
-    char *result = strdup(pkgLabel);
-    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-    return result;
-}
+    const std::string mainAppId(){
+        if (!m_handle) {
+            return "";
+        }
+        char *mainAppId;
+        int ret = pkgmgrinfo_pkginfo_get_mainappid(m_handle, &mainAppId);
+        if (ret != PMINFO_R_OK) {
+            ALOGE("pkgmgrinfo_pkginfo_get_mainappid failed  with " << ret);
+            return "";
+        }
+        return mainAppId ? mainAppId : "";
+    }
+    const std::string pkgLabel() {
+        if (!m_handle) {
+            return "";
+        }
+        char *pkgLabel;
+        int ret = pkgmgrinfo_pkginfo_get_label(m_handle, &pkgLabel);
+        if (ret != PMINFO_R_OK) {
+            ALOGE("pkgmgrinfo_pkginfo_get_label failed  with " << ret);
+            return "";
+        }
+        return pkgLabel ? pkgLabel : "";
+    }
+    pkgmgrinfo_pkginfo_h m_handle;
+};
 }
 
 namespace AskUser {
 
-void identifyApp(const std::string &client, std::string &appId, std::string &pkgLabel) {
-    char *pkg_name = nullptr;
-    char *app_name = nullptr;
-    char *pkg_label = nullptr;
-
-    int ret = security_manager_identify_app_from_cynara_client(client.c_str(), &pkg_name, &app_name);
-    std::unique_ptr<char, decltype(free)*> pkg_name_p(pkg_name, free);
-
-    // non-hybrid
-    if (!app_name && pkg_name_p)
-        app_name = toAppId(pkg_name_p.get());
-
-    pkg_label = toPkgLabel(pkg_name_p.get());
+void identifyApp(const std::string &client, const std::string &user,
+                 std::string &appId, std::string &pkgLabel)
+{
+    char *pkgName = nullptr;
+    char *appName = nullptr;
 
-    std::unique_ptr<char, decltype(free)*> app_name_p(app_name, free);
+    int ret = security_manager_identify_app_from_cynara_client(client.c_str(), &pkgName, &appName);
+    std::unique_ptr<char, decltype(free)*> pkg_name_p(pkgName, free);
+    std::unique_ptr<char, decltype(free)*> app_name_p(appName, free);
     throwOnSMError("security_manager_identify_app_from_cynara_client", ret);
 
-    std::unique_ptr<char, decltype(free)*> pkg_label_p(pkg_label, free);
-
-    if (!app_name) {
-        ALOGW("Identifying of application failed!");
+    if (!pkgName) {
+        ALOGE("Couldn't identify clients package id");
         return;
     }
 
-    if (!pkg_label) {
-        ALOGW("Get pkg label failed!");
-        return;
-    }
+    uid_t uid = std::strtoul(user.c_str(), nullptr, 10);
+    PkgInfo pkgInfo(pkgName, uid);
+    if (!appName)
+        appId = pkgInfo.mainAppId();
 
-    appId = app_name;
-    pkgLabel = pkg_label;
+    pkgLabel = pkgInfo.pkgLabel();
 }
 
 PolicyEntry::PolicyEntry() {
@@ -111,6 +107,10 @@ PolicyEntry::PolicyEntry() {
                                   security_manager_policy_entry_new(&m_entry));
 }
 
+PolicyEntry::PolicyEntry(PolicyEntry &&other) : m_entry(std::move(other.m_entry)) {
+    other.m_entry = nullptr;
+}
+
 PolicyEntry::~PolicyEntry() {
     security_manager_policy_entry_free(m_entry);
 }
@@ -120,6 +120,11 @@ void PolicyEntry::setApp(const std::string &appId) {
                    security_manager_policy_entry_set_application(m_entry, appId.c_str()));
 }
 
+void PolicyEntry::setUser(const std::string &user) {
+    throwOnSMError("security_manager_policy_entry_set_user",
+                   security_manager_policy_entry_set_user(m_entry, user.c_str()));
+}
+
 void PolicyEntry::setPrivilege(const std::string &privilege) {
     throwOnSMError("security_manager_policy_entry_set_privilege",
                    security_manager_policy_entry_set_privilege(m_entry, privilege.c_str()));
@@ -136,12 +141,14 @@ PolicyRequest::PolicyRequest() {
 }
 
 PolicyRequest::~PolicyRequest() {
+    m_entries.clear();
     security_manager_policy_update_req_free(m_req);
 }
 
-void PolicyRequest::addEntry(const PolicyEntry &entry) {
+void PolicyRequest::addEntry(PolicyEntry &&entry) {
     throwOnSMError("security_manager_policy_update_req_add_entry",
                    security_manager_policy_update_req_add_entry(m_req, entry.get()));
+    m_entries.emplace_back(std::move(entry));
 }
 
 void PolicyRequest::updatePolicy() {
similarity index 78%
rename from src/agent/notification-daemon/Policy.h
rename to src/common/policy/Policy.h
index 24e114f..9b9db55 100644 (file)
 
 #pragma once
 
-#include <security-manager.h>
-
 #include <string>
+#include <vector>
+
+struct policy_entry;
+struct policy_update_req;
 
 namespace AskUser {
 
-void identifyApp(const std::string &client, std::string &appId, std::string &pkgLabel);
+void identifyApp(const std::string &client, const std::string &user,
+                 std::string &appId, std::string &pkgLabel);
 
 class PolicyEntry {
 public:
     PolicyEntry();
+    PolicyEntry(PolicyEntry &&other);
     ~PolicyEntry();
     void setApp(const std::string &appId);
+    void setUser(const std::string &user);
     void setPrivilege(const std::string &privilege);
     void setLevel(const std::string &level);
 
@@ -47,11 +52,12 @@ class PolicyRequest {
 public:
     PolicyRequest();
     ~PolicyRequest();
-    void addEntry(const PolicyEntry &entry);
+    void addEntry(PolicyEntry &&entry);
     void updatePolicy();
 
 private:
     policy_update_req *m_req;
+    std::vector<PolicyEntry> m_entries;
 };
 
 } /* namespace AskUser */
similarity index 85%
rename from src/agent/notification-daemon/PrivilegeInfo.cpp
rename to src/common/policy/PrivilegeInfo.cpp
index 2fdae69..1ab529e 100644 (file)
@@ -43,18 +43,11 @@ namespace PrivilegeInfo {
 
 std::string getPrivacyDisplayName(const std::string &privilege) {
     char *displayName = nullptr;
-    char *privacy = nullptr;
-    int res = privilege_info_get_privacy_by_privilege(privilege.c_str(), &privacy);
-    if (res != PRVMGR_ERR_NONE || !privacy) {
-        ALOGE("Unable to get privacy name for: <" << privilege << ">, err: <" << res << ">");
+    int ret = privilege_info_get_privacy_display(getPrivacyName(privilege).c_str(), &displayName);
+    if (ret != PRVMGR_ERR_NONE || !displayName) {
+        ALOGE("Unable to get privacy display name for <" << privilege << ">, err: <" << ret << ">");
         return privilege;
     }
-    res = privilege_info_get_privacy_display(privacy, &displayName);
-    if (res != PRVMGR_ERR_NONE || !displayName) {
-        ALOGE("Unable to get privacy display name for <" << privacy << ">, err: <" << res << ">");
-        return privilege;
-    }
-    free(privacy);
     std::unique_ptr<char, decltype(free)*> displaNamePtr(displayName, free);
     return displayName;
 }