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