arc-bridge: Implement IPC message for app launcher.
This CL comes along with:
https://codereview.chromium.org/1481523002 (split arc_bride_service)
https://codereview.chromium.org/1464353003 (fake_arc_bridge)
https://codereview.chromium.org/1413153007 (app_list)
This includes set of IPC messages to interact with Android
via ARC bridge service in chromeos.
BUG=558209
BUG=b/24545231
TEST=Build and deploy android, chrome, chromium CLs. Apps
appear in chromium app launcher. Once clicked, app is
started in Android window.
TEST=build Chrome with enable_arc=1 Debug/Release
TEST=unit_tests with enable_arc=1 Debug/Release
(Together with all required CLs)
Review URL: https://codereview.chromium.org/1475563002
Cr-Commit-Position: refs/heads/master@{#362895}
diff --git a/components/arc.gypi b/components/arc.gypi
index 3773f09..7cf871c 100644
--- a/components/arc.gypi
+++ b/components/arc.gypi
@@ -25,6 +25,8 @@
'arc/common/arc_instance_messages.h',
'arc/common/arc_message_generator.cc',
'arc/common/arc_message_generator.h',
+ 'arc/common/arc_message_traits.h',
+ 'arc/common/arc_message_types.h',
],
},
],
diff --git a/components/arc/arc_bridge_service.cc b/components/arc/arc_bridge_service.cc
index af2835d..640e379 100644
--- a/components/arc/arc_bridge_service.cc
+++ b/components/arc/arc_bridge_service.cc
@@ -57,6 +57,16 @@
observer_list_.RemoveObserver(observer);
}
+void ArcBridgeService::AddAppObserver(AppObserver* observer) {
+ DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+ app_observer_list_.AddObserver(observer);
+}
+
+void ArcBridgeService::RemoveAppObserver(AppObserver* observer) {
+ DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+ app_observer_list_.RemoveObserver(observer);
+}
+
void ArcBridgeService::SetState(State state) {
DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
// DCHECK on enum classes not supported.
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h
index 78e8fa8..a3c1fe6 100644
--- a/components/arc/arc_bridge_service.h
+++ b/components/arc/arc_bridge_service.h
@@ -64,6 +64,7 @@
STOPPING,
};
+ // Notifies life cycle events of ArcBridgeService.
class Observer {
public:
// Called whenever the state of the bridge has changed.
@@ -79,6 +80,22 @@
virtual ~Observer() {}
};
+ // Notifies ARC apps related events.
+ class AppObserver {
+ public:
+ // Called whenever ARC sends information about available apps.
+ virtual void OnAppListRefreshed(const std::vector<AppInfo>& apps) {}
+
+ // Called whenever ARC sends app icon data for specific scale factor.
+ virtual void OnAppIcon(const std::string& package,
+ const std::string& activity,
+ ScaleFactor scale_factor,
+ const std::vector<uint8_t>& icon_png_data) {}
+
+ protected:
+ virtual ~AppObserver() {}
+ };
+
virtual ~ArcBridgeService();
// Creates instance of |ArcBridgeService| for normal use.
@@ -113,6 +130,11 @@
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
+ // Adds or removes ARC app observers. This can only be called on the thread
+ // that this class was created on.
+ void AddAppObserver(AppObserver* observer);
+ void RemoveAppObserver(AppObserver* observer);
+
// Gets the current state of the bridge service.
State state() const { return state_; }
@@ -129,6 +151,18 @@
const std::string& device_type,
base::ScopedFD fd) = 0;
+ // Requests to refresh an app list.
+ virtual bool RefreshAppList() = 0;
+
+ // Requests to launch an app.
+ virtual bool LaunchApp(const std::string& package,
+ const std::string& activity) = 0;
+
+ // Requests to load an icon of specific scale_factor.
+ virtual bool RequestAppIcon(const std::string& package,
+ const std::string& activity,
+ ScaleFactor scale_factor) = 0;
+
protected:
ArcBridgeService();
@@ -144,11 +178,17 @@
base::ObserverList<Observer>& observer_list() { return observer_list_; }
+ base::ObserverList<AppObserver>& app_observer_list() {
+ return app_observer_list_;
+ }
+
private:
scoped_refptr<base::SequencedTaskRunner> origin_task_runner_;
base::ObserverList<Observer> observer_list_;
+ base::ObserverList<AppObserver> app_observer_list_;
+
// If the ARC instance service is available.
bool available_;
diff --git a/components/arc/arc_bridge_service_impl.cc b/components/arc/arc_bridge_service_impl.cc
index 1a1c954..b5611b7 100644
--- a/components/arc/arc_bridge_service_impl.cc
+++ b/components/arc/arc_bridge_service_impl.cc
@@ -108,6 +108,38 @@
name, device_type, base::FileDescriptor(fd.Pass())));
}
+bool ArcBridgeServiceImpl::RefreshAppList() {
+ DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+ if (state() != State::READY) {
+ LOG(ERROR) << "Called RefreshAppList when the service is not ready";
+ return false;
+ }
+ return ipc_channel_->Send(new ArcInstanceMsg_RefreshApps());
+}
+
+bool ArcBridgeServiceImpl::LaunchApp(const std::string& package,
+ const std::string& activity) {
+ DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+ if (state() != State::READY) {
+ LOG(ERROR) << "Called LaunchApp when the service is not ready";
+ return false;
+ }
+ return ipc_channel_->Send(new ArcInstanceMsg_LaunchApp(package, activity));
+}
+
+bool ArcBridgeServiceImpl::RequestAppIcon(const std::string& package,
+ const std::string& activity,
+ ScaleFactor scale_factor) {
+ DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+ if (state() != State::READY) {
+ LOG(ERROR) << "Called RequestAppIcon when the service is not ready";
+ return false;
+ }
+ return ipc_channel_->Send(new ArcInstanceMsg_RequestAppIcon(package,
+ activity,
+ scale_factor));
+}
+
void ArcBridgeServiceImpl::SocketConnect(const base::FilePath& socket_path) {
DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
if (state() != State::STOPPED) {
@@ -226,6 +258,8 @@
IPC_BEGIN_MESSAGE_MAP(ArcBridgeServiceImpl, message)
IPC_MESSAGE_HANDLER(ArcInstanceHostMsg_InstanceBootPhase,
OnInstanceBootPhase)
+ IPC_MESSAGE_HANDLER(ArcInstanceHostMsg_AppListRefreshed, OnAppListRefreshed)
+ IPC_MESSAGE_HANDLER(ArcInstanceHostMsg_AppIcon, OnAppIcon)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -234,6 +268,23 @@
return handled;
}
+void ArcBridgeServiceImpl::OnAppListRefreshed(
+ const std::vector<arc::AppInfo>& apps) {
+ DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+ FOR_EACH_OBSERVER(AppObserver, app_observer_list(), OnAppListRefreshed(apps));
+}
+
+void ArcBridgeServiceImpl::OnAppIcon(
+ const std::string& package,
+ const std::string& activity,
+ ScaleFactor scale_factor,
+ const std::vector<uint8_t>& icon_png_data) {
+ DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+ FOR_EACH_OBSERVER(AppObserver,
+ app_observer_list(),
+ OnAppIcon(package, activity, scale_factor, icon_png_data));
+}
+
void ArcBridgeServiceImpl::OnArcAvailable(bool arc_available) {
DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
if (available() == arc_available)
diff --git a/components/arc/arc_bridge_service_impl.h b/components/arc/arc_bridge_service_impl.h
index d65e712..7482363 100644
--- a/components/arc/arc_bridge_service_impl.h
+++ b/components/arc/arc_bridge_service_impl.h
@@ -38,6 +38,18 @@
const std::string& device_type,
base::ScopedFD fd) override;
+ // Requests to refresh an app list.
+ bool RefreshAppList() override;
+
+ // Requests to launch an app.
+ bool LaunchApp(const std::string& package,
+ const std::string& activity) override;
+
+ // Requests to load an icon of specific scale_factor.
+ bool RequestAppIcon(const std::string& package,
+ const std::string& activity,
+ ScaleFactor scale_factor) override;
+
private:
friend class ArcBridgeTest;
FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, Basic);
@@ -70,6 +82,15 @@
// Called when the instance has reached a boot phase
void OnInstanceBootPhase(InstanceBootPhase phase);
+ // Called whenever ARC sends information about available apps.
+ void OnAppListRefreshed(const std::vector<arc::AppInfo>& apps);
+
+ // Called whenever ARC sends app icon data for specific scale factor.
+ void OnAppIcon(const std::string& package,
+ const std::string& activity,
+ ScaleFactor scale_factor,
+ const std::vector<uint8_t>& icon_png_data);
+
// IPC::Listener:
bool OnMessageReceived(const IPC::Message& message) override;
diff --git a/components/arc/common/arc_host_messages.h b/components/arc/common/arc_host_messages.h
index 116de0c..d7ecfdf 100644
--- a/components/arc/common/arc_host_messages.h
+++ b/components/arc/common/arc_host_messages.h
@@ -5,6 +5,9 @@
// Messages sent from the ARC instance to the host.
// Multiply-included message file, hence no include guard.
+#include <string>
+#include <vector>
+
#include "ipc/ipc_message_macros.h"
#include "components/arc/common/arc_message_types.h"
@@ -15,3 +18,21 @@
IPC_MESSAGE_CONTROL1(ArcInstanceHostMsg_InstanceBootPhase,
arc::InstanceBootPhase)
+
+// Sends a list of available ARC apps to Chrome. Members of AppInfo must contain
+// non-empty string. This message is sent in response to
+// ArcInstanceMsg_RefreshApps message from Chrome to ARC and when ARC receives
+// boot completed notification.
+IPC_MESSAGE_CONTROL1(ArcInstanceHostMsg_AppListRefreshed,
+ std::vector<arc::AppInfo> /* apps */)
+
+// Sends an icon of required |scale_factor| for specific ARC app. The app is
+// defined by |package| and |activity|. The icon content cannot be empty and
+// must match to |scale_factor| assuming 48x48 for SCALE_FACTOR_100P.
+// |scale_factor| is an enum defined at ui/base/layout.h. This message is sent
+// in response to ArcInstanceMsg_RequestIcon from Chrome to ARC.
+IPC_MESSAGE_CONTROL4(ArcInstanceHostMsg_AppIcon,
+ std::string, /* package */
+ std::string, /* activity */
+ arc::ScaleFactor, /* scale_factor */
+ std::vector<uint8_t> /* icon_png_data */)
diff --git a/components/arc/common/arc_instance_messages.h b/components/arc/common/arc_instance_messages.h
index 94870469..31597d2 100644
--- a/components/arc/common/arc_instance_messages.h
+++ b/components/arc/common/arc_instance_messages.h
@@ -7,6 +7,8 @@
#include <stdint.h>
+#include <string>
+
#include "base/file_descriptor_posix.h"
#include "ipc/ipc_message_macros.h"
@@ -24,3 +26,23 @@
std::string, /* name */
std::string, /* device_type */
base::FileDescriptor /* fd */)
+
+// Sends a request to ARC to refresh a list of ARC apps.
+// ArcInstanceMsg_RefreshApps is expected in response to this message. However,
+// response may not be sent if ARC is not ready yet (boot completed event is
+// not received).
+IPC_MESSAGE_CONTROL0(ArcInstanceMsg_RefreshApps)
+
+// Sends a request to ARC to launch an ARC app defined by |package| and
+// |activity|, which cannot be empty.
+IPC_MESSAGE_CONTROL2(ArcInstanceMsg_LaunchApp,
+ std::string, /* package */
+ std::string /* activity */)
+
+// Sends a request to ARC for the ARC app icon of a required scale factor.
+// Scale factor is an enum defined at ui/base/layout.h. App is defined by
+// package and activity, which cannot be empty.
+IPC_MESSAGE_CONTROL3(ArcInstanceMsg_RequestAppIcon,
+ std::string, /* package */
+ std::string, /* activity */
+ arc::ScaleFactor /* scale factor */)
diff --git a/components/arc/common/arc_message_generator.h b/components/arc/common/arc_message_generator.h
index 2b302a6..bd50a43 100644
--- a/components/arc/common/arc_message_generator.h
+++ b/components/arc/common/arc_message_generator.h
@@ -7,3 +7,4 @@
// Not using the full path since this is also expected to be compiled in ARC.
#include "arc_host_messages.h"
#include "arc_instance_messages.h"
+#include "arc_message_traits.h"
diff --git a/components/arc/common/arc_message_traits.h b/components/arc/common/arc_message_traits.h
new file mode 100644
index 0000000..9d0938f
--- /dev/null
+++ b/components/arc/common/arc_message_traits.h
@@ -0,0 +1,17 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/arc/common/arc_message_types.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_utils.h"
+
+IPC_ENUM_TRAITS_MIN_MAX_VALUE(arc::ScaleFactor,
+ arc::ScaleFactor::SCALE_FACTOR_100P,
+ arc::ScaleFactor::NUM_SCALE_FACTORS);
+
+IPC_STRUCT_TRAITS_BEGIN(arc::AppInfo)
+ IPC_STRUCT_TRAITS_MEMBER(name)
+ IPC_STRUCT_TRAITS_MEMBER(package)
+ IPC_STRUCT_TRAITS_MEMBER(activity)
+IPC_STRUCT_TRAITS_END()
diff --git a/components/arc/common/arc_message_types.h b/components/arc/common/arc_message_types.h
index e07193d..5971a6b 100644
--- a/components/arc/common/arc_message_types.h
+++ b/components/arc/common/arc_message_types.h
@@ -5,7 +5,10 @@
#ifndef COMPONENTS_ARC_COMMON_MESSAGE_TYPES
#define COMPONENTS_ARC_COMMON_MESSAGE_TYPES
+#include <string>
+
namespace arc {
+
// Describing the boot phase of the ARC instance, as defined by AOSP in
// com.android.server.SystemService
enum class InstanceBootPhase {
@@ -35,6 +38,30 @@
// Last enum entry for IPC_ENUM_TRAITS
LAST = BOOT_COMPLETED
};
-}
+
+// Duplicates ui::ScaleFactor enum in order to be accessible on Android side.
+enum ScaleFactor : int {
+ SCALE_FACTOR_NONE = 0,
+ SCALE_FACTOR_100P,
+ SCALE_FACTOR_125P,
+ SCALE_FACTOR_133P,
+ SCALE_FACTOR_140P,
+ SCALE_FACTOR_150P,
+ SCALE_FACTOR_180P,
+ SCALE_FACTOR_200P,
+ SCALE_FACTOR_250P,
+ SCALE_FACTOR_300P,
+
+ NUM_SCALE_FACTORS
+};
+
+// Describes ARC app.
+struct AppInfo {
+ std::string name;
+ std::string package;
+ std::string activity;
+};
+
+} // namespace arc
#endif // COMPONENTS_ARC_COMMON_MESSAGE_TYPES