Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / browser / application_system.cc
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "xwalk/application/browser/application_system.h"
6
7 #include <string>
8 #include "base/command_line.h"
9 #include "base/file_util.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "net/base/net_util.h"
12 #include "xwalk/application/browser/application.h"
13 #include "xwalk/application/browser/application_event_manager.h"
14 #include "xwalk/application/browser/application_service.h"
15 #include "xwalk/application/browser/application_storage.h"
16 #include "xwalk/application/common/application_manifest_constants.h"
17 #include "xwalk/application/common/event_names.h"
18 #include "xwalk/application/common/id_util.h"
19 #include "xwalk/application/extension/application_event_extension.h"
20 #include "xwalk/application/extension/application_runtime_extension.h"
21 #include "xwalk/application/extension/application_widget_extension.h"
22 #include "xwalk/runtime/browser/runtime_context.h"
23 #include "xwalk/runtime/common/xwalk_switches.h"
24
25 #if defined(OS_LINUX)
26 #include "xwalk/application/browser/application_system_linux.h"
27 #endif
28
29 namespace xwalk {
30 namespace application {
31
32 ApplicationSystem::ApplicationSystem(RuntimeContext* runtime_context)
33   : runtime_context_(runtime_context),
34     application_storage_(new ApplicationStorage(runtime_context->GetPath())),
35     event_manager_(new ApplicationEventManager()),
36     application_service_(new ApplicationService(
37         runtime_context,
38         application_storage_.get(),
39         event_manager_.get())) {}
40
41 ApplicationSystem::~ApplicationSystem() {
42 }
43
44 // static
45 scoped_ptr<ApplicationSystem> ApplicationSystem::Create(
46     RuntimeContext* runtime_context) {
47   scoped_ptr<ApplicationSystem> app_system;
48 #if defined(OS_LINUX)
49   app_system.reset(new ApplicationSystemLinux(runtime_context));
50 #else
51   app_system.reset(new ApplicationSystem(runtime_context));
52 #endif
53   return app_system.Pass();
54 }
55
56 bool ApplicationSystem::HandleApplicationManagementCommands(
57     const CommandLine& cmd_line, const GURL& url,
58     bool& run_default_message_loop) {
59   run_default_message_loop = false;
60   if (cmd_line.HasSwitch(switches::kListApplications)) {
61     const ApplicationData::ApplicationDataMap& apps =
62         application_storage_->GetInstalledApplications();
63     LOG(INFO) << "Application ID                       Application Name";
64     LOG(INFO) << "-----------------------------------------------------";
65     ApplicationData::ApplicationDataMap::const_iterator it;
66     for (it = apps.begin(); it != apps.end(); ++it)
67       LOG(INFO) << it->first << "     " << it->second->Name();
68     LOG(INFO) << "-----------------------------------------------------";
69     return true;
70   }
71
72   if (cmd_line.HasSwitch(switches::kUninstall)) {
73     const CommandLine::StringVector& args = cmd_line.GetArgs();
74     if (args.empty())
75       return false;
76
77     std::string app_id = std::string(args[0].begin(), args[0].end());
78     if (!ApplicationData::IsIDValid(app_id))
79       return false;
80
81     if (application_service_->Uninstall(app_id)) {
82       LOG(INFO) << "[OK] Application uninstalled successfully: " << app_id;
83     } else {
84       LOG(ERROR) << "[ERR] An error occurred when uninstalling application "
85                  << app_id;
86     }
87     return true;
88   }
89
90   if (cmd_line.HasSwitch(switches::kInstall)) {
91     base::FilePath path;
92     if (!net::FileURLToFilePath(url, &path))
93       return false;
94
95     if (!base::PathExists(path))
96       return false;
97
98     std::string app_id;
99     if (application_service_->Install(path, &app_id)) {
100       LOG(INFO) << "[OK] Application installed: " << app_id;
101       if (application_storage_->GetApplicationData(app_id)->HasMainDocument())
102         run_default_message_loop = true;
103     } else if (!app_id.empty() &&
104                application_service_->Update(app_id, path)) {
105       LOG(INFO) << "[OK] Application updated: " << app_id;
106       if (application_storage_->GetApplicationData(app_id)->HasMainDocument())
107         run_default_message_loop = true;
108     } else {
109       LOG(ERROR) << "[ERR] Application install/update failure: "
110                  << path.value();
111     }
112     return true;
113   }
114
115   run_default_message_loop = true;
116   return false;
117 }
118
119 template <typename T>
120 bool ApplicationSystem::LaunchWithCommandLineParam(
121     const T& param, const CommandLine& cmd_line) {
122   scoped_refptr<Event> event = Event::CreateEvent(
123         kOnLaunched, scoped_ptr<base::ListValue>(new base::ListValue));
124
125   Application::LaunchParams launch_params;
126   if (cmd_line.HasSwitch(switches::kFullscreen))
127     launch_params.window_state = ui::SHOW_STATE_FULLSCREEN;
128
129   if (Application* application =
130       application_service_->Launch(param, launch_params)) {
131     event_manager_->SendEvent(application->id(), event);
132     return true;
133   }
134
135   return false;
136 }
137
138 // Launch an application created from arbitrary url.
139 // FIXME: This application should have the same strict permissions
140 // as common browser apps.
141 template <>
142 bool ApplicationSystem::LaunchWithCommandLineParam<GURL>(
143     const GURL& url, const CommandLine& cmd_line) {
144   namespace keys = xwalk::application_manifest_keys;
145
146   const std::string& url_spec = url.spec();
147   DCHECK(!url_spec.empty());
148   const std::string& app_id = GenerateId(url_spec);
149   // FIXME: we need to handle hash collisions.
150   DCHECK(!application_storage_->GetApplicationData(app_id));
151
152   base::DictionaryValue manifest;
153   // FIXME: define permissions!
154   manifest.SetString(keys::kURLKey, url_spec);
155   manifest.SetString(keys::kNameKey,
156       "Crosswalk Hosted App [Restricted Permissions]");
157   manifest.SetString(keys::kVersionKey, "0");
158   manifest.SetInteger(keys::kManifestVersionKey, 1);
159   std::string error;
160   scoped_refptr<ApplicationData> application_data = ApplicationData::Create(
161             base::FilePath(), Manifest::COMMAND_LINE, manifest, app_id, &error);
162   if (!application_data) {
163     LOG(ERROR) << "Error occurred while trying to launch application: "
164                << error;
165     return NULL;
166   }
167
168   Application::LaunchParams launch_params;
169   if (cmd_line.HasSwitch(switches::kFullscreen))
170     launch_params.window_state = ui::SHOW_STATE_FULLSCREEN;
171   launch_params.entry_points = Application::URLKey;
172
173   return !!application_service_->Launch(application_data, launch_params);
174 }
175
176 bool ApplicationSystem::LaunchFromCommandLine(
177     const CommandLine& cmd_line, const GURL& url,
178     bool& run_default_message_loop) {
179
180   // Handles raw app_id passed as first non-switch argument.
181   const CommandLine::StringVector& args = cmd_line.GetArgs();
182   if (!args.empty()) {
183     std::string app_id = std::string(args[0].begin(), args[0].end());
184     if (ApplicationData::IsIDValid(app_id)) {
185       run_default_message_loop = LaunchWithCommandLineParam(app_id, cmd_line);
186       return true;
187     }
188   }
189
190   if (!url.is_valid())
191     return false;
192
193   base::FilePath path;
194   if (url.SchemeIsFile() &&
195       net::FileURLToFilePath(url, &path) &&
196       base::DirectoryExists(path)) {  // Handles local directory.
197     run_default_message_loop = LaunchWithCommandLineParam(path, cmd_line);
198   } else {  // Handles external URL.
199     run_default_message_loop = LaunchWithCommandLineParam(url, cmd_line);
200   }
201
202   return true;
203 }
204
205 void ApplicationSystem::CreateExtensions(
206     content::RenderProcessHost* host,
207     extensions::XWalkExtensionVector* extensions) {
208   Application* application =
209     application_service_->GetApplicationByRenderHostID(host->GetID());
210   if (!application)
211     return;  // We might be in browser mode.
212
213   extensions->push_back(new ApplicationRuntimeExtension(application));
214   extensions->push_back(new ApplicationEventExtension(
215               event_manager_.get(), application_storage_.get(), application));
216   extensions->push_back(new ApplicationWidgetExtension(application));
217 }
218
219 }  // namespace application
220 }  // namespace xwalk