summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chrome_process_singleton_win_unittest.cc
blob: d56d7a576981baa34470a4f895c847fde6099cad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) 2013 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 "chrome/browser/chrome_process_singleton.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

bool ServerCallback(int* callback_count,
                    const base::CommandLine& command_line,
                    const base::FilePath& current_directory) {
  ++(*callback_count);
  return true;
}

bool ClientCallback(const base::CommandLine& command_line,
                    const base::FilePath& current_directory) {
  ADD_FAILURE();
  return false;
}

}  // namespace

TEST(ChromeProcessSingletonTest, Basic) {
  base::ScopedTempDir profile_dir;
  ASSERT_TRUE(profile_dir.CreateUniqueTempDir());

  int callback_count = 0;

  ChromeProcessSingleton ps1(
      profile_dir.path(),
      base::Bind(&ServerCallback, base::Unretained(&callback_count)));
  ps1.Unlock();

  ChromeProcessSingleton ps2(profile_dir.path(), base::Bind(&ClientCallback));
  ps2.Unlock();

  ProcessSingleton::NotifyResult result = ps1.NotifyOtherProcessOrCreate();

  ASSERT_EQ(ProcessSingleton::PROCESS_NONE, result);
  ASSERT_EQ(0, callback_count);

  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);

  ASSERT_EQ(1, callback_count);
}

TEST(ChromeProcessSingletonTest, Lock) {
  base::ScopedTempDir profile_dir;
  ASSERT_TRUE(profile_dir.CreateUniqueTempDir());

  int callback_count = 0;

  ChromeProcessSingleton ps1(
      profile_dir.path(),
      base::Bind(&ServerCallback, base::Unretained(&callback_count)));

  ChromeProcessSingleton ps2(profile_dir.path(), base::Bind(&ClientCallback));
  ps2.Unlock();

  ProcessSingleton::NotifyResult result = ps1.NotifyOtherProcessOrCreate();

  ASSERT_EQ(ProcessSingleton::PROCESS_NONE, result);
  ASSERT_EQ(0, callback_count);

  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);

  ASSERT_EQ(0, callback_count);
  ps1.Unlock();
  ASSERT_EQ(1, callback_count);
}

#if defined(OS_WIN) && !defined(USE_AURA)
namespace {

void SetForegroundWindowHandler(bool* flag,
                                gfx::NativeWindow /* target_window */) {
  *flag = true;
}

}  // namespace

TEST(ChromeProcessSingletonTest, LockWithModalDialog) {
  base::ScopedTempDir profile_dir;
  ASSERT_TRUE(profile_dir.CreateUniqueTempDir());

  int callback_count = 0;
  bool called_set_foreground_window = false;

  ChromeProcessSingleton ps1(
      profile_dir.path(),
      base::Bind(&ServerCallback, base::Unretained(&callback_count)),
      base::Bind(&SetForegroundWindowHandler,
                 base::Unretained(&called_set_foreground_window)));
  ps1.SetActiveModalDialog(::GetShellWindow());

  ChromeProcessSingleton ps2(profile_dir.path(), base::Bind(&ClientCallback));
  ps2.Unlock();

  ProcessSingleton::NotifyResult result = ps1.NotifyOtherProcessOrCreate();

  ASSERT_EQ(ProcessSingleton::PROCESS_NONE, result);
  ASSERT_EQ(0, callback_count);

  ASSERT_FALSE(called_set_foreground_window);
  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);
  ASSERT_TRUE(called_set_foreground_window);

  ASSERT_EQ(0, callback_count);
  ps1.SetActiveModalDialog(NULL);
  ps1.Unlock();
  // The notification sent while a modal dialog was present was silently
  // dropped.
  ASSERT_EQ(0, callback_count);

  // But now that the active modal dialog is NULL notifications will be handled.
  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);
  ASSERT_EQ(1, callback_count);
}
#endif  // defined(OS_WIN) && !defined(USE_AURA)