1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/ash/screenshot_taker.h"
6
7#include "ash/shell.h"
8#include "ash/test/ash_test_base.h"
9#include "base/bind.h"
10#include "base/command_line.h"
11#include "base/files/file_util.h"
12#include "base/files/scoped_temp_dir.h"
13#include "base/message_loop/message_loop.h"
14#include "chrome/browser/browser_process.h"
15#include "chrome/browser/notifications/notification_ui_manager.h"
16#include "chrome/test/base/in_process_browser_test.h"
17#include "chrome/test/base/testing_browser_process.h"
18#include "chrome/test/base/testing_profile.h"
19#include "chrome/test/base/testing_profile_manager.h"
20#include "content/public/test/test_utils.h"
21#include "ui/aura/window_event_dispatcher.h"
22
23#if defined(OS_CHROMEOS)
24#include "chromeos/login/login_state.h"
25#endif
26
27namespace ash {
28namespace test {
29
30class ScreenshotTakerTest : public AshTestBase,
31                            public ScreenshotTakerObserver {
32 public:
33  ScreenshotTakerTest()
34      : running_(false),
35        screenshot_complete_(false),
36        screenshot_result_(ScreenshotTakerObserver::SCREENSHOT_SUCCESS) {
37  }
38
39  virtual void SetUp() {
40    AshTestBase::SetUp();
41  }
42
43  virtual void TearDown() {
44    RunAllPendingInMessageLoop();
45    AshTestBase::TearDown();
46  }
47
48  // Overridden from ScreenshotTakerObserver
49  virtual void OnScreenshotCompleted(
50      ScreenshotTakerObserver::Result screenshot_result,
51      const base::FilePath& screenshot_path) OVERRIDE {
52    screenshot_complete_ = true;
53    screenshot_result_ = screenshot_result;
54    screenshot_path_ = screenshot_path;
55    if (!running_)
56      return;
57    message_loop_runner_->Quit();
58    running_ = false;
59  }
60
61 protected:
62  // ScreenshotTakerTest is a friend of ScreenshotTaker and therefore
63  // allowed to set the directory, basename and profile.
64  void SetScreenshotDirectoryForTest(
65      ScreenshotTaker* screenshot_taker,
66      const base::FilePath& screenshot_directory) {
67    screenshot_taker->SetScreenshotDirectoryForTest(screenshot_directory);
68  }
69  void SetScreenshotBasenameForTest(
70      ScreenshotTaker* screenshot_taker,
71      const std::string& screenshot_basename) {
72    screenshot_taker->SetScreenshotBasenameForTest(screenshot_basename);
73  }
74  void SetScreenshotProfileForTest(
75      ScreenshotTaker* screenshot_taker,
76      Profile* profile) {
77    screenshot_taker->SetScreenshotProfileForTest(profile);
78  }
79
80  void Wait() {
81    if (screenshot_complete_)
82      return;
83    running_ = true;
84    message_loop_runner_ = new content::MessageLoopRunner;
85    message_loop_runner_->Run();
86    EXPECT_TRUE(screenshot_complete_);
87  }
88
89  bool running_;
90  bool screenshot_complete_;
91  ScreenshotTakerObserver::Result screenshot_result_;
92  base::FilePath screenshot_path_;
93  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
94
95 private:
96  DISALLOW_COPY_AND_ASSIGN(ScreenshotTakerTest);
97};
98
99TEST_F(ScreenshotTakerTest, TakeScreenshot) {
100#if defined(OS_CHROMEOS)
101  // Note that within the test framework the LoginState object will always
102  // claim that the user did log in.
103  ASSERT_FALSE(chromeos::LoginState::IsInitialized());
104  chromeos::LoginState::Initialize();
105#endif
106  scoped_ptr<TestingProfileManager> profile_manager(
107      new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
108  ASSERT_TRUE(profile_manager->SetUp());
109  TestingProfile* profile =
110      profile_manager->CreateTestingProfile("test_profile");
111  ScreenshotTaker screenshot_taker;
112  screenshot_taker.AddObserver(this);
113  base::ScopedTempDir directory;
114  ASSERT_TRUE(directory.CreateUniqueTempDir());
115  SetScreenshotDirectoryForTest(&screenshot_taker, directory.path());
116  SetScreenshotBasenameForTest(&screenshot_taker, "Screenshot");
117  SetScreenshotProfileForTest(&screenshot_taker, profile);
118
119  EXPECT_TRUE(screenshot_taker.CanTakeScreenshot());
120
121  screenshot_taker.HandleTakePartialScreenshot(
122      Shell::GetPrimaryRootWindow(), gfx::Rect(0, 0, 100, 100));
123
124  EXPECT_FALSE(screenshot_taker.CanTakeScreenshot());
125
126  Wait();
127
128#if defined(OS_CHROMEOS)
129  // Screenshot notifications on Windows not yet turned on.
130  EXPECT_TRUE(g_browser_process->notification_ui_manager()->FindById(
131      std::string("screenshot")) != NULL);
132  g_browser_process->notification_ui_manager()->CancelAll();
133#endif
134
135  EXPECT_EQ(ScreenshotTakerObserver::SCREENSHOT_SUCCESS, screenshot_result_);
136
137  if (ScreenshotTakerObserver::SCREENSHOT_SUCCESS == screenshot_result_)
138    EXPECT_TRUE(base::PathExists(screenshot_path_));
139
140#if defined(OS_CHROMEOS)
141  chromeos::LoginState::Shutdown();
142#endif
143}
144
145}  // namespace test
146}  // namespace ash
147