2005f21dfbe81e70e95db3f463b41d76b4a46c8c
[framework/web/wrt-installer.git] / src / jobs / widget_uninstall / job_widget_uninstall.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <regex.h>
18 #include <sys/stat.h>
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_certificates.h>
28 #include <dpl/wrt-dao-ro/global_config.h>
29 #include <pkg-manager/pkgmgr_signal.h>
30 #include <app2ext_interface.h>
31
32 using namespace WrtDB;
33
34 namespace { //anonymous
35 const char* REG_TIZEN_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
36 const int PKGID_LENTH = 10;
37
38 bool checkDirectoryExist(const std::string& pkgId)
39 {
40     std::string installPath =
41         std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
42         "/" + pkgId;
43
44     struct stat dirStat;
45     if ((stat(installPath.c_str(), &dirStat) == 0)) {
46         return true;
47     }
48     return false;
49 }
50
51 class UninstallerTaskFail :
52     public DPL::TaskDecl<UninstallerTaskFail>
53 {
54   private:
55     bool m_uninstalled;
56
57     void StepFail()
58     {
59         if (m_uninstalled) {
60             ThrowMsg(Jobs::WidgetUninstall::Exceptions::WidgetNotExist,
61                      "Widget does not exist");
62         } else {
63             Throw(Jobs::WidgetUninstall::Exceptions::Base);
64         }
65     }
66
67   public:
68     UninstallerTaskFail(bool uninstalled) :
69         DPL::TaskDecl<UninstallerTaskFail>(this),
70         m_uninstalled(uninstalled)
71     {
72         AddStep(&UninstallerTaskFail::StepFail);
73     }
74 };
75 }
76
77 namespace Jobs {
78 namespace WidgetUninstall {
79 JobWidgetUninstall::JobWidgetUninstall(
80     const std::string & tizenAppId,
81     const WidgetUninstallationStruct &
82     uninstallerStruct) :
83     Job(Uninstallation),
84     JobContextBase<WidgetUninstallationStruct>(uninstallerStruct)
85 {
86     using namespace PackageManager;
87     m_context.removeStarted = false;
88     m_context.removeFinished = false;
89     m_context.removeAbnormal = false;
90     m_context.uninstallStep = UninstallerContext::UNINSTALL_START;
91     m_context.job = this;
92     m_context.isExternalWidget = getExternalWidgetFlag();
93
94     Try
95     {
96         WidgetStatus status = getWidgetStatus(tizenAppId);
97
98         if (WidgetStatus::Ok == status) {
99             WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(m_context.tzAppid));
100             m_context.tzPkgid = DPL::ToUTF8String(dao.getTizenPkgId());
101             m_context.locations = WidgetLocation(m_context.tzPkgid);
102             m_context.locations->registerAppid(m_context.tzAppid);
103
104             LogInfo("Widget model exists. App id : " << m_context.tzAppid);
105
106             AddTask(new TaskSmack(m_context));
107             AddTask(new TaskCheck(m_context));
108
109             if (dao.getPackagingType() == PKG_TYPE_HYBRID_WEB_APP) {
110                 AddTask(new TaskUninstallOspsvc(m_context));
111             }
112             AddTask(new TaskRemoveFiles(m_context));
113             AddTask(new TaskDbUpdate(m_context));
114             AddTask(new TaskRemoveCustomHandlers(m_context));
115             AddTask(new TaskDeleteCertificates(m_context));
116
117             // send start signal of pkgmgr
118             if (getInstallerStruct().pkgmgrInterface->setPkgname(m_context.tzPkgid))
119             {
120                 getInstallerStruct().pkgmgrInterface->sendSignal(
121                         PKGMGR_START_KEY,
122                         PKGMGR_START_UNINSTALL);
123             }
124         } else if (WidgetStatus::NOT_INSTALLED == status) {
125             AddTask(new UninstallerTaskFail(true));
126         } else if (WidgetStatus::ABNORMAL == status) {
127             m_context.locations = WidgetLocation(m_context.tzPkgid);
128             m_context.removeAbnormal = true;
129             AddTask(new TaskRemoveFiles(m_context));
130         } else {
131             AddTask(new UninstallerTaskFail(false));
132         }
133     } Catch(WidgetDAOReadOnly::Exception::Base) {
134         AddTask(new UninstallerTaskFail(false));
135     }
136 }
137
138 JobWidgetUninstall::WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id)
139 {
140     regex_t regx;
141     if(regcomp(&regx, REG_TIZEN_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
142         LogDebug("Regcomp failed");
143     }
144     std::string pkgId;
145
146     Try {
147         if ((regexec(&regx, id.c_str(),
148                         static_cast<size_t>(0), NULL, 0) == REG_NOERROR)) {
149             pkgId = id;
150
151             TizenAppId appid =
152                 WrtDB::WidgetDAOReadOnly::getTzAppId(
153                         DPL::FromUTF8String(id));
154             LogDebug("Get appid from pkgid : " << appid);
155             m_context.tzAppid = DPL::ToUTF8String(appid);
156         } else {
157             pkgId = id.substr(0, PKGID_LENTH);
158             WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(id));
159             m_context.tzAppid = id;
160         }
161     } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
162         LogDebug("package id : " << pkgId);
163         m_context.tzPkgid = pkgId;
164         if (!pkgId.empty()) {
165             if(checkDirectoryExist(pkgId)) {
166                 LogError("installed widget status is abnormal");
167                 return WidgetStatus::ABNORMAL;
168             }
169         }
170         return WidgetStatus::NOT_INSTALLED;
171     }
172     return WidgetStatus::Ok;
173 }
174
175 std::string JobWidgetUninstall::getRemovedTizenId() const
176 {
177     return m_context.tzAppid;
178 }
179
180 bool JobWidgetUninstall::getRemoveStartedFlag() const
181 {
182     return m_context.removeStarted;
183 }
184
185 bool JobWidgetUninstall::getRemoveFinishedFlag() const
186 {
187     return m_context.removeFinished;
188 }
189
190 void JobWidgetUninstall::SendProgress()
191 {
192     using namespace PackageManager;
193     if (!getRemoveStartedFlag() ||
194         (getRemoveStartedFlag() && getRemoveFinishedFlag()))
195     {
196         if (NULL != getInstallerStruct().progressCallback) {
197             // send progress signal of pkgmgr
198             std::ostringstream percent;
199             percent << static_cast<int>(GetProgressPercent());
200
201             LogDebug("Call widget uninstall progressCallback");
202             getInstallerStruct().progressCallback(
203                 getInstallerStruct().userParam,
204                 GetProgressPercent(), GetProgressDescription());
205         }
206     }
207 }
208
209 void JobWidgetUninstall::SendFinishedSuccess()
210 {
211     using namespace PackageManager;
212     // send signal of pkgmgr
213     getInstallerStruct().pkgmgrInterface->sendSignal(
214         PKGMGR_END_KEY,
215         PKGMGR_END_SUCCESS);
216
217     LogDebug("Call widget uninstall success finishedCallback");
218     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
219                                           getRemovedTizenId(),
220                                           Jobs::Exceptions::Success);
221 }
222
223 void JobWidgetUninstall::SendFinishedFailure()
224 {
225     using namespace PackageManager;
226     LogError("Error in uninstallation step: " << m_exceptionCaught);
227     LogError("Message: " << m_exceptionMessage);
228
229     // send signal of pkgmgr
230     getInstallerStruct().pkgmgrInterface->sendSignal(
231         PKGMGR_END_KEY,
232         PKGMGR_END_FAILURE);
233
234     LogDebug("Call widget uninstall failure finishedCallback");
235     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
236                                           getRemovedTizenId(),
237                                           m_exceptionCaught); //TODO
238     LogDebug("[JobWidgetUninstall] Asynchronous failure callback status sent");
239 }
240
241 void JobWidgetUninstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
242 {
243     m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
244     m_exceptionMessage = e.GetMessage();
245 }
246
247 bool JobWidgetUninstall::getExternalWidgetFlag() const
248 {
249     LogDebug("Get external widget");
250     if (APP2EXT_SD_CARD ==
251         app2ext_get_app_location(m_context.tzAppid.c_str()))
252     {
253         LogDebug("This widget is in external stroage");
254         return true;
255     }
256     return false;
257 }
258 } //namespace WidgetUninstall
259 } //namespace Jobs