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