[Release] wrt-installer_0.1.4 for sdk branch
[framework/web/wrt-installer.git] / src / 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
28 using namespace WrtDB;
29
30 namespace Logic {
31 InstallerLogic::InstallerLogic() :
32     m_NextHandle(0)
33 {}
34
35 InstallerLogic::~InstallerLogic()
36 {
37     Assert(m_jobs.empty() && "There are still running jobs");
38     //FIXME what should be done here?
39 }
40
41 void InstallerLogic::Initialize()
42 {
43     LogDebug("Done");
44 }
45
46 void InstallerLogic::Terminate()
47 {
48     //TODO how to delete, if it is still running, paused and so on
49     FOREACH(it, m_jobs)
50     {
51         it->second->SetPaused(true); //FIXME this is not enough!
52     }
53
54     LogDebug("Done");
55 }
56
57 Jobs::JobHandle InstallerLogic::AddAndStartJob(Jobs::Job *job)
58 {
59     Jobs::JobHandle handle = GetNewJobHandle();
60     job->SetJobHandle(handle);
61
62     m_jobs.insert(std::make_pair(handle, job));
63
64     //Start job
65     CONTROLLER_POST_EVENT(InstallerController,
66                           InstallerControllerEvents::NextStepEvent(job));
67
68     return handle;
69 }
70
71 //InstallWidget, UninstallWidget InstallPlugin method are almost the same
72 // But each Job has different constructor, so creating new Job is specific
73 Jobs::JobHandle InstallerLogic::InstallWidget(
74     const std::string & widgetPath,
75     const WidgetInstallationStruct &
76     installerStruct)
77 {
78     LogDebug("New Widget Installation:");
79
80     Jobs::Job *job =
81         new Jobs::WidgetInstall::JobWidgetInstall(widgetPath, installerStruct);
82
83     return AddAndStartJob(job);
84 }
85
86 Jobs::JobHandle InstallerLogic::UninstallWidget(
87     const std::string & widgetPkgName,
88     const
89     WidgetUninstallationStruct &uninstallerStruct)
90 {
91     LogDebug("New Widget Uninstallation");
92
93     Jobs::Job *job =
94         new Jobs::WidgetUninstall::JobWidgetUninstall(widgetPkgName,
95                                                       uninstallerStruct);
96
97     return AddAndStartJob(job);
98 }
99
100 Jobs::JobHandle InstallerLogic::InstallPlugin(
101     std::string const & pluginPath,
102     const PluginInstallerStruct &
103     installerStruct)
104 {
105     LogDebug("New Plugin Installation");
106
107     Jobs::Job *job =
108         new Jobs::PluginInstall::JobPluginInstall(pluginPath, installerStruct);
109     // before start install plugin, reset plugin data which is stopped
110     // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS)
111     ResetProgressPlugins();
112     return AddAndStartJob(job);
113 }
114
115 #define TRANSLATE_JOB_EXCEPTION() \
116     _rethrown_exception.getParam()
117 #define TRANSLATE_JOB_MESSAGE() \
118     _rethrown_exception.GetMessage()
119
120 bool InstallerLogic::NextStep(Jobs::Job *job)
121 {
122     Try {
123         bool stepSucceded = job->NextStep();
124
125         job->SendProgress();
126
127         if (stepSucceded) {
128             return !job->IsPaused();
129         }
130
131         if (!job->GetUndoType()) {
132             //job successfully finished
133
134             //send finished callback
135             job->SendFinishedSuccess();
136
137             switch (job->GetInstallationType()) {
138             case Jobs::PluginInstallation:
139                 //todo move it somewhere
140                 InstallWaitingPlugins();
141                 break;
142             default: //because of warning
143                 break;
144             }
145         } else {
146             //job abort process completed
147             job->SendFinishedFailure();
148         }
149
150         //clean job
151         m_jobs.erase(job->GetJobHandle());
152         delete job;
153
154         return false;
155     } catch (Jobs::JobExceptionBase &exc) {
156         //start revert job
157         LogInfo("Exception occured: " << exc.getParam() <<
158                 ". Reverting job...");
159         bool hasAbortSteps = job->Abort();
160         job->SetUndoType(true);
161         job->SaveExceptionData(exc);
162
163         if (!hasAbortSteps) {
164             //no AbortSteps
165             job->SendFinishedFailure();
166
167             //clean job
168             m_jobs.erase(job->GetJobHandle());
169             delete job;
170         }
171         return hasAbortSteps;
172     }
173 }
174
175 //TODO this should be moved somewhere...when it should take place? after widget
176 //is closing?
177 void InstallerLogic::InstallDeferredWidgetPackages()
178 {
179     LogWarning("Not implemented");
180     //    LogInfo("Installing deferred widget packages...");
181     //
182     //    WidgetPackageList packages =
183     // GlobalDAO::GetDefferedWidgetPackageInstallationList();
184     //
185     //    LogInfo(packages.size() << " widget package(s) to install");
186     //
187     //    // Make a copy of widget packages to install, because some
188     //    // widget packages may still fail because they are running
189     //    m_packagesToInstall = packages;
190     //
191     //    // Start processing
192     //    InstallSingleDeferredPackage();
193 }
194
195 void InstallerLogic::InstallSingleDeferredPackage()
196 {
197     LogWarning("Not implemented");
198     //    if (m_packagesToInstall.empty())
199     //        return;
200     //
201     //    // Take single package
202     //    DPL::String widgetPackage = m_packagesToInstall.front();
203     //    m_packagesToInstall.pop_front();
204     //
205     //    // Remove it from DB
206     //    GlobalDAO::RemoveDefferedWidgetPackageInstallation(widgetPackage);
207     //
208     //    // Begin installation
209     //    LogInfo("Installing deferred widget package: " << widgetPackage);
210     //
211     //    // Post installation
212     //    CONTROLLER_POST_EVENT(
213     //        InstallerController,
214     // InstallerControllerEvents::InstallWidgetEvent(
215     //            DPL::ToUTF8String(widgetPackage).c_str(),
216     // WidgetInstallationStruct(
217     //                    &DummyInstallCallback, &DummyProgressCallback, NULL,
218     //                        WidgetUpdateMode::PolicyWac)));
219 }
220
221 void InstallerLogic::InstallWaitingPlugins()
222 {
223     PluginHandleSetPtr waitingPlugins;
224
225     waitingPlugins =
226         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING);
227
228     FOREACH(it, *waitingPlugins)
229     {
230         resolvePluginDependencies(*it);
231     }
232 }
233
234 void InstallerLogic::ResetProgressPlugins()
235 {
236     PluginHandleSetPtr progressPlugins;
237
238     progressPlugins =
239         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_IN_PROGRESS);
240
241     FOREACH(it, *progressPlugins) {
242         FeatureHandleListPtr featureListPtr =
243             FeatureDAOReadOnly::GetFeatureHandleListForPlugin(*it);
244         FOREACH(ItFeature, *featureListPtr) {
245             FeatureDAO::UnregisterFeature(*ItFeature);
246         }
247         PluginDAO::unregisterPlugin(*it);
248     }
249 }
250
251 bool InstallerLogic::resolvePluginDependencies(PluginHandle handle)
252 {
253     PluginHandleSetPtr dependencies(new PluginHandleSet);
254
255     PluginObjects::ObjectsPtr requiredObjects =
256         PluginDAO::getRequiredObjectsForPluginHandle(handle);
257
258     PluginHandle depHandle =
259         Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE;
260
261     FOREACH(requiredObject, *requiredObjects)
262     {
263         depHandle =
264             PluginDAO::getPluginHandleForImplementedObject(*requiredObject);
265
266         if (depHandle ==
267             Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE)
268         {
269             LogError("Library implementing: " <<
270                      *requiredObject << " NOT FOUND");
271
272             //PluginDAO::SetPluginInstallationStatus(INSTALLATION_WAITING);
273             return false;
274         }
275         dependencies->insert(depHandle);
276     }
277
278     PluginDAO::registerPluginLibrariesDependencies(handle, dependencies);
279     PluginDAO::setPluginInstallationStatus(handle,
280                                            PluginDAO::INSTALLATION_COMPLETED);
281
282     return true;
283 }
284 }
285