2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 #include "AppManagerWrapper.h"
19 #include <Commons/Exception.h>
20 #include <Commons/Regex.h>
22 // To get package id from appId
23 #include <package_manager.h>
24 #include <TimeTracer.h>
29 namespace Application {
32 using namespace WrtDeviceApis::Commons;
35 AppManagerWrapper::AppManagerWrapper() :
36 m_manager_handle(NULL),
41 AppManagerWrapper::~AppManagerWrapper()
43 if(m_manager_handle != NULL)
45 unregisterAppListChangedCallbacks();
49 void AppManagerWrapper::setCurrentAppId(std::string appId)
51 m_curr_app_id = appId;
54 std::string AppManagerWrapper::getCurrentAppId() const
60 void AppManagerWrapper::registerAppListChangedCallbacks(IAppManagerAppListChangedCallbacks *callbacks)
64 LoggerE("callback cannot be set to NULL.");
70 registerAppListChangedCallbacks();
73 m_callbacks.insert(callbacks);
76 void AppManagerWrapper::unregisterAppListChangedCallbacks(IAppManagerAppListChangedCallbacks *callbacks)
80 LoggerE("callback cannot be set to NULL.");
84 if(m_callbacks.size() == 0)
86 LoggerE("No callbacks are registered.");
90 AppListChangedCallbacksSet::iterator iter = m_callbacks.find(callbacks);
91 if(iter == m_callbacks.end())
93 LoggerE("Callback " << callbacks << " is not registered.");
97 m_callbacks.erase(iter);
99 if(m_callbacks.size() == 0)
101 unregisterAppListChangedCallbacks();
106 long AppManagerWrapper::getWatchIdAndInc()
108 return ++m_watchIdAcc;
112 bool AppManagerWrapper::app_callback(package_info_app_component_type_e comp_type, const char *app_id, void *user_data)
115 LoggerE("Callback is called. but no package name is passed. skip this request");
119 if(user_data == NULL) {
120 LoggerE("user data is not exist. skip this request");
124 AppManagerWrapper *appManager = (AppManagerWrapper *)user_data;
125 appManager->applist.push_back(app_id);
130 void AppManagerWrapper::appListChangedCallback(app_manger_event_type_e event_type, const char *pkgId, void *user_data)
132 if(user_data == NULL) {
133 LoggerE("user data is not exist. skip this request");
137 AppManagerWrapper *appManager = (AppManagerWrapper *)user_data;
139 if (event_type == APP_MANAGER_EVENT_UNINSTALLED) {
140 for (size_t i = 0; i < appManager->applist.size(); i++) {
141 appListAppUninstalled(appManager->applist.at(i).c_str());
144 package_info_h package_info;
146 int ret = package_manager_get_package_info(pkgId, &package_info);
147 if (ret != PACKAGE_MANAGER_ERROR_NONE) {
148 LoggerE("Cannot create package info");
152 ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_ALLAPP, app_callback, user_data);
153 if (ret != PACKAGE_MANAGER_ERROR_NONE) {
154 LoggerE("failed while getting appids");
155 package_info_destroy(package_info);
159 ret = package_info_destroy(package_info);
160 if (ret != PACKAGE_MANAGER_ERROR_NONE) {
161 LoggerE("Cannot destroy package info");
164 for (size_t i = 0; i < appManager->applist.size(); i++) {
167 case APP_MANAGER_EVENT_INSTALLED:
168 appListAppInstalled(appManager->applist.at(i).c_str());
170 case APP_MANAGER_EVENT_UPDATED:
171 appListAppUpdated(appManager->applist.at(i).c_str());
174 LoggerE("app_manager listener gave wrong event_type : " << event_type);
181 appManager->applist.clear();
185 void AppManagerWrapper::appListAppInstalled(const char *appId)
187 AppListChangedCallbacksSet::iterator iter = m_callbacks.begin();
188 for(; iter != m_callbacks.end(); iter++)
190 (*iter)->onAppManagerEventInstalled(appId);
194 void AppManagerWrapper::appListAppUninstalled(const char *appId)
196 AppListChangedCallbacksSet::iterator iter = m_callbacks.begin();
197 for(; iter != m_callbacks.end(); iter++)
199 (*iter)->onAppManagerEventUninstalled(appId);
203 void AppManagerWrapper::appListAppUpdated(const char *appId)
205 AppListChangedCallbacksSet::iterator iter = m_callbacks.begin();
206 for(; iter != m_callbacks.end(); iter++)
208 (*iter)->onAppManagerEventUpdated(appId);
213 int AppManagerWrapper::app_list_changed_cb_broker(int id, const char *type, const char *package, const char *key, const char *val, const void *msg, void *data)
215 static app_manger_event_type_e event_type;
217 if (!strcasecmp(key, "start")) {
218 if (!strcasecmp(val, "install")) {
219 event_type = APP_MANAGER_EVENT_INSTALLED;
220 } else if (!strcasecmp(val, "uninstall")) {
221 // After uninstallation, we cannot get app ids from package name.
222 // So, we have to store app ids which is included to target package.
223 package_info_h package_info;
225 int ret = package_manager_get_package_info(package, &package_info);
226 if (ret != PACKAGE_MANAGER_ERROR_NONE) {
227 LoggerE("Cannot create package info");
230 ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_ALLAPP, app_callback, data);
231 if (ret != PACKAGE_MANAGER_ERROR_NONE) {
232 LoggerE("failed while getting appids");
235 ret = package_info_destroy(package_info);
236 if (ret != PACKAGE_MANAGER_ERROR_NONE) {
237 LoggerE("Cannot destroy package info");
239 event_type = APP_MANAGER_EVENT_UNINSTALLED;
240 } else if (!strcasecmp(val, "update")) {
241 event_type = APP_MANAGER_EVENT_UPDATED;
243 } else if (!strcasecmp(key, "end") && !strcasecmp(val, "ok")) {
244 if (event_type >= 0) {
246 AppManagerWrapper *appManager = (AppManagerWrapper *)data;
247 appManager->appListChangedCallback(event_type, package, data);
252 return APP_MANAGER_ERROR_NONE;
256 void AppManagerWrapper::registerAppListChangedCallbacks()
258 if (m_manager_handle != NULL) {
259 LoggerW("Callback is already registered.");
263 TIME_TRACER_ITEM_BEGIN("(addAppInfoEventListener)pkgmgr_client_new", 0);
264 m_manager_handle = pkgmgr_client_new(PC_LISTENING);
265 TIME_TRACER_ITEM_END("(addAppInfoEventListener)pkgmgr_client_new", 0);
266 if (m_manager_handle == NULL) {
267 ThrowMsg(InvalidArgumentException, "Error while registering listener to app_manager");
270 TIME_TRACER_ITEM_BEGIN("(addAppInfoEventListener)pkgmgr_client_listen_status", 0);
271 pkgmgr_client_listen_status(m_manager_handle, app_list_changed_cb_broker, this);
272 TIME_TRACER_ITEM_END("(addAppInfoEventListener)pkgmgr_client_listen_status", 0);
275 void AppManagerWrapper::unregisterAppListChangedCallbacks()
277 if (m_manager_handle == NULL) {
278 LoggerE("No callback is registered");
282 TIME_TRACER_ITEM_BEGIN("(removeAppInfoEventListener)pkgmgr_client_free", 0);
283 pkgmgr_client_free(m_manager_handle);
284 TIME_TRACER_ITEM_END("(removeAppInfoEventListener)pkgmgr_client_free", 0);
285 m_manager_handle = NULL;
288 bool AppManagerWrapper::initializeAppInfo(ApplicationInformationPtr &appInfo)
292 char* packageId = NULL;
295 ret = package_manager_get_package_id_by_app_id(appInfo->getAppId().c_str(), &packageId);
296 if ((ret != PACKAGE_MANAGER_ERROR_NONE) || (packageId == NULL)) {
297 LoggerE("Fail to get package id");
299 // get installed size from package server (to solve smack issue)
300 pkgmgr_client *pc = pkgmgr_client_new(PC_REQUEST);
302 LoggerE("Fail to create pkgmgr client");
304 ret = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, PM_GET_TOTAL_SIZE, pc, NULL, packageId, NULL, NULL, NULL);
306 LoggerE("Fail to get installed size");
308 appInfo->setInstallSize(ret);
311 pkgmgr_client_free(pc);
320 // if error occured, retry? or not?
321 appInfo->setInitialize();
326 SINGLETON_IMPLEMENTATION(AppManagerWrapper)