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 <PrivacyManager.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 const std::string PrivacyChecker::DB_PATH("/opt/dbspace/.privacy.db");
\r
31 std::map < std::string, bool >PrivacyChecker::m_privacyCache;
\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::getUniqueIdFromPackageId(const std::string pkgId, int& uniqueId)
\r
43 std::string PkgIdQuery = std::string("SELECT UNIQUE_ID from PackageInfo where PKG_ID=?");
\r
46 openDb(DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);
\r
47 prepareDb(pDbH, PkgIdQuery.c_str(), pStmt);
\r
49 res = sqlite3_bind_text(pStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT);
\r
50 TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_IO_ERROR, , "sqlite3_bind_text : %d", res);
\r
52 res = sqlite3_step(pStmt.get());
\r
53 TryReturn( res == SQLITE_ROW, PRIV_MGR_ERROR_IO_ERROR, , "sqlite3_step : %d", res);
\r
55 uniqueId = sqlite3_column_int(pStmt.get(), 0);
\r
56 LOGI("%s : %d", pkgId.c_str(), uniqueId);
\r
59 return PRIV_MGR_ERROR_SUCCESS;
\r
63 PrivacyChecker::initialize(const std::string pkgId)
\r
67 if (m_isInitialized)
\r
68 return PRIV_MGR_ERROR_SUCCESS;
\r
71 pthread_t signalThread;
\r
72 res = pthread_create(&signalThread, NULL, &runSignalListenerThread, NULL);
\r
73 TryReturn(res >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, errno = res;, "Failed to create listener thread :%s", strerror(res));
\r
76 res = updateCache();
\r
77 TryReturn(res == 0, res, m_pkgId.clear(), "Failed to update cache : %d", res);
\r
79 m_isInitialized = true;
\r
83 return PRIV_MGR_ERROR_SUCCESS;
\r
87 PrivacyChecker::runSignalListenerThread(void* pData)
\r
89 pthread_detach(pthread_self());
\r
90 LOGI("Running g main loop for signal");
\r
92 if (m_pLoop != NULL)
\r
95 m_pLoop = g_main_new(TRUE);
\r
99 g_main_loop_run(m_pLoop);
\r
103 pthread_exit(NULL);
\r
109 PrivacyChecker::initializeDbus(void)
\r
113 dbus_error_init(&error);
\r
115 m_pDBusConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
\r
116 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
118 dbus_connection_setup_with_g_main(m_pDBusConnection, NULL);
\r
119 std::unique_ptr < char[] > pRule(new char[MAX_LOCAL_BUF_SIZE]);
\r
121 snprintf(pRule.get(), MAX_LOCAL_BUF_SIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH.c_str(), DBUS_SIGNAL_INTERFACE.c_str());
\r
122 dbus_bus_add_match(m_pDBusConnection, pRule.get(), &error);
\r
123 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
125 dbus_bool_t r = dbus_connection_add_filter(m_pDBusConnection, handleNotification, NULL, NULL);
\r
126 TryReturn(r, PRIV_MGR_ERROR_SYSTEM_ERROR, , "dbus_connection_add_filter: %d", PRIV_MGR_ERROR_SYSTEM_ERROR);
\r
130 return PRIV_MGR_ERROR_SUCCESS;
\r
134 PrivacyChecker::finalizeDbus(void)
\r
136 dbus_connection_remove_filter(m_pDBusConnection, handleNotification, NULL);
\r
137 dbus_connection_close(m_pDBusConnection);
\r
138 m_pDBusConnection = NULL;
\r
140 return PRIV_MGR_ERROR_SUCCESS;
\r
145 PrivacyChecker::handleNotification(DBusConnection* connection, DBusMessage* message, void* user_data)
\r
149 dbus_error_init(&error);
\r
154 if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE.c_str(), DBUS_SIGNAL_NAME.c_str()))
\r
156 r = dbus_message_get_args(message, &error,
\r
157 DBUS_TYPE_STRING, &pPkgId,
\r
158 DBUS_TYPE_STRING, &pPrivacyId,
\r
159 DBUS_TYPE_INVALID);
\r
160 TryReturn(r, DBUS_HANDLER_RESULT_NOT_YET_HANDLED, , "Fail to get data : %s", error.message);
\r
162 if (std::string(pPkgId) == m_pkgId)
\r
164 LOGI("Current app pkg privacy information updated");
\r
165 updateCache(pPrivacyId);
\r
171 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
\r
174 return DBUS_HANDLER_RESULT_HANDLED;
\r
178 PrivacyChecker::check(const std::string privacyId)
\r
182 std::lock_guard < std::mutex > guard(m_cacheMutex);
\r
184 TryReturn(m_isInitialized, -1, , "Not initialized");
\r
186 std::map < std::string, bool >::const_iterator iter = m_privacyCache.find(privacyId);
\r
187 if (iter == m_privacyCache.end() )
\r
189 LOGD("NO matcheded");
\r
192 else if (!iter->second)
\r
194 LOGD("NOT allowed");
\r
199 return PRIV_MGR_ERROR_SUCCESS;
\r
203 PrivacyChecker::finalize(void)
\r
205 std::lock_guard <std::mutex> guard (m_cacheMutex);
\r
206 m_privacyCache.clear();
\r
208 if (m_pLoop != NULL)
\r
210 g_main_loop_quit(m_pLoop);
\r
214 m_isInitialized = false;
\r
216 return PRIV_MGR_ERROR_SUCCESS;
\r
220 PrivacyChecker::updateCache(void)
\r
223 static const std::string PrivacyQuery = "SELECT PRIVACY_ID, IS_ENABLED from Privacy where ID=?";
\r
225 std::lock_guard < std::mutex > guard(m_cacheMutex);
\r
229 res = getUniqueIdFromPackageId(m_pkgId, id);
\r
230 TryReturn( res == 0, -1, , "getUniqueIdFromPackageId : %d", res);
\r
231 LOGD("id : %d" ,id);
\r
233 openDb(DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);
\r
234 prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);
\r
235 res = sqlite3_bind_int(pPrivacyStmt.get(), 1, id);
\r
236 TryReturn( res == 0, -1, , "sqlite3_bind_int : %d", res);
\r
239 while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW )
\r
242 const char* privacyId = reinterpret_cast < const char* > (sqlite3_column_text(pPrivacyStmt.get(), 0));
\r
243 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 1) > 0 ? true : false;
\r
245 m_privacyCache.insert(std::map < std::string, bool >::value_type(std::string(privacyId), privacyEnabled));
\r
247 LOGD("Privacy found : %s %d", privacyId, privacyEnabled);
\r
250 return PRIV_MGR_ERROR_SUCCESS;
\r
253 PrivacyChecker::printCache(void)
\r
255 std::map < std::string, bool >::const_iterator iter = m_privacyCache.begin();
\r
256 for (; iter != m_privacyCache.end(); ++iter)
\r
258 LOGD(" %s : %d", iter->first.c_str(), iter->second);
\r
262 PrivacyChecker::updateCache(const std::string privacyId)
\r
265 static const std::string PrivacyQuery = "SELECT IS_ENABLED from Privacy where ID=? and PRIVACY_ID=?";
\r
269 res = getUniqueIdFromPackageId(m_pkgId, id);
\r
270 TryReturn( res == 0, -1, , "getUniqueIdFromPackageId : %d", res);
\r
272 LOGD("id : %d" ,id);
\r
274 openDb(DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);
\r
275 prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);
\r
276 res = sqlite3_bind_int(pPrivacyStmt.get(), 1, id);
\r
277 TryReturn( res == 0, -1, , "sqlite3_bind_int : %d", res);
\r
279 res = sqlite3_bind_text(pPrivacyStmt.get(), 2, privacyId.c_str(), -1, SQLITE_TRANSIENT);
\r
280 TryReturn( res == 0, -1, , "sqlite3_bind_text : %d", res);
\r
282 while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW )
\r
284 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 0) > 0 ? true : false;
\r
286 std::lock_guard < std::mutex > guard(m_cacheMutex);
\r
287 m_privacyCache.erase(privacyId);
\r
288 m_privacyCache.insert(std::map < std::string, bool >::value_type(privacyId, privacyEnabled));
\r
293 return PRIV_MGR_ERROR_SUCCESS;
\r