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 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 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 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 if (cmd_line.HasSwitch(switches::kFullscreen))
127 launch_params.window_state = ui::SHOW_STATE_FULLSCREEN;
129 if (application_service_->Launch(param, launch_params)) {
136 // Launch an application created from arbitrary url.
137 // FIXME: This application should have the same strict permissions
138 // as common browser apps.
140 bool ApplicationSystem::LaunchWithCommandLineParam<GURL>(
141 const GURL& url, const CommandLine& cmd_line) {
142 namespace keys = xwalk::application_manifest_keys;
144 const std::string& url_spec = url.spec();
145 DCHECK(!url_spec.empty());
146 const std::string& app_id = GenerateId(url_spec);
147 // FIXME: we need to handle hash collisions.
148 DCHECK(!application_storage_->GetApplicationData(app_id));
150 base::DictionaryValue manifest;
151 // FIXME: define permissions!
152 manifest.SetString(keys::kURLKey, url_spec);
153 manifest.SetString(keys::kNameKey,
154 "Crosswalk Hosted App [Restricted Permissions]");
155 manifest.SetString(keys::kVersionKey, "0");
156 manifest.SetInteger(keys::kManifestVersionKey, 1);
158 scoped_refptr<ApplicationData> application_data = ApplicationData::Create(
159 base::FilePath(), Manifest::COMMAND_LINE, manifest, app_id, &error);
160 if (!application_data) {
161 LOG(ERROR) << "Error occurred while trying to launch application: "
166 Application::LaunchParams launch_params;
167 if (cmd_line.HasSwitch(switches::kFullscreen))
168 launch_params.window_state = ui::SHOW_STATE_FULLSCREEN;
169 launch_params.entry_points = Application::URLKey;
171 return !!application_service_->Launch(application_data, launch_params);
174 bool ApplicationSystem::LaunchFromCommandLine(
175 const CommandLine& cmd_line, const GURL& url,
176 bool& run_default_message_loop) {
178 // Handles raw app_id passed as first non-switch argument.
179 const CommandLine::StringVector& args = cmd_line.GetArgs();
181 std::string app_id = std::string(args[0].begin(), args[0].end());
182 if (ApplicationData::IsIDValid(app_id)) {
183 run_default_message_loop = LaunchWithCommandLineParam(app_id, cmd_line);
192 if (url.SchemeIsFile() &&
193 net::FileURLToFilePath(url, &path) &&
194 base::DirectoryExists(path)) { // Handles local directory.
195 run_default_message_loop = LaunchWithCommandLineParam(path, cmd_line);
196 } else { // Handles external URL.
197 run_default_message_loop = LaunchWithCommandLineParam(url, cmd_line);
203 void ApplicationSystem::CreateExtensions(
204 content::RenderProcessHost* host,
205 extensions::XWalkExtensionVector* extensions) {
206 Application* application =
207 application_service_->GetApplicationByRenderHostID(host->GetID());
209 return; // We might be in browser mode.
211 extensions->push_back(new ApplicationRuntimeExtension(application));
212 extensions->push_back(new ApplicationEventExtension(
213 event_manager_.get(), application_storage_.get(), application));
214 extensions->push_back(new ApplicationWidgetExtension(application));
217 } // namespace application