Fix prevent issue
[platform/framework/native/installer.git] / src / Step / UninstallStep.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17 /**
18  * @file        UninstallStep.cpp
19  * @brief       This is the implementation file for %UninstallStep class.
20  */
21
22 #include <unique_ptr.h>
23
24 #include <app2ext_interface.h>
25
26 #include <FIoDirectory.h>
27 #include <FIo_FileImpl.h>
28 #include <FBase_StringConverter.h>
29 #include <FAppPkg_PackageInfoImpl.h>
30
31 #include "InstallationContext.h"
32 #include "UninstallStep.h"
33 #include "InstallerUtil.h"
34 #include "CompatibilityManager.h"
35 #include "DeviceManager.h"
36
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Collection;
39 using namespace Tizen::App;
40 using namespace Tizen::App::Package;
41 using namespace Tizen::Io;
42
43 UninstallStep::UninstallStep(void)
44 :__state(STATE_GET_PACKAGEINFO)
45 ,__pContext(null)
46 {
47 }
48
49 UninstallStep::~UninstallStep(void)
50 {
51 }
52
53 InstallerError
54 UninstallStep::Run(InstallationContext* pContext)
55 {
56         InstallerError error = INSTALLER_ERROR_NONE;
57         AppLog(" UninstallStep - START");
58
59         __pContext = pContext;
60
61         while (true)
62         {
63                 switch (__state)
64                 {
65                 case STATE_GET_PACKAGEINFO:
66                         AppLog("[STATE_GET_PACKAGEINFO]");
67                         error = OnStateGetPackageInfo();
68                         break;
69
70                 case STATE_POLICY_CHECK:
71                         AppLog("[STATE_POLICY_CHECK]");
72                         error = OnStatePolicyCheck();
73                         break;
74
75                 case STATE_TERMINATE_APP:
76                         AppLog("[STATE_TERMINATE_APP]");
77                         error = OnStateTerminateApp();
78                         break;
79
80                 case STATE_START_TIMER:
81                         AppLog("[STATE_START_TIMER]");
82                         error = OnStateStartTimer();
83                         break;
84
85                 case STATE_DELETE_DIR:
86                         AppLog("[STATE_DELETE_DIR]");
87                         error = OnStateRemoveDir();
88                         break;
89
90                 case STATE_DONE:
91                         AppLog("[STATE_DONE]");
92                         error = OnStateDone();
93                         break;
94
95                 default:
96                         break;
97                 }
98
99                 if (error != INSTALLER_ERROR_NONE)
100                 {
101                         break;
102                 }
103
104                 if (__state > STATE_DONE)
105                 {
106                         AppLog(" UninstallStep - END");
107                         break;
108                 }
109         }
110
111         return error;
112 }
113
114 void
115 UninstallStep::GoNextState(void)
116 {
117         __state++;
118 }
119
120 InstallerError
121 UninstallStep::OnStateGetPackageInfo(void)
122 {
123         InstallerError error = INSTALLER_ERROR_NONE;
124         PackageId packageId = __pContext->__packageId;
125
126         std::unique_ptr< _PackageInfoImpl > pPackageInfoImpl(new (std::nothrow) _PackageInfoImpl());
127         TryReturn(pPackageInfoImpl, INSTALLER_ERROR_OUT_OF_MEMORY, "pPackageInfoImpl is null.");
128
129         AppLog("package = %ls", packageId.GetPointer());
130
131         result r = pPackageInfoImpl->Construct(packageId);
132         TryReturn(r == E_SUCCESS, INSTALLER_ERROR_INTERNAL_STATE, "pPackageInfoImpl->Construct(%ls) failed.", packageId.GetPointer());
133
134 //      bool isUninstallable = pPackageInfoImpl->IsUninstallable();
135 //      if (isUninstallable == false)
136 //      {
137 //              __pContext->__additionalErrorString = L"Thrown when the application cannot be uninstalled because the application was preloaded.";
138 //      }
139 //      TryReturn(isUninstallable == true, INSTALLER_ERROR_PACKAGE_INVALID, "preload app cannot be uninstalled.");
140
141         String rwXmlPath;
142         rwXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, packageId.GetPointer());
143         if (File::IsFileExist(rwXmlPath) == false)
144         {
145                 AppLog("This is a preload app = [%ls]", rwXmlPath.GetPointer());
146                 __pContext->__isPreloaded = true;
147         }
148
149         __pContext->__rootPath = pPackageInfoImpl->GetAppRootPath();
150
151         if (__pContext->__isHybridService == true)
152         {
153                 AppLog("Uninstallation for HybridService");
154                 __state = STATE_TERMINATE_APP;
155                 return error;
156         }
157
158         if (pPackageInfoImpl->IsInstalledInExternalStorage() == true)
159         {
160                 int res = 0;
161                 app2ext_handle* pHandle = null;
162
163                 std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
164                 TryReturn(pPackageId, INSTALLER_ERROR_INTERNAL_STATE, "pAppId is null");
165
166                 pHandle = app2ext_init(APP2EXT_SD_CARD);
167                 TryReturn(pHandle, INSTALLER_ERROR_INTERNAL_STATE, "app2ext_init() failed");
168
169                 res = pHandle->interface.pre_uninstall(pPackageId.get());
170                 TryReturn(res == 0, INSTALLER_ERROR_INTERNAL_STATE, "pHandle->interface.pre_uninstall() failed [%d]", res);
171
172                 __pContext->__pApp2ExtHandle = (void*)pHandle;
173
174                 AppLog("[app2sd] pre_uninstall(%s)", pPackageId.get());
175         }
176
177         std::unique_ptr< ArrayList > pList(pPackageInfoImpl->GetAppInfoListN());
178         TryReturn(pList, INSTALLER_ERROR_DATABASE, "pList is null.");
179
180         for (int i = 0; i < pList.get()->GetCount(); i++)
181         {
182                 _PackageAppInfoImpl* pAppInfoImpl = dynamic_cast<_PackageAppInfoImpl*>(pList.get()->GetAt(i));
183                 if (pAppInfoImpl)
184                 {
185                         std::unique_ptr< AppData > pAppData(new (std::nothrow) AppData);
186                         TryReturn(pAppData, INSTALLER_ERROR_OUT_OF_MEMORY, "pAppData is null.");
187
188                         error = pAppData.get()->Construct();
189                         TryReturn(error == INSTALLER_ERROR_NONE, INSTALLER_ERROR_INTERNAL_STATE, "pAppData.get()->Construct() failed.");
190
191                         pAppData.get()->__appId = pAppInfoImpl->GetPackageName();
192                         pAppData.get()->__feature = pAppInfoImpl->GetAppFeature();
193
194                         __pContext->__pAppDataList->Add(pAppData.release());
195                 }
196         }
197
198         GoNextState();
199         return error;
200 }
201
202 InstallerError
203 UninstallStep::OnStatePolicyCheck(void)
204 {
205         InstallerError error = INSTALLER_ERROR_NONE;
206
207         DeviceManager deviceManager;
208         deviceManager.Construct(__pContext);
209
210         bool res = deviceManager.IsUninstallationDisabled();
211         TryReturn(res == false, INSTALLER_ERROR_DISABLED, "IsUninstallationDisabled() failed.");
212
213         GoNextState();
214         return error;
215 }
216
217 InstallerError
218 UninstallStep::OnStateTerminateApp(void)
219 {
220         InstallerError error = INSTALLER_ERROR_NONE;
221
222         InstallerUtil::TerminateApps(__pContext->__packageId);
223
224         GoNextState();
225         return error;
226 }
227
228 InstallerError
229 UninstallStep::OnStateStartTimer(void)
230 {
231         InstallerError error = INSTALLER_ERROR_NONE;
232
233         GoNextState();
234         return error;
235 }
236
237 InstallerError
238 UninstallStep::OnStateRemoveDir(void)
239 {
240         InstallerError error = INSTALLER_ERROR_NONE;
241         bool res = true;
242
243         CompatibilityManager compatibilityManager;
244         compatibilityManager.Construct(__pContext);
245
246         String rootPath;
247         rootPath = __pContext->__rootPath;
248         AppLog("rootPath = [%ls]", rootPath.GetPointer());
249
250         String compatPath(rootPath);
251         compatPath.Append(L"/info/compat.info");
252         bool ospCompat = File::IsFileExist(compatPath);
253         result r = GetLastResult();
254         if (r == E_SUCCESS && ospCompat == true)
255         {
256                 if (compatibilityManager.FinalizeDataCaging(rootPath) == false)
257                 {
258                         AppLog("[Tizen::Io] Failed to unmount directories for 2.0 application, appRootPath: %ls",
259                                         rootPath.GetPointer());
260                         return INSTALLER_ERROR_UNMOUNT_FAILED;
261                 }
262         }
263         else if (r != E_SUCCESS)
264         {
265                 AppLog("[Tizen::Io] Failed to access %ls", compatPath.GetPointer());
266                 return INSTALLER_ERROR_UNMOUNT_FAILED;
267         }
268
269         compatibilityManager.CleanDirectories(rootPath, __pContext->__packageId);
270
271
272         String virtualRootInfoFile = rootPath + VIRTUAL_ROOT_INFO_FILE;
273         if (File::IsFileExist(virtualRootInfoFile) == true)
274         {
275                 res = compatibilityManager.FinalizeVirtualRoot(rootPath, __pContext->__packageId);
276                 TryReturn(res == true, INSTALLER_ERROR_UNMOUNT_FAILED, "compatibilityManager.FinalizeVirtualRoot(%ls) failed.", rootPath.GetPointer());
277         }
278
279         AppLog("Directory::Remove - START");
280
281         if (__pContext->__isHybridService == true)
282         {
283                 AppLog("Uninstallation for HybridService - skip Remove");
284
285         }
286         else
287         {
288                 String realPath;
289                 if (InstallerUtil::IsSymlink(rootPath) == true)
290                 {
291                         if (InstallerUtil::GetRealPath(rootPath, realPath) == true)
292                         {
293                                 InstallerUtil::Remove(realPath);
294                         }
295                 }
296
297                 InstallerUtil::Remove(rootPath);
298         }
299
300         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
301         TryReturn(pAppDataList, INSTALLER_ERROR_INTERNAL_STATE, "pAppDataList is null");
302
303         int count = pAppDataList->GetCount();
304         for (int i = 0; i < count; i++)
305         {
306                 AppData* pAppData = null;
307                 pAppDataList->GetAt(i, pAppData);
308
309                 if (pAppData)
310                 {
311                         if (pAppData->__feature == CATEGORY_TYPE_IME)
312                         {
313                                 String symlinkPath;
314                                 symlinkPath.Format(1024, L"%s/%ls.so", IME_PATH, pAppData->__appId.GetPointer());
315                                 InstallerUtil::Remove(symlinkPath);
316                         }
317                 }
318         }
319
320         AppLog("Directory::Remove - END");
321
322         GoNextState();
323         return error;
324 }
325
326 InstallerError
327 UninstallStep::OnStateDone(void)
328 {
329         InstallerError error = INSTALLER_ERROR_NONE;
330
331         GoNextState();
332         return error;
333 }