tizen beta release
[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 <plugin_logic.h>
21 #include <dpl/wrt-dao-rw/feature_dao.h>
22 #include <dpl/wrt-dao-rw/plugin_dao.h>
23 #include <dpl/wrt-dao-ro/global_config.h>
24 #include <widget_install/job_widget_install.h>
25 #include <widget_uninstall/job_widget_uninstall.h>
26 #include <plugin_install/job_plugin_install.h>
27 #include <job_exception_base.h>
28 #include <plugin_install/plugin_objects.h>
29
30 using namespace WrtDB;
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         if (stepSucceded) {
121             job->SendProgress();
122
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::InstallPluginGeolocation(
215         const PluginInstallerStruct &installerStruct)
216 {
217     FeatureDAO::RegisterStrangeFeature(
218         std::string(GlobalConfig::GetW3CGeolocationFeatureName()));
219
220     LogDebug("Call plugins installer FinishedCallback");
221     installerStruct.finishedCallback(installerStruct.userParam,
222         Jobs::PluginInstall::Exceptions::Success);
223 }
224
225 void InstallerLogic::InstallWaitingPlugins()
226 {
227     PluginHandleSetPtr waitingPlugins;
228
229     waitingPlugins =
230         PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING);
231
232     FOREACH(it, *waitingPlugins)
233     {
234         resolvePluginDependencies(*it);
235     }
236 }
237
238 bool InstallerLogic::resolvePluginDependencies(PluginHandle handle)
239 {
240     PluginHandleSetPtr dependencies(new PluginHandleSet);
241
242     PluginObjects::ObjectsPtr requiredObjects =
243         PluginDAO::getRequiredObjectsForPluginHandle(handle);
244
245     PluginHandle depHandle =
246         Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE;
247
248     FOREACH(requiredObject, *requiredObjects)
249     {
250         depHandle =
251             PluginDAO::getPluginHandleForImplementedObject(*requiredObject);
252
253         if (depHandle ==
254             Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE) {
255             LogError("Library implementing: " <<
256                      *requiredObject << " NOT FOUND");
257
258             //PluginDAO::SetPluginInstallationStatus(INSTALLATION_WAITING);
259             return false;
260         }
261         dependencies->insert(depHandle);
262     }
263
264     PluginDAO::registerPluginLibrariesDependencies(handle, dependencies);
265     PluginDAO::setPluginInstallationStatus(handle,
266                                            PluginDAO::INSTALLATION_COMPLETED);
267
268     return true;
269 }
270