[go: up one dir, main page]

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