Initialize Tizen 2.3
[framework/web/wrt-installer.git] / src_mobile / logic / installer_logic.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 #include <installer_logic.h>
17 #include <installer_controller.h>
18 #include <dpl/string.h>
19 #include <dpl/foreach.h>
20 #include <dpl/wrt-dao-rw/feature_dao.h>
21 #include <dpl/wrt-dao-rw/plugin_dao.h>
22 #include <widget_install/job_widget_install.h>
23 #include <widget_uninstall/job_widget_uninstall.h>
24 #include <plugin_install/job_plugin_install.h>
25 #include <job_exception_base.h>
26 #include <plugin_install/plugin_objects.h>
27 #include <installer_log.h>
28
29 using namespace WrtDB;
30
31 namespace Logic {
32 InstallerLogic::InstallerLogic() :
33     m_job(0),
34     m_NextHandle(0)
35 {}
36
37 InstallerLogic::~InstallerLogic()
38 {
39         Assert(!m_job && "There are still running job");
40     //FIXME what should be done here?
41 }
42
43 void InstallerLogic::Initialize()
44 {
45     _D("Done");
46 }
47
48 void InstallerLogic::Terminate()
49 {
50     //TODO how to delete, if it is still running, paused and so on
51     if(m_job)
52         m_job->SetPaused(true);
53
54     _D("Done");
55 }
56
57 Jobs::JobHandle InstallerLogic::AddAndStartJob()
58 {
59     Jobs::JobHandle handle = GetNewJobHandle();
60     m_job->SetJobHandle(handle);
61     //Start job
62     CONTROLLER_POST_EVENT(InstallerController,
63                           InstallerControllerEvents::NextStepEvent(m_job));
64
65     return handle;
66 }
67
68 //InstallWidget, UninstallWidget InstallPlugin method are almost the same
69 // But each Job has different constructor, so creating new Job is specific
70 Jobs::JobHandle InstallerLogic::InstallWidget(
71     const std::string & widgetPath,
72     const std::string & pkgId,
73     const Jobs::WidgetInstall::WidgetInstallationStruct &
74     installerStruct)
75 {
76     if(m_job)
77     {
78         _E("Job is in progress. It is impossible to add new job");
79         return -1;
80     }
81
82     _D("New Widget Installation:");
83
84     m_job = new Jobs::WidgetInstall::JobWidgetInstall(widgetPath, pkgId, installerStruct);
85
86     return AddAndStartJob();
87 }
88
89 Jobs::JobHandle InstallerLogic::UninstallWidget(
90     const std::string & widgetPkgName,
91     const
92     WidgetUninstallationStruct &uninstallerStruct)
93 {
94     if(m_job)
95     {
96         _E("Job is in progress. It is impossible to add new job");
97         return -1;
98     }
99
100     _D("New Widget Uninstallation");
101
102     m_job  =
103         new Jobs::WidgetUninstall::JobWidgetUninstall(widgetPkgName,
104                                                       uninstallerStruct);
105
106       return AddAndStartJob();
107 }
108
109 Jobs::JobHandle InstallerLogic::InstallPlugin(
110     std::string const & pluginPath,     // TODO change type to PluginPath
111     const PluginInstallerStruct &
112     installerStruct)
113 {
114     if(m_job)
115     {
116         _E("Job is in progress. It is impossible to add new job");
117         return -1;
118     }
119
120     _D("New Plugin Installation");
121
122     // TODO Conversion to PluginPath is temporary
123     m_job =
124         new Jobs::PluginInstall::JobPluginInstall(PluginPath(pluginPath), installerStruct);
125
126     // before start install plugin, reset plugin data which is stopped
127     // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS)
128     ResetProgressPlugins();
129
130     return AddAndStartJob();
131 }
132
133 #define TRANSLATE_JOB_EXCEPTION() \
134     _rethrown_exception.getParam()
135 #define TRANSLATE_JOB_MESSAGE() \
136     _rethrown_exception.GetMessage()
137
138 bool InstallerLogic::NextStep(Jobs::Job *job)
139 {
140     Try {
141         bool stepSucceded = job->NextStep();
142
143         job->SendProgress();
144
145         if (stepSucceded) {
146             return !job->IsPaused();
147         }
148
149         if (!job->GetAbortStarted()) {
150             //job successfully finished
151
152             //send finished callback
153             job->SendFinishedSuccess();
154
155             switch (job->GetInstallationType()) {
156             case Jobs::PluginInstallation:
157                 InstallWaitingPlugins();
158                 break;
159             default: //because of warning
160                 break;
161             }
162         } else {
163             //job abort process completed
164             job->SendFinishedFailure();
165         }
166
167         //clean job
168         delete job;
169         m_job=0;
170
171         return false;
172     } catch (Jobs::JobExceptionBase &exc) {
173         //start revert job
174         _D("Exception occured: %d. Reverting job...", exc.getParam());
175         bool hasAbortSteps = job->Abort();
176         job->SetAbortStarted(true);
177         job->SaveExceptionData(exc);
178
179         if (!hasAbortSteps) {
180             //no AbortSteps
181             job->SendFinishedFailure();
182
183             //clean job
184             delete job;
185             m_job=0;
186         }
187         return hasAbortSteps;
188     }
189 }
190
191 void InstallerLogic::InstallWaitingPlugins()
192 {
193     PluginHandleSetPtr waitingPlugins;
194
195     waitingPlugins =
196         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING);
197
198     FOREACH(it, *waitingPlugins)
199     {
200         resolvePluginDependencies(*it);
201     }
202 }
203
204 void InstallerLogic::ResetProgressPlugins()
205 {
206     PluginHandleSetPtr progressPlugins;
207
208     progressPlugins =
209         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_IN_PROGRESS);
210
211     FOREACH(it, *progressPlugins) {
212         FeatureHandleListPtr featureListPtr =
213             FeatureDAOReadOnly::GetFeatureHandleListForPlugin(*it);
214         FOREACH(ItFeature, *featureListPtr) {
215             FeatureDAO::UnregisterFeature(*ItFeature);
216         }
217         PluginDAO::unregisterPlugin(*it);
218     }
219 }
220
221 bool InstallerLogic::resolvePluginDependencies(PluginHandle handle)
222 {
223     PluginHandleSetPtr dependencies(new PluginHandleSet);
224
225     PluginObjects::ObjectsPtr requiredObjects =
226         PluginDAO::getRequiredObjectsForPluginHandle(handle);
227
228     PluginHandle depHandle =
229         Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE;
230
231     FOREACH(requiredObject, *requiredObjects)
232     {
233         depHandle =
234             PluginDAO::getPluginHandleForImplementedObject(*requiredObject);
235
236         if (depHandle ==
237             Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE)
238         {
239             _E("Library implementing: %s NOT FOUND", (*requiredObject).c_str());
240
241             //PluginDAO::SetPluginInstallationStatus(INSTALLATION_WAITING);
242             return false;
243         }
244         dependencies->insert(depHandle);
245     }
246
247     PluginDAO::registerPluginLibrariesDependencies(handle, dependencies);
248     PluginDAO::setPluginInstallationStatus(handle,
249                                            PluginDAO::INSTALLATION_COMPLETED);
250
251     return true;
252 }
253 }
254