Update wrt-installer_0.0.54
[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
107     return AddAndStartJob(job);
108 }
109
110 #define TRANSLATE_JOB_EXCEPTION() \
111     _rethrown_exception.getParam()
112 #define TRANSLATE_JOB_MESSAGE() \
113     _rethrown_exception.GetMessage()
114
115 bool InstallerLogic::NextStep(Jobs::Job *job)
116 {
117     Try {
118         bool stepSucceded = job->NextStep();
119
120         job->SendProgress();
121
122         if (stepSucceded) {
123             return !job->IsPaused();
124         }
125
126         if (!job->GetUndoType()) {
127             //job successfully finished
128
129             //send finished callback
130             job->SendFinishedSuccess();
131
132             switch (job->GetInstallationType()) {
133             case Jobs::PluginInstallation:
134                 //todo move it somewhere
135                 InstallWaitingPlugins();
136                 break;
137             default: //because of warning
138                 break;
139             }
140         } else {
141             //job abort process completed
142             job->SendFinishedFailure();
143         }
144
145         //clean job
146         m_jobs.erase(job->GetJobHandle());
147         delete job;
148
149         return false;
150     }
151     catch (Jobs::JobExceptionBase &exc) {
152         //start revert job
153         LogInfo("Exception occured: " << exc.getParam() <<
154                 ". Reverting job...");
155         bool hasAbortSteps = job->Abort();
156         job->SetUndoType(true);
157         job->SaveExceptionData(exc);
158
159         if (!hasAbortSteps) {
160             //no AbortSteps
161             job->SendFinishedFailure();
162
163             //clean job
164             m_jobs.erase(job->GetJobHandle());
165             delete job;
166         }
167         return hasAbortSteps;
168     }
169 }
170
171 //TODO this should be moved somewhere...when it should take place? after widget
172 //is closing?
173 void InstallerLogic::InstallDeferredWidgetPackages()
174 {
175     LogWarning("Not implemented");
176     //    LogInfo("Installing deferred widget packages...");
177     //
178     //    WidgetPackageList packages = GlobalDAO::GetDefferedWidgetPackageInstallationList();
179     //
180     //    LogInfo(packages.size() << " widget package(s) to install");
181     //
182     //    // Make a copy of widget packages to install, because some
183     //    // widget packages may still fail because they are running
184     //    m_packagesToInstall = packages;
185     //
186     //    // Start processing
187     //    InstallSingleDeferredPackage();
188 }
189
190 void InstallerLogic::InstallSingleDeferredPackage()
191 {
192     LogWarning("Not implemented");
193     //    if (m_packagesToInstall.empty())
194     //        return;
195     //
196     //    // Take single package
197     //    DPL::String widgetPackage = m_packagesToInstall.front();
198     //    m_packagesToInstall.pop_front();
199     //
200     //    // Remove it from DB
201     //    GlobalDAO::RemoveDefferedWidgetPackageInstallation(widgetPackage);
202     //
203     //    // Begin installation
204     //    LogInfo("Installing deferred widget package: " << widgetPackage);
205     //
206     //    // Post installation
207     //    CONTROLLER_POST_EVENT(
208     //        InstallerController, InstallerControllerEvents::InstallWidgetEvent(
209     //            DPL::ToUTF8String(widgetPackage).c_str(), WidgetInstallationStruct(
210     //                    &DummyInstallCallback, &DummyProgressCallback, NULL,
211     //                        WidgetUpdateMode::PolicyWac)));
212 }
213
214 void InstallerLogic::InstallWaitingPlugins()
215 {
216     PluginHandleSetPtr waitingPlugins;
217
218     waitingPlugins =
219         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING);
220
221     FOREACH(it, *waitingPlugins)
222     {
223         resolvePluginDependencies(*it);
224     }
225 }
226
227 bool InstallerLogic::resolvePluginDependencies(PluginHandle handle)
228 {
229     PluginHandleSetPtr dependencies(new PluginHandleSet);
230
231     PluginObjects::ObjectsPtr requiredObjects =
232         PluginDAO::getRequiredObjectsForPluginHandle(handle);
233
234     PluginHandle depHandle =
235         Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE;
236
237     FOREACH(requiredObject, *requiredObjects)
238     {
239         depHandle =
240             PluginDAO::getPluginHandleForImplementedObject(*requiredObject);
241
242         if (depHandle ==
243             Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE) {
244             LogError("Library implementing: " <<
245                      *requiredObject << " NOT FOUND");
246
247             //PluginDAO::SetPluginInstallationStatus(INSTALLATION_WAITING);
248             return false;
249         }
250         dependencies->insert(depHandle);
251     }
252
253     PluginDAO::registerPluginLibrariesDependencies(handle, dependencies);
254     PluginDAO::setPluginInstallationStatus(handle,
255                                            PluginDAO::INSTALLATION_COMPLETED);
256
257     return true;
258 }
259
260 }
261