12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/apps/app_shim/app_shim_host_mac.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <vector>
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/basictypes.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/mac/app_shim_messages.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace {
16a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestingAppShimHost : public AppShimHost {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestingAppShimHost() {}
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestingAppShimHost() {}
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ReceiveMessage(IPC::Message* message);
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::vector<IPC::Message*>& sent_messages() {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return sent_messages_.get();
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool Send(IPC::Message* message) OVERRIDE;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) private:
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<IPC::Message> sent_messages_;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestingAppShimHost);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TestingAppShimHost::ReceiveMessage(IPC::Message* message) {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool handled = OnMessageReceived(*message);
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete message;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return handled;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TestingAppShimHost::Send(IPC::Message* message) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sent_messages_.push_back(message);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kTestAppId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kTestProfileDir[] = "Profile 1";
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)class AppShimHostTest : public testing::Test,
52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                        public apps::AppShimHandler {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AppShimHostTest() : launch_result_(apps::APP_SHIM_LAUNCH_SUCCESS),
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      launch_count_(0),
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      launch_now_count_(0),
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      close_count_(0),
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      focus_count_(0),
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      quit_count_(0) {}
60a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestingAppShimHost* host() { return host_.get(); }
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void LaunchApp(apps::AppShimLaunchType launch_type) {
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(host()->ReceiveMessage(
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        new AppShimHostMsg_LaunchApp(base::FilePath(kTestProfileDir),
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                     kTestAppId,
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                     launch_type,
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                     std::vector<base::FilePath>())));
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  apps::AppShimLaunchResult GetLaunchResult() {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, host()->sent_messages().size());
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC::Message* message = host()->sent_messages()[0];
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(AppShimMsg_LaunchApp_Done::ID, message->type());
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppShimMsg_LaunchApp_Done::Param param;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppShimMsg_LaunchApp_Done::Read(message, &param);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return param.a;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  void SimulateDisconnect() {
81a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    implicit_cast<IPC::Listener*>(host_.release())->OnChannelError();
82a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
83a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
84a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) protected:
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnShimLaunch(Host* host,
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            apps::AppShimLaunchType launch_type,
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            const std::vector<base::FilePath>& file) OVERRIDE {
88a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ++launch_count_;
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (launch_type == apps::APP_SHIM_LAUNCH_NORMAL)
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ++launch_now_count_;
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    host->OnAppLaunchComplete(launch_result_);
92a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
94a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  virtual void OnShimClose(Host* host) OVERRIDE { ++close_count_; }
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void OnShimFocus(Host* host,
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           apps::AppShimFocusType focus_type,
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           const std::vector<base::FilePath>& file) OVERRIDE {
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ++focus_count_;
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void OnShimSetHidden(Host* host, bool hidden) OVERRIDE {}
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void OnShimQuit(Host* host) OVERRIDE { ++quit_count_; }
105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  apps::AppShimLaunchResult launch_result_;
107a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int launch_count_;
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int launch_now_count_;
109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int close_count_;
110a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int focus_count_;
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int quit_count_;
112a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    testing::Test::SetUp();
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    host_.reset(new TestingAppShimHost());
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TestingAppShimHost> host_;
120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
121a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppShimHostTest);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}  // namespace
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(AppShimHostTest, TestLaunchAppWithHandler) {
128a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  apps::AppShimHandler::RegisterHandler(kTestAppId, this);
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LaunchApp(apps::APP_SHIM_LAUNCH_NORMAL);
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(kTestAppId,
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            implicit_cast<apps::AppShimHandler::Host*>(host())->GetAppId());
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(apps::APP_SHIM_LAUNCH_SUCCESS, GetLaunchResult());
133a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(1, launch_count_);
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, launch_now_count_);
135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(0, focus_count_);
136a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(0, close_count_);
137a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // A second OnAppLaunchComplete is ignored.
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  implicit_cast<apps::AppShimHandler::Host*>(host())->
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_APP_NOT_FOUND);
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(apps::APP_SHIM_LAUNCH_SUCCESS, GetLaunchResult());
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(host()->ReceiveMessage(
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new AppShimHostMsg_FocusApp(apps::APP_SHIM_FOCUS_NORMAL,
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  std::vector<base::FilePath>())));
146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(1, focus_count_);
147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(host()->ReceiveMessage(new AppShimHostMsg_QuitApp()));
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, quit_count_);
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
151a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SimulateDisconnect();
152a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(1, close_count_);
153a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  apps::AppShimHandler::RemoveHandler(kTestAppId);
154a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(AppShimHostTest, TestNoLaunchNow) {
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  apps::AppShimHandler::RegisterHandler(kTestAppId, this);
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LaunchApp(apps::APP_SHIM_LAUNCH_REGISTER_ONLY);
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(kTestAppId,
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            implicit_cast<apps::AppShimHandler::Host*>(host())->GetAppId());
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(apps::APP_SHIM_LAUNCH_SUCCESS, GetLaunchResult());
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, launch_count_);
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, launch_now_count_);
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, focus_count_);
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, close_count_);
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  apps::AppShimHandler::RemoveHandler(kTestAppId);
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AppShimHostTest, TestFailLaunch) {
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  apps::AppShimHandler::RegisterHandler(kTestAppId, this);
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  launch_result_ = apps::APP_SHIM_LAUNCH_APP_NOT_FOUND;
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LaunchApp(apps::APP_SHIM_LAUNCH_NORMAL);
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(apps::APP_SHIM_LAUNCH_APP_NOT_FOUND, GetLaunchResult());
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  apps::AppShimHandler::RemoveHandler(kTestAppId);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
176