Idle: Add ScopedSetIdleState to make ui/base/idle more test-friendly
This CL adds a new ScopedSetIdleState class for testing that sets an
overriding idle state in ui/base/idle so that classes depending on
ui/base/idle can be more easily tested.
(cherry picked from commit ecd097eeadf2ba1df20c0c269cedfc80912ebeb7)
Bug: 951560
Change-Id: I4234af0783c7fc053620803b74f0ef6b0fc0ce4c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1643414
Reviewed-by: Scott Violet <sky@chromium.org>
Commit-Queue: Tommy Steimel <steimel@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#666444}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1653869
Reviewed-by: Tommy Steimel <steimel@chromium.org>
Cr-Commit-Position: refs/branch-heads/3809@{#234}
Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002}
diff --git a/ui/base/idle/BUILD.gn b/ui/base/idle/BUILD.gn
index d9e3eea..530d02a 100644
--- a/ui/base/idle/BUILD.gn
+++ b/ui/base/idle/BUILD.gn
@@ -13,6 +13,13 @@
defines = [ "IS_UI_BASE_IDLE_IMPL" ]
+ # All targets in this file are allowed to access any of the headers.
+ friend = [ ":*" ]
+
+ public = [
+ "idle.h",
+ ]
+
deps = [
"//base",
"//ui/base",
@@ -26,6 +33,8 @@
"idle.cc",
"idle.h",
"idle_chromeos.cc",
+ "idle_internal.cc",
+ "idle_internal.h",
"idle_mac.mm",
"idle_win.cc",
]
@@ -66,3 +75,17 @@
]
}
}
+
+static_library("test_support") {
+ testonly = true
+
+ sources = [
+ "scoped_set_idle_state.cc",
+ "scoped_set_idle_state.h",
+ ]
+
+ deps = [
+ ":idle",
+ "//base",
+ ]
+}
diff --git a/ui/base/idle/idle.cc b/ui/base/idle/idle.cc
index 0333fbc..3f0e34d 100644
--- a/ui/base/idle/idle.cc
+++ b/ui/base/idle/idle.cc
@@ -4,9 +4,14 @@
#include "ui/base/idle/idle.h"
+#include "ui/base/idle/idle_internal.h"
+
namespace ui {
IdleState CalculateIdleState(int idle_threshold) {
+ if (IdleStateForTesting().has_value())
+ return IdleStateForTesting().value();
+
if (CheckIdleStateIsLocked())
return IDLE_STATE_LOCKED;
diff --git a/ui/base/idle/idle_android.cc b/ui/base/idle/idle_android.cc
index f21e03d..40190e8 100644
--- a/ui/base/idle/idle_android.cc
+++ b/ui/base/idle/idle_android.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "jni/IdleDetector_jni.h"
+#include "ui/base/idle/idle_internal.h"
using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF8;
@@ -71,6 +72,9 @@
}
bool CheckIdleStateIsLocked() {
+ if (IdleStateForTesting().has_value())
+ return IdleStateForTesting().value() == IDLE_STATE_LOCKED;
+
return AndroidIdleMonitor::GetInstance()->CheckIdleStateIsLocked();
}
diff --git a/ui/base/idle/idle_chromeos.cc b/ui/base/idle/idle_chromeos.cc
index a58a285..a0f4cde 100644
--- a/ui/base/idle/idle_chromeos.cc
+++ b/ui/base/idle/idle_chromeos.cc
@@ -6,6 +6,7 @@
#include "base/time/time.h"
#include "chromeos/dbus/session_manager/session_manager_client.h"
+#include "ui/base/idle/idle_internal.h"
#include "ui/base/user_activity/user_activity_detector.h"
namespace ui {
@@ -17,6 +18,9 @@
}
bool CheckIdleStateIsLocked() {
+ if (IdleStateForTesting().has_value())
+ return IdleStateForTesting().value() == IDLE_STATE_LOCKED;
+
return chromeos::SessionManagerClient::Get()->IsScreenLocked();
}
diff --git a/ui/base/idle/idle_internal.cc b/ui/base/idle/idle_internal.cc
new file mode 100644
index 0000000..ac62882
--- /dev/null
+++ b/ui/base/idle/idle_internal.cc
@@ -0,0 +1,16 @@
+// Copyright 2019 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 "ui/base/idle/idle_internal.h"
+
+#include "base/no_destructor.h"
+
+namespace ui {
+
+base::Optional<IdleState>& IdleStateForTesting() {
+ static base::NoDestructor<base::Optional<IdleState>> idle_state;
+ return *idle_state;
+}
+
+} // namespace ui
diff --git a/ui/base/idle/idle_internal.h b/ui/base/idle/idle_internal.h
new file mode 100644
index 0000000..01e9598
--- /dev/null
+++ b/ui/base/idle/idle_internal.h
@@ -0,0 +1,20 @@
+// Copyright 2019 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.
+
+#ifndef UI_BASE_IDLE_IDLE_INTERNAL_H_
+#define UI_BASE_IDLE_IDLE_INTERNAL_H_
+
+#include "base/component_export.h"
+#include "base/optional.h"
+#include "ui/base/idle/idle.h"
+
+namespace ui {
+
+// An optional idle state set by tests via a ScopedSetIdleState to override the
+// actual idle state of the system.
+COMPONENT_EXPORT(UI_BASE_IDLE) base::Optional<IdleState>& IdleStateForTesting();
+
+} // namespace ui
+
+#endif // UI_BASE_IDLE_IDLE_INTERNAL_H_
diff --git a/ui/base/idle/idle_linux.cc b/ui/base/idle/idle_linux.cc
index 7058b87..ec0ed5c 100644
--- a/ui/base/idle/idle_linux.cc
+++ b/ui/base/idle/idle_linux.cc
@@ -4,6 +4,8 @@
#include "ui/base/idle/idle.h"
+#include "ui/base/idle/idle_internal.h"
+
#if defined(USE_X11)
#include "ui/base/idle/idle_query_x11.h"
#include "ui/base/idle/screensaver_window_finder_x11.h"
@@ -21,6 +23,9 @@
}
bool CheckIdleStateIsLocked() {
+ if (IdleStateForTesting().has_value())
+ return IdleStateForTesting().value() == IDLE_STATE_LOCKED;
+
#if defined(USE_X11)
// Usually the screensaver is used to lock the screen.
return ScreensaverWindowFinder::ScreensaverWindowExists();
diff --git a/ui/base/idle/idle_mac.mm b/ui/base/idle/idle_mac.mm
index dc35550..5453586 100644
--- a/ui/base/idle/idle_mac.mm
+++ b/ui/base/idle/idle_mac.mm
@@ -7,6 +7,8 @@
#include <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
+#include "ui/base/idle/idle_internal.h"
+
@interface MacScreenMonitor : NSObject {
@private
BOOL screensaverRunning_;
@@ -92,6 +94,9 @@
}
bool CheckIdleStateIsLocked() {
+ if (IdleStateForTesting().has_value())
+ return IdleStateForTesting().value() == IDLE_STATE_LOCKED;
+
return [g_screenMonitor isScreensaverRunning] ||
[g_screenMonitor isScreenLocked];
}
diff --git a/ui/base/idle/idle_win.cc b/ui/base/idle/idle_win.cc
index 4946406..2c1d3a7 100644
--- a/ui/base/idle/idle_win.cc
+++ b/ui/base/idle/idle_win.cc
@@ -7,6 +7,7 @@
#include <limits.h>
#include <windows.h>
+#include "ui/base/idle/idle_internal.h"
#include "ui/base/win/lock_state.h"
namespace ui {
@@ -51,6 +52,9 @@
}
bool CheckIdleStateIsLocked() {
+ if (IdleStateForTesting().has_value())
+ return IdleStateForTesting().value() == IDLE_STATE_LOCKED;
+
return ui::IsWorkstationLocked() || IsScreensaverRunning();
}
diff --git a/ui/base/idle/scoped_set_idle_state.cc b/ui/base/idle/scoped_set_idle_state.cc
new file mode 100644
index 0000000..93baa00
--- /dev/null
+++ b/ui/base/idle/scoped_set_idle_state.cc
@@ -0,0 +1,20 @@
+// Copyright 2019 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 "ui/base/idle/scoped_set_idle_state.h"
+
+#include "ui/base/idle/idle_internal.h"
+
+namespace ui {
+
+ScopedSetIdleState::ScopedSetIdleState(IdleState state)
+ : previous_state_(IdleStateForTesting()) {
+ IdleStateForTesting() = state;
+}
+
+ScopedSetIdleState::~ScopedSetIdleState() {
+ IdleStateForTesting() = previous_state_;
+}
+
+} // namespace ui
diff --git a/ui/base/idle/scoped_set_idle_state.h b/ui/base/idle/scoped_set_idle_state.h
new file mode 100644
index 0000000..fa3e617
--- /dev/null
+++ b/ui/base/idle/scoped_set_idle_state.h
@@ -0,0 +1,26 @@
+// Copyright 2019 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.
+
+#ifndef UI_BASE_IDLE_SCOPED_SET_IDLE_STATE_H_
+#define UI_BASE_IDLE_SCOPED_SET_IDLE_STATE_H_
+
+#include "base/optional.h"
+#include "ui/base/idle/idle.h"
+
+namespace ui {
+
+class ScopedSetIdleState {
+ public:
+ explicit ScopedSetIdleState(IdleState state);
+ ~ScopedSetIdleState();
+
+ private:
+ base::Optional<IdleState> previous_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSetIdleState);
+};
+
+} // namespace ui
+
+#endif // UI_BASE_IDLE_SCOPED_SET_IDLE_STATE_H_
\ No newline at end of file