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