Index: chromeos/dbus/arc_bridge_client.cc |
diff --git a/chromeos/dbus/arc_bridge_client.cc b/chromeos/dbus/arc_bridge_client.cc |
index 584e10bc5e9557ba763b401deb6f66883739200a..b78c697cf9c3cf725f5b42d3a7f3bfed12f6f41b 100644 |
--- a/chromeos/dbus/arc_bridge_client.cc |
+++ b/chromeos/dbus/arc_bridge_client.cc |
@@ -6,6 +6,7 @@ |
#include "base/bind.h" |
#include "base/logging.h" |
#include "base/memory/weak_ptr.h" |
+#include "base/observer_list.h" |
#include "dbus/bus.h" |
#include "dbus/message.h" |
#include "dbus/object_path.h" |
@@ -22,6 +23,11 @@ const char kArcBridgeServiceName[] = "org.chromium.arc"; |
const char kArcBridgeServiceInterface[] = "org.chromium.arc"; |
const char kPingMethod[] = "Ping"; |
+const char kAppLauncherReadySignal[] = "AppLauncherReady"; |
+const char kAppReadySignal[] = "AppLauncherAppReady"; |
+const char kAppsRefreshedSignal[] = "AppLauncherAppsRefreshed"; |
+const char kRefreshAppsMethod[] = "RefreshApps"; |
+const char kLaunchAppMethod[] = "LaunchApp"; |
void OnVoidDBusMethod(const VoidDBusMethodCallback& callback, |
dbus::Response* response) { |
@@ -43,20 +49,125 @@ class ArcBridgeClientImpl : public ArcBridgeClient { |
base::Bind(&OnVoidDBusMethod, callback)); |
} |
+ void Refresh() override { |
+ dbus::MethodCall method_call(kArcBridgeServiceInterface, |
+ kRefreshAppsMethod); |
+ DCHECK(proxy_); |
+ proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ dbus::ObjectProxy::EmptyResponseCallback()); |
+ } |
+ |
+ void LaunchApp(const std::string& package, |
+ const std::string& activity) override { |
+ dbus::MethodCall method_call(kArcBridgeServiceInterface, kLaunchAppMethod); |
+ dbus::MessageWriter writer(&method_call); |
+ writer.AppendString(package); |
+ writer.AppendString(activity); |
+ DCHECK(proxy_); |
+ proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ dbus::ObjectProxy::EmptyResponseCallback()); |
+ } |
+ |
+ void AddAppObserver(AppObserver* observer) override { |
+ app_observers_.AddObserver(observer); |
+ } |
+ |
+ void RemoveAppObserver(AppObserver* observer) override { |
+ app_observers_.RemoveObserver(observer); |
+ } |
+ |
protected: |
void Init(dbus::Bus* bus) override { |
proxy_ = bus->GetObjectProxy(kArcBridgeServiceName, |
dbus::ObjectPath(kArcBridgeServicePath)); |
DCHECK(proxy_); |
+ |
+ proxy_->ConnectToSignal( |
+ kArcBridgeServiceInterface, kAppLauncherReadySignal, |
+ base::Bind(&ArcBridgeClientImpl::AppLauncherReadyReceived, |
+ weak_ptr_factory_.GetWeakPtr()), |
+ base::Bind(&ArcBridgeClientImpl::AppLauncherReadyConnected, |
+ weak_ptr_factory_.GetWeakPtr())); |
+ |
+ proxy_->ConnectToSignal(kArcBridgeServiceInterface, kAppReadySignal, |
+ base::Bind(&ArcBridgeClientImpl::AppReadyReceived, |
+ weak_ptr_factory_.GetWeakPtr()), |
+ base::Bind(&ArcBridgeClientImpl::AppReadyConnected, |
+ weak_ptr_factory_.GetWeakPtr())); |
+ |
+ proxy_->ConnectToSignal( |
+ kArcBridgeServiceInterface, kAppsRefreshedSignal, |
+ base::Bind(&ArcBridgeClientImpl::AppsRefreshedReceived, |
+ weak_ptr_factory_.GetWeakPtr()), |
+ base::Bind(&ArcBridgeClientImpl::AppsRefreshedConnected, |
+ weak_ptr_factory_.GetWeakPtr())); |
} |
private: |
dbus::ObjectProxy* proxy_; |
+ base::ObserverList<AppObserver> app_observers_; |
// Note: This should remain the last member so it'll be destroyed and |
// invalidate its weak pointers before any other members are destroyed. |
base::WeakPtrFactory<ArcBridgeClientImpl> weak_ptr_factory_; |
+ void AppLauncherReadyReceived(dbus::Signal* signal) { Refresh(); } |
+ |
+ // Called when the TimeUpdated signal is initially connected. |
+ void AppLauncherReadyConnected(const std::string& interface_name, |
+ const std::string& signal_name, |
+ bool success) {} |
+ |
+ bool ReadAppInfo(dbus::MessageReader& reader, AppInfo& app) { |
+ size_t icon_size; |
+ const uint8* icon_data; |
+ if (!reader.PopString(&app.name) || !reader.PopString(&app.package) || |
+ !reader.PopArrayOfBytes(&icon_data, &icon_size)) { |
+ return false; |
+ } |
+ |
+ if (icon_size) { |
+ app.icon.resize(icon_size); |
+ memcpy(&app.icon[0], icon_data, icon_size); |
+ } |
+ |
+ return true; |
+ } |
+ |
+ void AppReadyReceived(dbus::Signal* signal) { |
+ AppInfo app; |
+ dbus::MessageReader reader(signal); |
+ if (!ReadAppInfo(reader, app)) { |
+ return; |
+ } |
+ |
+ FOR_EACH_OBSERVER(AppObserver, app_observers_, OnAppReady(app)); |
+ } |
+ |
+ void AppReadyConnected(const std::string& interface_name, |
+ const std::string& signal_name, |
+ bool success) {} |
+ |
+ void AppsRefreshedReceived(dbus::Signal* signal) { |
+ dbus::MessageReader reader(signal); |
+ uint32 app_count; |
+ if (!reader.PopUint32(&app_count)) { |
+ return; |
+ } |
+ std::vector<AppInfo> apps(app_count); |
+ for (uint32 i = 0; i < app_count; ++i) { |
+ if (!ReadAppInfo(reader, apps[i])) { |
+ return; |
+ } |
+ } |
+ |
+ FOR_EACH_OBSERVER(AppObserver, app_observers_, OnAppsRefreshed(apps)); |
+ } |
+ |
+ void AppsRefreshedConnected(const std::string& interface_name, |
+ const std::string& signal_name, |
+ bool success) {} |
+ |
DISALLOW_COPY_AND_ASSIGN(ArcBridgeClientImpl); |
}; |
@@ -74,4 +185,8 @@ ArcBridgeClient* ArcBridgeClient::Create() { |
return new ArcBridgeClientImpl(); |
} |
+ArcBridgeClient::AppInfo::AppInfo() {} |
+ |
+ArcBridgeClient::AppInfo::~AppInfo() {} |
+ |
} // namespace chromeos |