1 // Copyright (c) 2014 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/runtime/browser/runtime_platform_util.h"
8 #include "base/files/file_util.h"
9 #include "base/logging.h"
10 #include "base/process/kill.h"
11 #include "base/process/launch.h"
13 #include "dbus/message.h"
14 #include "dbus/object_proxy.h"
17 namespace platform_util {
19 // The system default web browser path.
20 // In some Tizen releases, there exists a system browser called 'MiniBrowser',
21 // which we can use to open an external link from a web app.
22 const char kWebBrowserPath[] = "/usr/bin/MiniBrowser";
24 typedef base::Callback<void (const GURL&, dbus::MessageWriter*)> ParamsWriter;
26 struct ProtocolDBusServiceInfo {
29 const char* interface;
31 const char* object_path;
32 ParamsWriter params_writer;
35 void ParseAndWriteTelParams(const GURL& url,
36 dbus::MessageWriter* dbus_writer) {
38 dbus_writer->AppendString(url.GetContent());
39 // Always don't auto dial
40 dbus_writer->AppendBool(false);
43 void ParseAndWriteMailParams(const GURL& uri,
44 dbus::MessageWriter* dbus_writer) {
47 void ParseAndWriteSmsParams(const GURL& url,
48 dbus::MessageWriter* dbus_writer) {
49 // Support the case sms:12345678?body=Hello
50 std::string query = url.query();
51 std::string content = url.GetContent();
52 // Extract the phone number
53 const std::string number = content.substr(0, content.find(query) - 1);
55 const std::string body = query.erase(0, 5);
57 dbus_writer->AppendString(number);
58 dbus_writer->AppendString(body);
59 // Always don't auto dial
60 dbus_writer->AppendBool(false);
63 const ProtocolDBusServiceInfo protocol_dbus_services[] = {
64 {"tel", "org.tizen.dialer", "org.tizen.dialer.Control", "Dial", "/",
65 base::Bind(ParseAndWriteTelParams)},
66 {"mailto", "org.tizen.email_service", "org.tizen.email_service", "Launch",
67 "/org/tizen/email_service",
68 base::Bind(ParseAndWriteMailParams)},
69 {"sms", "org.tizen.dialer", "org.tizen.dialer.Control", "Send", "/",
70 base::Bind(ParseAndWriteSmsParams)},
73 bool CallDbusService(const ProtocolDBusServiceInfo& info,
75 const dbus::ObjectPath dbus_path(info.object_path);
77 dbus::Bus::Options options;
78 scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
79 dbus::ObjectProxy* app_proxy =
80 bus->GetObjectProxy(info.service, dbus_path);
82 VLOG(1) << "app_proxy failed.";
86 dbus::MethodCall method_call(info.interface, info.method);
87 dbus::MessageWriter writer(&method_call);
88 info.params_writer.Run(url, &writer);
90 app_proxy->CallMethod(&method_call,
91 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
92 dbus::ObjectProxy::EmptyResponseCallback());
98 bool HandleExternalProtocol(const GURL& url) {
99 for (size_t i = 0; i < arraysize(protocol_dbus_services); ++i) {
100 const ProtocolDBusServiceInfo& info = protocol_dbus_services[i];
101 if (url.SchemeIs(info.scheme)) {
102 return CallDbusService(info, url);
108 void OpenExternal(const GURL& url) {
109 if (url.SchemeIsHTTPOrHTTPS()) {
110 LOG(INFO) << "Open in WebBrowser.";
111 std::vector<std::string> argv;
112 if (base::PathExists(base::FilePath(kWebBrowserPath)))
113 argv.push_back(kWebBrowserPath);
115 argv.push_back("xwalk-launcher");
116 argv.push_back(url.spec());
117 base::ProcessHandle handle;
119 if (base::LaunchProcess(argv, base::LaunchOptions(), &handle))
120 base::EnsureProcessGetsReaped(handle);
121 } else if (!HandleExternalProtocol(url)) {
122 LOG(ERROR) << "Can not handle url: " << url.spec();
126 } // namespace platform_util