WidgetHandle removal - part 2. Task order change
[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 Jobs::JobHandle InstallerLogic::InstallWidget(const std::string & widgetPath,
76         const WidgetInstallationStruct &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(const std::string & widgetPkgName,
87         const WidgetUninstallationStruct &uninstallerStruct)
88 {
89     LogDebug("New Widget Uninstallation");
90
91     Jobs::Job *job =
92         new Jobs::WidgetUninstall::JobWidgetUninstall(widgetPkgName,
93                                                       uninstallerStruct);
94
95     return AddAndStartJob(job);
96 }
97
98 Jobs::JobHandle InstallerLogic::InstallPlugin(std::string const & pluginPath,
99         const PluginInstallerStruct &installerStruct)
100 {
101     LogDebug("New Plugin Installation");
102
103     Jobs::Job *job =
104         new Jobs::PluginInstall::JobPluginInstall(pluginPath, installerStruct);
105     // before start install plugin, reset plugin data which is stopped
106     // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS)
107     ResetProgressPlugins();
108     return AddAndStartJob(job);
109 }
110
111 #define TRANSLATE_JOB_EXCEPTION() \
112     _rethrown_exception.getParam()
113 #define TRANSLATE_JOB_MESSAGE() \
114     _rethrown_exception.GetMessage()
115
116 bool InstallerLogic::NextStep(Jobs::Job *job)
117 {
118     Try {
119         bool stepSucceded = job->NextStep();
120
121         job->SendProgress();
122
123         if (stepSucceded) {
124             return !job->IsPaused();
125         }
126
127         if (!job->GetUndoType()) {
128             //job successfully finished
129
130             //send finished callback
131             job->SendFinishedSuccess();
132
133             switch (job->GetInstallationType()) {
134             case Jobs::PluginInstallation:
135                 //todo move it somewhere
136                 InstallWaitingPlugins();
137                 break;
138             default: //because of warning
139                 break;
140             }
141         } else {
142             //job abort process completed
143             job->SendFinishedFailure();
144         }
145
146         //clean job
147         m_jobs.erase(job->GetJobHandle());
148         delete job;
149
150         return false;
151     }
152     catch (Jobs::JobExceptionBase &exc) {
153         //start revert job
154         LogInfo("Exception occured: " << exc.getParam() <<
155                 ". Reverting job...");
156         bool hasAbortSteps = job->Abort();
157         job->SetUndoType(true);
158         job->SaveExceptionData(exc);
159
160         if (!hasAbortSteps) {
161             //no AbortSteps
162             job->SendFinishedFailure();
163
164             //clean job
165             m_jobs.erase(job->GetJobHandle());
166             delete job;
167         }
168         return hasAbortSteps;
169     }
170 }
171
172 //TODO this should be moved somewhere...when it should take place? after widget
173 //is closing?
174 void InstallerLogic::InstallDeferredWidgetPackages()
175 {
176     LogWarning("Not implemented");
177     //    LogInfo("Installing deferred widget packages...");
178     //
179     //    WidgetPackageList packages = GlobalDAO::GetDefferedWidgetPackageInstallationList();
180     //
181     //    LogInfo(packages.size() << " widget package(s) to install");
182     //
183     //    // Make a copy of widget packages to install, because some
184     //    // widget packages may still fail because they are running
185     //    m_packagesToInstall = packages;
186     //
187     //    // Start processing
188     //    InstallSingleDeferredPackage();
189 }
190
191 void InstallerLogic::InstallSingleDeferredPackage()
192 {
193     LogWarning("Not implemented");
194     //    if (m_packagesToInstall.empty())
195     //        return;
196     //
197     //    // Take single package
198     //    DPL::String widgetPackage = m_packagesToInstall.front();
199     //    m_packagesToInstall.pop_front();
200     //
201     //    // Remove it from DB
202     //    GlobalDAO::RemoveDefferedWidgetPackageInstallation(widgetPackage);
203     //
204     //    // Begin installation
205     //    LogInfo("Installing deferred widget package: " << widgetPackage);
206     //
207     //    // Post installation
208     //    CONTROLLER_POST_EVENT(
209     //        InstallerController, InstallerControllerEvents::InstallWidgetEvent(
210     //            DPL::ToUTF8String(widgetPackage).c_str(), WidgetInstallationStruct(
211     //                    &DummyInstallCallback, &DummyProgressCallback, NULL,
212     //                        WidgetUpdateMode::PolicyWac)));
213 }
214
215 void InstallerLogic::InstallWaitingPlugins()
216 {
217     PluginHandleSetPtr waitingPlugins;
218
219     waitingPlugins =
220         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING);
221
222     FOREACH(it, *waitingPlugins)
223     {
224         resolvePluginDependencies(*it);
225     }
226 }
227
228 void InstallerLogic::ResetProgressPlugins()
229 {
230     PluginHandleSetPtr progressPlugins;
231
232     progressPlugins =
233         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_IN_PROGRESS);
234
235     FOREACH(it, *progressPlugins) {
236         FeatureHandleListPtr featureListPtr =
237             FeatureDAOReadOnly::GetFeatureHandleListForPlugin(*it);
238         FOREACH(ItFeature, *featureListPtr) {
239             FeatureDAO::UnregisterFeature(*ItFeature);
240         }
241         PluginDAO::unregisterPlugin(*it);
242     }
243 }
244
245 bool InstallerLogic::resolvePluginDependencies(PluginHandle handle)
246 {
247     PluginHandleSetPtr dependencies(new PluginHandleSet);
248
249     PluginObjects::ObjectsPtr requiredObjects =
250         PluginDAO::getRequiredObjectsForPluginHandle(handle);
251
252     PluginHandle depHandle =
253         Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE;
254
255     FOREACH(requiredObject, *requiredObjects)
256     {
257         depHandle =
258             PluginDAO::getPluginHandleForImplementedObject(*requiredObject);
259
260         if (depHandle ==
261             Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE) {
262             LogError("Library implementing: " <<
263                      *requiredObject << " NOT FOUND");
264
265             //PluginDAO::SetPluginInstallationStatus(INSTALLATION_WAITING);
266             return false;
267         }
268         dependencies->insert(depHandle);
269     }
270
271     PluginDAO::registerPluginLibrariesDependencies(handle, dependencies);
272     PluginDAO::setPluginInstallationStatus(handle,
273                                            PluginDAO::INSTALLATION_COMPLETED);
274
275     return true;
276 }
277
278 }
279