2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 #include <PrivacyChecker.h>
\r
18 #include <PrivacyManagerClient.h>
\r
19 #include <SocketClient.h>
\r
20 #include <algorithm>
\r
24 #include <sqlite3.h>
\r
25 #include <dbus/dbus-glib-lowlevel.h>
\r
26 #include <sys/types.h>
\r
29 bool PrivacyChecker::m_isInitialized = false;
\r
30 std::map < std::string, bool >PrivacyChecker::m_privacyCache;
\r
31 std::map < std::string, std::map < std::string, bool > > PrivacyChecker::m_privacyInfoCache;
\r
32 std::mutex PrivacyChecker::m_cacheMutex;
\r
33 std::string PrivacyChecker::m_pkgId;
\r
34 DBusConnection* PrivacyChecker::m_pDBusConnection;
\r
35 GMainLoop* PrivacyChecker::m_pLoop = NULL;
\r
37 const int MAX_LOCAL_BUF_SIZE = 128;
\r
40 PrivacyChecker::initialize(const std::string pkgId)
\r
44 if (m_isInitialized)
\r
45 return PRIV_MGR_ERROR_SUCCESS;
\r
48 pthread_t signalThread;
\r
49 res = pthread_create(&signalThread, NULL, &runSignalListenerThread, NULL);
\r
50 TryReturn(res >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, errno = res;, "Failed to create listener thread :%s", strerror(res));
\r
53 res = updateCache(m_privacyCache);
\r
54 TryReturn(res == 0, res, m_pkgId.clear(), "Failed to update cache : %d", res);
\r
56 m_isInitialized = true;
\r
60 return PRIV_MGR_ERROR_SUCCESS;
\r
64 PrivacyChecker::runSignalListenerThread(void* pData)
\r
66 pthread_detach(pthread_self());
\r
67 LOGI("Running g main loop for signal");
\r
69 if (m_pLoop != NULL)
\r
72 m_pLoop = g_main_new(TRUE);
\r
76 g_main_loop_run(m_pLoop);
\r
86 PrivacyChecker::initializeDbus(void)
\r
90 dbus_error_init(&error);
\r
92 m_pDBusConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
\r
93 TryReturn(m_pDBusConnection != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, dbus_error_free(&error), "dbus_bus_get_private [%s] : %d", PRIV_MGR_ERROR_SYSTEM_ERROR);
\r
95 dbus_connection_setup_with_g_main(m_pDBusConnection, NULL);
\r
96 std::unique_ptr < char[] > pRule(new char[MAX_LOCAL_BUF_SIZE]);
\r
98 snprintf(pRule.get(), MAX_LOCAL_BUF_SIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH.c_str(), DBUS_SIGNAL_INTERFACE.c_str());
\r
99 dbus_bus_add_match(m_pDBusConnection, pRule.get(), &error);
\r
100 TryReturn(!dbus_error_is_set(&error), PRIV_MGR_ERROR_SYSTEM_ERROR, dbus_error_free(&error), "dbus_bus_add_match[%s] : %d", error.message, PRIV_MGR_ERROR_SYSTEM_ERROR);
\r
102 dbus_bool_t r = dbus_connection_add_filter(m_pDBusConnection, handleNotification, NULL, NULL);
\r
103 TryReturn(r, PRIV_MGR_ERROR_SYSTEM_ERROR, , "dbus_connection_add_filter: %d", PRIV_MGR_ERROR_SYSTEM_ERROR);
\r
107 return PRIV_MGR_ERROR_SUCCESS;
\r
111 PrivacyChecker::finalizeDbus(void)
\r
113 dbus_connection_remove_filter(m_pDBusConnection, handleNotification, NULL);
\r
114 dbus_connection_close(m_pDBusConnection);
\r
115 m_pDBusConnection = NULL;
\r
117 return PRIV_MGR_ERROR_SUCCESS;
\r
122 PrivacyChecker::handleNotification(DBusConnection* connection, DBusMessage* message, void* user_data)
\r
126 dbus_error_init(&error);
\r
131 if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE.c_str(), DBUS_SIGNAL_NAME.c_str()))
\r
133 r = dbus_message_get_args(message, &error,
\r
134 DBUS_TYPE_STRING, &pPkgId,
\r
135 DBUS_TYPE_STRING, &pPrivacyId,
\r
136 DBUS_TYPE_INVALID);
\r
137 TryReturn(r, DBUS_HANDLER_RESULT_NOT_YET_HANDLED, , "Fail to get data : %s", error.message);
\r
139 std::lock_guard < std::mutex > guard(m_cacheMutex);
\r
141 if (std::string(pPkgId) == m_pkgId)
\r
143 LOGI("Current app pkg privacy information updated");
\r
144 updateCache(pPrivacyId, m_privacyCache);
\r
148 std::map < std::string, std::map < std::string, bool > > :: iterator iter = m_privacyInfoCache.find(std::string(pPkgId));
\r
149 if (iter != m_privacyInfoCache.end())
\r
151 updateCache(pPrivacyId, iter->second);
\r
157 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
\r
160 return DBUS_HANDLER_RESULT_HANDLED;
\r
164 PrivacyChecker::check(const std::string privacyId)
\r
168 std::lock_guard < std::mutex > guard(m_cacheMutex);
\r
170 int ret = check(privacyId, m_privacyCache);
\r
178 PrivacyChecker::check(const std::string privacyId, std::map < std::string, bool >& privacyMap)
\r
182 TryReturn(m_isInitialized, PRIV_MGR_ERROR_NOT_INITIALIZED, , "Not initialized");
\r
184 std::map < std::string, bool >::const_iterator iter = privacyMap.find(privacyId);
\r
185 if (iter == privacyMap.end() )
\r
187 LOGD("NO matcheded");
\r
188 return PRIV_MGR_ERROR_USER_NOT_CONSENTED;
\r
190 else if (!iter->second)
\r
192 LOGD("NOT allowed");
\r
193 return PRIV_MGR_ERROR_USER_NOT_CONSENTED;
\r
197 return PRIV_MGR_ERROR_SUCCESS;
\r
201 PrivacyChecker::check(const std::string pkgId, const std::string privacyId)
\r
205 std::lock_guard < std::mutex > guard(m_cacheMutex);
\r
209 std::map < std::string, std::map < std::string, bool > >::iterator iter = m_privacyInfoCache.find(pkgId);
\r
210 if (iter == m_privacyInfoCache.end() )
\r
212 std::map < std::string, bool > pkgCacheMap;
\r
213 res = updateCache(pkgCacheMap);
\r
214 TryReturn( res == PRIV_MGR_ERROR_SUCCESS, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res);
\r
216 m_privacyInfoCache.insert( std::map < std::string, std::map < std::string, bool > >::value_type(std::string(pkgId), pkgCacheMap));
\r
218 iter = m_privacyInfoCache.find(pkgId);
\r
220 if (iter->second.size() == 0)
\r
221 return PRIV_MGR_ERROR_USER_NOT_CONSENTED;
\r
223 res = check(privacyId, iter->second);
\r
231 PrivacyChecker::finalize(void)
\r
233 std::lock_guard <std::mutex> guard (m_cacheMutex);
\r
234 m_privacyCache.clear();
\r
236 if (m_pLoop != NULL)
\r
238 g_main_loop_quit(m_pLoop);
\r
242 m_isInitialized = false;
\r
244 return PRIV_MGR_ERROR_SUCCESS;
\r
248 PrivacyChecker::printCache(void)
\r
250 std::map < std::string, bool >::const_iterator iter = m_privacyCache.begin();
\r
251 for (; iter != m_privacyCache.end(); ++iter)
\r
253 LOGD(" %s : %d", iter->first.c_str(), iter->second);
\r
258 PrivacyChecker::updateCache(const std::string privacyId, std::map < std::string, bool >& pkgCacheMap)
\r
261 static const std::string PrivacyQuery = "SELECT IS_ENABLED from PrivacyInfo where PKG_ID=? and PRIVACY_ID=?";
\r
263 openDb(PRIVACY_DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);
\r
264 prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);
\r
265 int res = sqlite3_bind_text(pPrivacyStmt.get(), 1, m_pkgId.c_str(), -1, SQLITE_TRANSIENT);
\r
266 TryReturn( res == 0, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res);
\r
268 res = sqlite3_bind_text(pPrivacyStmt.get(), 2, privacyId.c_str(), -1, SQLITE_TRANSIENT);
\r
269 TryReturn( res == 0, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res);
\r
271 while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW )
\r
273 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 0) > 0 ? true : false;
\r
275 std::lock_guard < std::mutex > guard(m_cacheMutex);
\r
276 pkgCacheMap.erase(privacyId);
\r
277 pkgCacheMap.insert(std::map < std::string, bool >::value_type(privacyId, privacyEnabled));
\r
282 return PRIV_MGR_ERROR_SUCCESS;
\r
287 PrivacyChecker::updateCache(std::map < std::string, bool >& pkgCacheMap)
\r
290 static const std::string PrivacyQuery = "SELECT PRIVACY_ID, IS_ENABLED from PrivacyInfo where PKG_ID=?";
\r
292 pkgCacheMap.clear();
\r
294 openDb(PRIVACY_DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);
\r
295 prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);
\r
296 int res = sqlite3_bind_text(pPrivacyStmt.get(), 1, m_pkgId.c_str(), -1, SQLITE_TRANSIENT);
\r
297 TryReturn( res == 0, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res);
\r
299 while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW )
\r
302 const char* privacyId = reinterpret_cast < const char* > (sqlite3_column_text(pPrivacyStmt.get(), 0));
\r
303 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 1) > 0 ? true : false;
\r
305 pkgCacheMap.insert(std::map < std::string, bool >::value_type(std::string(privacyId), privacyEnabled));
\r
307 LOGD("Privacy found : %s %d", privacyId, privacyEnabled);
\r
310 return PRIV_MGR_ERROR_SUCCESS;
\r