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