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