2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <widget_uninstall/job_widget_uninstall.h>
20 #include <widget_uninstall/widget_uninstall_errors.h>
21 #include <widget_uninstall/task_check.h>
22 #include <widget_uninstall/task_db_update.h>
23 #include <widget_uninstall/task_remove_files.h>
24 #include <widget_uninstall/task_remove_custom_handlers.h>
25 #include <widget_uninstall/task_smack.h>
26 #include <widget_uninstall/task_uninstall_ospsvc.h>
27 #include <widget_uninstall/task_delete_pkginfo.h>
28 #include <dpl/wrt-dao-ro/global_config.h>
29 #include <pkg-manager/pkgmgr_signal.h>
30 #include <app2ext_interface.h>
31 #include <dpl/utils/path.h>
32 #include <installer_log.h>
34 using namespace WrtDB;
36 namespace { //anonymous
37 const char* REG_TIZEN_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
38 const int PKGID_LENTH = 10;
39 const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps");
41 bool checkDirectoryExist(const std::string& pkgId)
43 DPL::Utils::Path installPath(GlobalConfig::GetUserInstalledWidgetPath());
45 return installPath.Exists();
50 namespace WidgetUninstall {
52 class UninstallerTaskFail :
53 public DPL::TaskDecl<UninstallerTaskFail>
56 WidgetStatus m_status;
60 if (WidgetStatus::NOT_INSTALLED == m_status) {
61 ThrowMsg(Jobs::WidgetUninstall::Exceptions::WidgetNotExist,
62 "Widget does not exist");
63 } else if (WidgetStatus::PREALOAD == m_status) {
64 ThrowMsg(Jobs::WidgetUninstall::Exceptions::Unremovable,
65 "Widget cann't uninstall");
67 Throw(Jobs::WidgetUninstall::Exceptions::Base);
72 UninstallerTaskFail(WidgetStatus status) :
73 DPL::TaskDecl<UninstallerTaskFail>(this),
77 AddStep(&UninstallerTaskFail::StepFail);
81 JobWidgetUninstall::JobWidgetUninstall(
82 const std::string & tizenPkgId,
83 const WidgetUninstallationStruct &
86 JobContextBase<WidgetUninstallationStruct>(uninstallerStruct),
88 m_exceptionCaught(Jobs::Exceptions::Success)
90 using namespace PackageManager;
91 m_context.removeStarted = false;
92 m_context.removeFinished = false;
93 m_context.removeAbnormal = false;
94 m_context.uninstallStep = UninstallerContext::UNINSTALL_START;
99 WidgetStatus status = getWidgetStatus(tizenPkgId);
101 if (WidgetStatus::Ok == status) {
102 //TODO: check and save type
104 WrtDB::WidgetDAOReadOnly dao(*m_context.tzAppIdList.begin());
105 m_context.tzPkgid = DPL::ToUTF8String(dao.getTizenPkgId());
106 m_context.locations = WidgetLocation(m_context.tzPkgid);
107 m_context.locations->registerAppid(DPL::ToUTF8String(*m_context.tzAppIdList.begin()));
108 m_context.installedPath =
109 DPL::Utils::Path(*dao.getWidgetInstalledPath());
110 m_context.manifestFile = getManifestFile();
111 PackagingType packagingType = dao.getPackagingType();
113 _D("Widget model exists. Pkg id : %s", m_context.tzPkgid.c_str());
115 // send start signal of pkgmgr
116 if (GetInstallerStruct().pkgmgrInterface->setPkgname(m_context.tzPkgid))
118 GetInstallerStruct().pkgmgrInterface->startJob(InstallationType::Uninstallation);
121 AddTask(new TaskCheck(m_context));
122 if (packagingType == PKG_TYPE_HYBRID_WEB_APP) {
123 AddTask(new TaskUninstallOspsvc(m_context));
125 AddTask(new TaskDeletePkgInfo(m_context));
126 AddTask(new TaskDbUpdate(m_context));
127 AddTask(new TaskSmack(m_context));
129 AddTask(new TaskRemoveCustomHandlers(m_context));
130 AddTask(new TaskRemoveFiles(m_context));
131 } else if (WidgetStatus::NOT_INSTALLED == status ||
132 WidgetStatus::PREALOAD == status) {
133 AddTask(new UninstallerTaskFail(status));
134 } else if (WidgetStatus::ABNORMAL == status) {
135 m_context.locations = WidgetLocation(m_context.tzPkgid);
136 m_context.removeAbnormal = true;
137 AddTask(new TaskRemoveFiles(m_context));
139 AddTask(new UninstallerTaskFail(WidgetStatus::UNRECOGNIZED));
141 } Catch(WidgetDAOReadOnly::Exception::Base) {
142 AddTask(new UninstallerTaskFail(WidgetStatus::UNRECOGNIZED));
146 WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id)
149 if(regcomp(®x, REG_TIZEN_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
150 _D("Regcomp failed");
152 std::string pkgId = id;
153 DPL::Utils::Path installPath;
154 if ((regexec(®x, id.c_str(),
155 static_cast<size_t>(0), NULL, 0) != REG_NOERROR)) {
157 pkgId = id.substr(0, PKGID_LENTH);
159 //Service app cannot uninstall by appid
160 WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(id));
161 if( dao.getWidgetType().appType == APP_TYPE_TIZENWEBSERVICE ){
162 _E("Service app cannot uninstall by appid");
163 return WidgetStatus::NOT_INSTALLED;
167 m_context.tzAppIdList = WrtDB::WidgetDAOReadOnly::getTzAppIdList(DPL::FromUTF8String(pkgId));
168 if( m_context.tzAppIdList.empty() ){
169 if(checkDirectoryExist(pkgId)) {
170 _E("installed widget status is abnormal");
171 return WidgetStatus::ABNORMAL;
173 return WidgetStatus::NOT_INSTALLED;
175 return WidgetStatus::Ok;
178 std::string JobWidgetUninstall::getRemovedTizenId() const
183 bool JobWidgetUninstall::getRemoveStartedFlag() const
185 return m_context.removeStarted;
188 bool JobWidgetUninstall::getRemoveFinishedFlag() const
190 return m_context.removeFinished;
193 DPL::Utils::Path JobWidgetUninstall::getManifestFile() const
195 std::ostringstream manifest_name;
196 manifest_name << m_context.tzPkgid << ".xml";
197 DPL::Utils::Path manifestFile;
199 const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps/" + m_context.tzPkgid);
200 const DPL::Utils::Path USR_PACKAGES_PATH("/usr/share/packages");
201 const DPL::Utils::Path OPT_PACKAGES_PATH("/opt/share/packages");
203 if (PRELOAD_INSTALLED_PATH == m_context.installedPath) {
204 _D("This widget is preloaded.");
205 manifestFile = USR_PACKAGES_PATH;
207 manifestFile = OPT_PACKAGES_PATH;
210 manifestFile /= manifest_name.str();
211 _D("Manifest file : %s", manifestFile.Fullpath().c_str());
216 void JobWidgetUninstall::SendProgress()
218 using namespace PackageManager;
219 if (!getRemoveStartedFlag() ||
220 (getRemoveStartedFlag() && getRemoveFinishedFlag()))
222 if (NULL != GetInstallerStruct().progressCallback) {
223 // send progress signal of pkgmgr
224 std::ostringstream percent;
225 percent << static_cast<int>(GetProgressPercent());
227 _D("Call widget uninstall progressCallback");
228 GetInstallerStruct().progressCallback(
229 GetInstallerStruct().userParam,
230 GetProgressPercent(), GetProgressDescription());
235 void JobWidgetUninstall::SendFinishedSuccess()
237 using namespace PackageManager;
238 // send signal of pkgmgr
239 GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
241 _D("Call widget uninstall success finishedCallback");
242 GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
244 Jobs::Exceptions::Success);
247 void JobWidgetUninstall::SendFinishedFailure()
249 using namespace PackageManager;
251 LOGE(COLOR_ERROR "Error in uninstallation step: %d" COLOR_END, m_exceptionCaught);
252 LOGE(COLOR_ERROR "Message: %s" COLOR_END, m_exceptionMessage.c_str());
253 fprintf(stderr, "[Err:%d] %s", m_exceptionCaught, m_exceptionMessage.c_str());
255 // send signal of pkgmgr
256 GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
258 _D("Call widget uninstall failure finishedCallback");
259 GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
262 _D("[JobWidgetUninstall] Asynchronous failure callback status sent");
265 void JobWidgetUninstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
267 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
268 m_exceptionMessage = e.GetMessage();
270 } //namespace WidgetUninstall