OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "chromeos/dbus/arc_bridge_client.h" | 4 #include "chromeos/dbus/arc_bridge_client.h" |
5 | 5 |
6 #include "base/bind.h" | 6 #include "base/bind.h" |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
| 9 #include "base/observer_list.h" |
9 #include "dbus/bus.h" | 10 #include "dbus/bus.h" |
10 #include "dbus/message.h" | 11 #include "dbus/message.h" |
11 #include "dbus/object_path.h" | 12 #include "dbus/object_path.h" |
12 #include "dbus/object_proxy.h" | 13 #include "dbus/object_proxy.h" |
13 | 14 |
14 namespace chromeos { | 15 namespace chromeos { |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 // todo(denniskempin): Move constants to the chromiumos platform | 19 // todo(denniskempin): Move constants to the chromiumos platform |
19 // service_constants.h | 20 // service_constants.h |
20 const char kArcBridgeServicePath[] = "/org/chromium/arc"; | 21 const char kArcBridgeServicePath[] = "/org/chromium/arc"; |
21 const char kArcBridgeServiceName[] = "org.chromium.arc"; | 22 const char kArcBridgeServiceName[] = "org.chromium.arc"; |
22 const char kArcBridgeServiceInterface[] = "org.chromium.arc"; | 23 const char kArcBridgeServiceInterface[] = "org.chromium.arc"; |
23 | 24 |
24 const char kPingMethod[] = "Ping"; | 25 const char kPingMethod[] = "Ping"; |
| 26 const char kAppLauncherReadySignal[] = "AppLauncherReady"; |
| 27 const char kAppReadySignal[] = "AppLauncherAppReady"; |
| 28 const char kAppsRefreshedSignal[] = "AppLauncherAppsRefreshed"; |
| 29 const char kRefreshAppsMethod[] = "RefreshApps"; |
| 30 const char kLaunchAppMethod[] = "LaunchApp"; |
25 | 31 |
26 void OnVoidDBusMethod(const VoidDBusMethodCallback& callback, | 32 void OnVoidDBusMethod(const VoidDBusMethodCallback& callback, |
27 dbus::Response* response) { | 33 dbus::Response* response) { |
28 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE); | 34 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE); |
29 } | 35 } |
30 | 36 |
31 class ArcBridgeClientImpl : public ArcBridgeClient { | 37 class ArcBridgeClientImpl : public ArcBridgeClient { |
32 public: | 38 public: |
33 ArcBridgeClientImpl() : proxy_(nullptr), weak_ptr_factory_(this) {} | 39 ArcBridgeClientImpl() : proxy_(nullptr), weak_ptr_factory_(this) {} |
34 | 40 |
35 ~ArcBridgeClientImpl() override {} | 41 ~ArcBridgeClientImpl() override {} |
36 | 42 |
37 // Calls Ping method. |callback| is called after the method call succeeds. | 43 // Calls Ping method. |callback| is called after the method call succeeds. |
38 void Ping(const VoidDBusMethodCallback& callback) override { | 44 void Ping(const VoidDBusMethodCallback& callback) override { |
39 DCHECK(proxy_); | 45 DCHECK(proxy_); |
40 | 46 |
41 dbus::MethodCall method_call(kArcBridgeServiceInterface, kPingMethod); | 47 dbus::MethodCall method_call(kArcBridgeServiceInterface, kPingMethod); |
42 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 48 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
43 base::Bind(&OnVoidDBusMethod, callback)); | 49 base::Bind(&OnVoidDBusMethod, callback)); |
44 } | 50 } |
45 | 51 |
| 52 void Refresh() override { |
| 53 dbus::MethodCall method_call(kArcBridgeServiceInterface, |
| 54 kRefreshAppsMethod); |
| 55 DCHECK(proxy_); |
| 56 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 57 dbus::ObjectProxy::EmptyResponseCallback()); |
| 58 } |
| 59 |
| 60 void LaunchApp(const std::string& package, |
| 61 const std::string& activity) override { |
| 62 dbus::MethodCall method_call(kArcBridgeServiceInterface, kLaunchAppMethod); |
| 63 dbus::MessageWriter writer(&method_call); |
| 64 writer.AppendString(package); |
| 65 writer.AppendString(activity); |
| 66 DCHECK(proxy_); |
| 67 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 68 dbus::ObjectProxy::EmptyResponseCallback()); |
| 69 } |
| 70 |
| 71 void AddAppObserver(AppObserver* observer) override { |
| 72 app_observers_.AddObserver(observer); |
| 73 } |
| 74 |
| 75 void RemoveAppObserver(AppObserver* observer) override { |
| 76 app_observers_.RemoveObserver(observer); |
| 77 } |
| 78 |
46 protected: | 79 protected: |
47 void Init(dbus::Bus* bus) override { | 80 void Init(dbus::Bus* bus) override { |
48 proxy_ = bus->GetObjectProxy(kArcBridgeServiceName, | 81 proxy_ = bus->GetObjectProxy(kArcBridgeServiceName, |
49 dbus::ObjectPath(kArcBridgeServicePath)); | 82 dbus::ObjectPath(kArcBridgeServicePath)); |
50 DCHECK(proxy_); | 83 DCHECK(proxy_); |
| 84 |
| 85 proxy_->ConnectToSignal( |
| 86 kArcBridgeServiceInterface, kAppLauncherReadySignal, |
| 87 base::Bind(&ArcBridgeClientImpl::AppLauncherReadyReceived, |
| 88 weak_ptr_factory_.GetWeakPtr()), |
| 89 base::Bind(&ArcBridgeClientImpl::AppLauncherReadyConnected, |
| 90 weak_ptr_factory_.GetWeakPtr())); |
| 91 |
| 92 proxy_->ConnectToSignal(kArcBridgeServiceInterface, kAppReadySignal, |
| 93 base::Bind(&ArcBridgeClientImpl::AppReadyReceived, |
| 94 weak_ptr_factory_.GetWeakPtr()), |
| 95 base::Bind(&ArcBridgeClientImpl::AppReadyConnected, |
| 96 weak_ptr_factory_.GetWeakPtr())); |
| 97 |
| 98 proxy_->ConnectToSignal( |
| 99 kArcBridgeServiceInterface, kAppsRefreshedSignal, |
| 100 base::Bind(&ArcBridgeClientImpl::AppsRefreshedReceived, |
| 101 weak_ptr_factory_.GetWeakPtr()), |
| 102 base::Bind(&ArcBridgeClientImpl::AppsRefreshedConnected, |
| 103 weak_ptr_factory_.GetWeakPtr())); |
51 } | 104 } |
52 | 105 |
53 private: | 106 private: |
54 dbus::ObjectProxy* proxy_; | 107 dbus::ObjectProxy* proxy_; |
| 108 base::ObserverList<AppObserver> app_observers_; |
55 | 109 |
56 // Note: This should remain the last member so it'll be destroyed and | 110 // Note: This should remain the last member so it'll be destroyed and |
57 // invalidate its weak pointers before any other members are destroyed. | 111 // invalidate its weak pointers before any other members are destroyed. |
58 base::WeakPtrFactory<ArcBridgeClientImpl> weak_ptr_factory_; | 112 base::WeakPtrFactory<ArcBridgeClientImpl> weak_ptr_factory_; |
59 | 113 |
| 114 void AppLauncherReadyReceived(dbus::Signal* signal) { Refresh(); } |
| 115 |
| 116 // Called when the TimeUpdated signal is initially connected. |
| 117 void AppLauncherReadyConnected(const std::string& interface_name, |
| 118 const std::string& signal_name, |
| 119 bool success) {} |
| 120 |
| 121 bool ReadAppInfo(dbus::MessageReader& reader, AppInfo& app) { |
| 122 size_t icon_size; |
| 123 const uint8* icon_data; |
| 124 if (!reader.PopString(&app.name) || !reader.PopString(&app.package) || |
| 125 !reader.PopArrayOfBytes(&icon_data, &icon_size)) { |
| 126 return false; |
| 127 } |
| 128 |
| 129 if (icon_size) { |
| 130 app.icon.resize(icon_size); |
| 131 memcpy(&app.icon[0], icon_data, icon_size); |
| 132 } |
| 133 |
| 134 return true; |
| 135 } |
| 136 |
| 137 void AppReadyReceived(dbus::Signal* signal) { |
| 138 AppInfo app; |
| 139 dbus::MessageReader reader(signal); |
| 140 if (!ReadAppInfo(reader, app)) { |
| 141 return; |
| 142 } |
| 143 |
| 144 FOR_EACH_OBSERVER(AppObserver, app_observers_, OnAppReady(app)); |
| 145 } |
| 146 |
| 147 void AppReadyConnected(const std::string& interface_name, |
| 148 const std::string& signal_name, |
| 149 bool success) {} |
| 150 |
| 151 void AppsRefreshedReceived(dbus::Signal* signal) { |
| 152 dbus::MessageReader reader(signal); |
| 153 uint32 app_count; |
| 154 if (!reader.PopUint32(&app_count)) { |
| 155 return; |
| 156 } |
| 157 std::vector<AppInfo> apps(app_count); |
| 158 for (uint32 i = 0; i < app_count; ++i) { |
| 159 if (!ReadAppInfo(reader, apps[i])) { |
| 160 return; |
| 161 } |
| 162 } |
| 163 |
| 164 FOR_EACH_OBSERVER(AppObserver, app_observers_, OnAppsRefreshed(apps)); |
| 165 } |
| 166 |
| 167 void AppsRefreshedConnected(const std::string& interface_name, |
| 168 const std::string& signal_name, |
| 169 bool success) {} |
| 170 |
60 DISALLOW_COPY_AND_ASSIGN(ArcBridgeClientImpl); | 171 DISALLOW_COPY_AND_ASSIGN(ArcBridgeClientImpl); |
61 }; | 172 }; |
62 | 173 |
63 } // namespace | 174 } // namespace |
64 | 175 |
65 //////////////////////////////////////////////////////////////////////////////// | 176 //////////////////////////////////////////////////////////////////////////////// |
66 // ArcBridgeClient | 177 // ArcBridgeClient |
67 | 178 |
68 ArcBridgeClient::ArcBridgeClient() {} | 179 ArcBridgeClient::ArcBridgeClient() {} |
69 | 180 |
70 ArcBridgeClient::~ArcBridgeClient() {} | 181 ArcBridgeClient::~ArcBridgeClient() {} |
71 | 182 |
72 // static | 183 // static |
73 ArcBridgeClient* ArcBridgeClient::Create() { | 184 ArcBridgeClient* ArcBridgeClient::Create() { |
74 return new ArcBridgeClientImpl(); | 185 return new ArcBridgeClientImpl(); |
75 } | 186 } |
76 | 187 |
| 188 ArcBridgeClient::AppInfo::AppInfo() {} |
| 189 |
| 190 ArcBridgeClient::AppInfo::~AppInfo() {} |
| 191 |
77 } // namespace chromeos | 192 } // namespace chromeos |
OLD | NEW |