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.
5 #include "xwalk/application/browser/application_system.h"
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"
26 #include "xwalk/application/browser/application_system_linux.h"
30 namespace application {
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(
38 application_storage_.get(),
39 event_manager_.get())) {}
41 ApplicationSystem::~ApplicationSystem() {
45 scoped_ptr<ApplicationSystem> ApplicationSystem::Create(
46 RuntimeContext* runtime_context) {
47 scoped_ptr<ApplicationSystem> app_system;
49 app_system.reset(new ApplicationSystemLinux(runtime_context));
51 app_system.reset(new ApplicationSystem(runtime_context));
53 return app_system.Pass();
56 bool ApplicationSystem::HandleApplicationManagementCommands(
57 const base::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) << "-----------------------------------------------------";
72 if (cmd_line.HasSwitch(switches::kUninstall)) {
73 const base::CommandLine::StringVector& args = cmd_line.GetArgs();
77 std::string app_id = std::string(args[0].begin(), args[0].end());
78 if (!ApplicationData::IsIDValid(app_id))
81 if (application_service_->Uninstall(app_id)) {
82 LOG(INFO) << "[OK] Application uninstalled successfully: " << app_id;
84 LOG(ERROR) << "[ERR] An error occurred when uninstalling application "
90 if (cmd_line.HasSwitch(switches::kInstall)) {
92 if (!net::FileURLToFilePath(url, &path))
95 if (!base::PathExists(path))
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;
109 LOG(ERROR) << "[ERR] Application install/update failure: "
115 run_default_message_loop = true;
119 template <typename T>
120 bool ApplicationSystem::LaunchWithCommandLineParam(
121 const T& param, const base::CommandLine& cmd_line) {
122 scoped_refptr<Event> event = Event::CreateEvent(
123 kOnLaunched, scoped_ptr<base::ListValue>(new base::ListValue));
125 Application::LaunchParams launch_params;
126 launch_params.force_fullscreen = cmd_line.HasSwitch(switches::kFullscreen);
128 if (application_service_->Launch(param, launch_params)) {
135 // Launch an application created from arbitrary url.
136 // FIXME: This application should have the same strict permissions
137 // as common browser apps.
139 bool ApplicationSystem::LaunchWithCommandLineParam<GURL>(
140 const GURL& url, const base::CommandLine& cmd_line) {
141 namespace keys = xwalk::application_manifest_keys;
143 const std::string& url_spec = url.spec();
144 DCHECK(!url_spec.empty());
145 const std::string& app_id = GenerateId(url_spec);
146 // FIXME: we need to handle hash collisions.
147 DCHECK(!application_storage_->GetApplicationData(app_id));
149 base::DictionaryValue manifest;
150 // FIXME: define permissions!
151 manifest.SetString(keys::kURLKey, url_spec);
152 manifest.SetString(keys::kNameKey,
153 "Crosswalk Hosted App [Restricted Permissions]");
154 manifest.SetString(keys::kVersionKey, "0");
155 manifest.SetInteger(keys::kManifestVersionKey, 1);
157 scoped_refptr<ApplicationData> application_data = ApplicationData::Create(
158 base::FilePath(), Manifest::COMMAND_LINE, manifest, app_id, &error);
159 if (!application_data) {
160 LOG(ERROR) << "Error occurred while trying to launch application: "
165 Application::LaunchParams launch_params;
166 launch_params.force_fullscreen = cmd_line.HasSwitch(switches::kFullscreen);
167 launch_params.entry_points = Application::URLKey;
169 return !!application_service_->Launch(application_data, launch_params);
172 bool ApplicationSystem::LaunchFromCommandLine(
173 const base::CommandLine& cmd_line, const GURL& url,
174 bool& run_default_message_loop) {
176 // Handles raw app_id passed as first non-switch argument.
177 const base::CommandLine::StringVector& args = cmd_line.GetArgs();
179 std::string app_id = std::string(args[0].begin(), args[0].end());
180 if (ApplicationData::IsIDValid(app_id)) {
181 run_default_message_loop = LaunchWithCommandLineParam(app_id, cmd_line);
190 if (url.SchemeIsFile() &&
191 net::FileURLToFilePath(url, &path) &&
192 base::DirectoryExists(path)) { // Handles local directory.
193 run_default_message_loop = LaunchWithCommandLineParam(path, cmd_line);
194 } else { // Handles external URL.
195 run_default_message_loop = LaunchWithCommandLineParam(url, cmd_line);
201 void ApplicationSystem::CreateExtensions(
202 content::RenderProcessHost* host,
203 extensions::XWalkExtensionVector* extensions) {
204 Application* application =
205 application_service_->GetApplicationByRenderHostID(host->GetID());
207 return; // We might be in browser mode.
209 extensions->push_back(new ApplicationRuntimeExtension(application));
210 extensions->push_back(new ApplicationEventExtension(
211 event_manager_.get(), application_storage_.get(), application));
212 extensions->push_back(new ApplicationWidgetExtension(application));
215 } // namespace application