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