summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrg@chromium.com <brg@chromium.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-16 00:19:34 +0000
committerbrg@chromium.com <brg@chromium.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-16 00:19:34 +0000
commitf5205419c04244f460891b8ff8e30d3793ffa507 (patch)
tree4becb4662d36d92050001eb65e624cffeec95c10
parent5c7c98d536de7fb818b7f23ae52a92383072aa0d (diff)
downloadchromium_src-f5205419c04244f460891b8ff8e30d3793ffa507.zip
chromium_src-f5205419c04244f460891b8ff8e30d3793ffa507.tar.gz
chromium_src-f5205419c04244f460891b8ff8e30d3793ffa507.tar.bz2
Idle API for the extension system
Tests=ExtensionApiTest.Idle Bug=one Review URL: http://codereview.chromium.org/845005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41661 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc4
-rw-r--r--chrome/browser/extensions/extension_idle_api.cc156
-rw-r--r--chrome/browser/extensions/extension_idle_api.h28
-rw-r--r--chrome/browser/extensions/extension_idle_api_constants.cc18
-rw-r--r--chrome/browser/extensions/extension_idle_api_constants.h24
-rw-r--r--chrome/browser/extensions/extension_idle_apitest.cc15
-rw-r--r--chrome/browser/idle.h18
-rw-r--r--chrome/browser/idle_linux.cc15
-rw-r--r--chrome/browser/idle_mac.cc16
-rw-r--r--chrome/browser/idle_win.cc54
-rwxr-xr-xchrome/chrome_browser.gypi7
-rw-r--r--chrome/chrome_tests.gypi1
-rwxr-xr-xchrome/common/extensions/api/extension_api.json43
-rw-r--r--chrome/renderer/resources/renderer_extension_bindings.js1
-rw-r--r--chrome/test/data/extensions/api_test/idle/manifest.json7
-rw-r--r--chrome/test/data/extensions/api_test/idle/test.html1
-rw-r--r--chrome/test/data/extensions/api_test/idle/test.js38
17 files changed, 446 insertions, 0 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 02facbd..6d47016 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/extensions/extension_dom_ui.h"
#include "chrome/browser/extensions/extension_function.h"
#include "chrome/browser/extensions/extension_history_api.h"
+#include "chrome/browser/extensions/extension_idle_api.h"
#include "chrome/browser/extensions/extension_i18n_api.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_metrics_module.h"
@@ -157,6 +158,9 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<GetVisitsHistoryFunction>();
RegisterFunction<SearchHistoryFunction>();
+ // Idle
+ RegisterFunction<ExtensionIdleQueryStateFunction>();
+
// Toolstrips.
RegisterFunction<ToolstripExpandFunction>();
RegisterFunction<ToolstripCollapseFunction>();
diff --git a/chrome/browser/extensions/extension_idle_api.cc b/chrome/browser/extensions/extension_idle_api.cc
new file mode 100644
index 0000000..688e4be
--- /dev/null
+++ b/chrome/browser/extensions/extension_idle_api.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2010 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.
+
+// This implementation supposes a single extension thread and synchronized
+// method invokation.
+
+#include "chrome/browser/extensions/extension_idle_api.h"
+
+#include "base/stl_util-inl.h"
+#include "base/json/json_writer.h"
+#include "base/task.h"
+#include "base/time.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/extensions/extension_host.h"
+#include "chrome/browser/extensions/extension_message_service.h"
+#include "chrome/browser/extensions/extension_idle_api_constants.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/notification_service.h"
+
+namespace keys = extension_idle_api_constants;
+
+namespace {
+
+const int kIdlePollInterval = 15; // Number of seconds between status checks
+ // when polling for active.
+const int kMinThreshold = 15; // In seconds. Set >1 sec for security concerns.
+const int kMaxThreshold = 60*60; // One hours, in seconds. Not set arbitrarily
+ // high for security concerns.
+
+struct ExtensionIdlePollingData {
+ IdleState state;
+ double timestamp;
+};
+
+// Static variables shared between instances of polling.
+static ExtensionIdlePollingData polling_data;
+
+// Forward declaration of utility methods.
+static const wchar_t* IdleStateToDescription(IdleState state);
+static StringValue* CreateIdleValue(IdleState idle_state);
+static int CheckThresholdBounds(int timeout);
+static IdleState CalculateIdleStateAndUpdateTimestamp(int threshold);
+static void CreateNewPollTask(Profile* profile);
+static IdleState ThrottledCalculateIdleState(int threshold, Profile* profile);
+
+// Internal object which watches for changes in the system idle state.
+class ExtensionIdlePollingTask : public Task {
+ public:
+ explicit ExtensionIdlePollingTask(Profile* profile) : profile_(profile) {}
+ virtual ~ExtensionIdlePollingTask() {}
+
+ // Overridden from Task.
+ virtual void Run();
+
+ private:
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionIdlePollingTask);
+};
+
+const wchar_t* IdleStateToDescription(IdleState state) {
+ if (IDLE_STATE_ACTIVE == state)
+ return keys::kStateActive;
+ if (IDLE_STATE_IDLE == state)
+ return keys::kStateIdle;
+ return keys::kStateLocked;
+};
+
+// Helper function for reporting the idle state. The lifetime of the object
+// returned is controlled by the caller.
+StringValue* CreateIdleValue(IdleState idle_state) {
+ StringValue* result = new StringValue(IdleStateToDescription(idle_state));
+ return result;
+}
+
+int CheckThresholdBounds(int timeout) {
+ if (timeout < kMinThreshold) return kMinThreshold;
+ if (timeout > kMaxThreshold) return kMaxThreshold;
+ return timeout;
+}
+
+IdleState CalculateIdleStateAndUpdateTimestamp(int threshold) {
+ polling_data.timestamp = base::Time::Now().ToDoubleT();
+ return CalculateIdleState(threshold);
+}
+
+void CreateNewPollTask(Profile* profile) {
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ new ExtensionIdlePollingTask(profile),
+ kIdlePollInterval * 1000);
+}
+
+IdleState ThrottledCalculateIdleState(int threshold, Profile* profile) {
+ // If we are not active we should be polling.
+ if (IDLE_STATE_ACTIVE != polling_data.state)
+ return polling_data.state;
+
+ // Only allow one check per threshold.
+ double time_now = base::Time::Now().ToDoubleT();
+ double delta = time_now - polling_data.timestamp;
+ if (delta < threshold)
+ return polling_data.state;
+
+ // Update the new state with a poll. Note this updates time of last check.
+ polling_data.state = CalculateIdleStateAndUpdateTimestamp(threshold);
+
+ if (IDLE_STATE_ACTIVE != polling_data.state)
+ CreateNewPollTask(profile);
+
+ return polling_data.state;
+}
+
+void ExtensionIdlePollingTask::Run() {
+ IdleState state = CalculateIdleStateAndUpdateTimestamp(
+ kIdlePollInterval);
+ if (state != polling_data.state) {
+ polling_data.state = state;
+
+ // Inform of change if the current state is IDLE_STATE_ACTIVE.
+ if (IDLE_STATE_ACTIVE == polling_data.state)
+ ExtensionIdleEventRouter::OnIdleStateChange(profile_, state);
+ }
+
+ // Create a secondary polling task until an active state is reached.
+ if (IDLE_STATE_ACTIVE != polling_data.state)
+ CreateNewPollTask(profile_);
+}
+
+}; // namespace
+
+bool ExtensionIdleQueryStateFunction::RunImpl() {
+ int threshold;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&threshold));
+ threshold = CheckThresholdBounds(threshold);
+ IdleState state = ThrottledCalculateIdleState(threshold, profile());
+ result_.reset(CreateIdleValue(state));
+ return true;
+}
+
+void ExtensionIdleEventRouter::OnIdleStateChange(Profile* profile,
+ IdleState state) {
+ // Prepare the single argument of the current state.
+ ListValue args;
+ args.Append(CreateIdleValue(state));
+ std::string json_args;
+ base::JSONWriter::Write(&args, false, &json_args);
+
+ profile->GetExtensionMessageService()->DispatchEventToRenderers(
+ keys::kOnStateChanged,
+ json_args,
+ profile->IsOffTheRecord());
+}
diff --git a/chrome/browser/extensions/extension_idle_api.h b/chrome/browser/extensions/extension_idle_api.h
new file mode 100644
index 0000000..641628a
--- /dev/null
+++ b/chrome/browser/extensions/extension_idle_api.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 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 CHROME_BROWSER_EXTENSIONS_EXTENSION_IDLE_API_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_IDLE_API_H_
+
+#include "chrome/browser/idle.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_function.h"
+
+// Event router class for events related to the idle API.
+class ExtensionIdleEventRouter {
+ public:
+ static void OnIdleStateChange(Profile* profile,
+ IdleState idleState);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ExtensionIdleEventRouter);
+};
+
+// Implementation of the chrome.experimental.idle.queryState API.
+class ExtensionIdleQueryStateFunction : public SyncExtensionFunction {
+ public:
+ virtual bool RunImpl();
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.idle.queryState")
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_IDLE_API_H_
diff --git a/chrome/browser/extensions/extension_idle_api_constants.cc b/chrome/browser/extensions/extension_idle_api_constants.cc
new file mode 100644
index 0000000..7cabe37
--- /dev/null
+++ b/chrome/browser/extensions/extension_idle_api_constants.cc
@@ -0,0 +1,18 @@
+// Copyright (c) 2010 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/extensions/extension_idle_api_constants.h"
+
+namespace extension_idle_api_constants {
+
+const wchar_t kSecondsKey[] = L"seconds";
+const wchar_t kStateKey[] = L"state";
+
+const char kOnStateChanged[] = "experimental.idle.onStateChanged";
+
+const wchar_t kStateActive[] = L"active";
+const wchar_t kStateIdle[] = L"idle";
+const wchar_t kStateLocked[] = L"locked";
+
+} // namespace extension_idle_api_constants
diff --git a/chrome/browser/extensions/extension_idle_api_constants.h b/chrome/browser/extensions/extension_idle_api_constants.h
new file mode 100644
index 0000000..5bdf696
--- /dev/null
+++ b/chrome/browser/extensions/extension_idle_api_constants.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2010 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 CHROME_BROWSER_EXTENSIONS_EXTENSION_IDLE_API_CONSTANTS_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_IDLE_API_CONSTANTS_H_
+
+namespace extension_idle_api_constants {
+
+// Keys.
+extern const wchar_t kSecondsKey[];
+extern const wchar_t kStateKey[];
+
+// Events.
+extern const char kOnStateChanged[];
+
+// States
+extern const wchar_t kStateActive[];
+extern const wchar_t kStateIdle[];
+extern const wchar_t kStateLocked[];
+
+}; // namespace extension_idle_api_constants
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_IDLE_API_CONSTANTS_H_
diff --git a/chrome/browser/extensions/extension_idle_apitest.cc b/chrome/browser/extensions/extension_idle_apitest.cc
new file mode 100644
index 0000000..89d7c3b
--- /dev/null
+++ b/chrome/browser/extensions/extension_idle_apitest.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2010 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 "base/command_line.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/common/chrome_switches.h"
+#include "net/base/mock_host_resolver.h"
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Idle) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ ASSERT_TRUE(RunExtensionTest("idle")) << message_;
+}
diff --git a/chrome/browser/idle.h b/chrome/browser/idle.h
new file mode 100644
index 0000000..e850dbe
--- /dev/null
+++ b/chrome/browser/idle.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2010 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 CHROME_BROWSER_IDLE_H_
+#define CHROME_BROWSER_IDLE_H_
+
+#include "base/task.h"
+
+enum IdleState {
+ IDLE_STATE_ACTIVE = 0,
+ IDLE_STATE_IDLE = 1, // No activity within threshold.
+ IDLE_STATE_LOCKED = 2 // Only available on supported systems.
+};
+
+IdleState CalculateIdleState(unsigned int idle_threshold);
+
+#endif // CHROME_BROWSER_IDLE_H_
diff --git a/chrome/browser/idle_linux.cc b/chrome/browser/idle_linux.cc
new file mode 100644
index 0000000..0da7f72
--- /dev/null
+++ b/chrome/browser/idle_linux.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2010 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/idle.h"
+
+#include "chrome/browser/sync/engine/idle_query_linux.h"
+
+IdleState CalculateIdleState(unsigned int idle_threshold) {
+ browser_sync::IdleQueryLinux idle_query;
+ unsigned int idle_time = idle_query.IdleTime();
+ if (idle_time >= idle_threshold)
+ return IDLE_STATE_IDLE;
+ return IDLE_STATE_ACTIVE;
+}
diff --git a/chrome/browser/idle_mac.cc b/chrome/browser/idle_mac.cc
new file mode 100644
index 0000000..383e4c7
--- /dev/null
+++ b/chrome/browser/idle_mac.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2009 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/idle.h"
+
+#include <CoreGraphics/CGEventSource.h>
+
+IdleState CalculateIdleState(unsigned int idle_threshold) {
+ unsigned int idle_time = CGEventSourceSecondsSinceLastEventType(
+ kCGEventSourceStateCombinedSessionState,
+ kCGAnyInputEventType);
+ if (idle_time >= idle_threshold)
+ return IDLE_STATE_IDLE;
+ return IDLE_STATE_ACTIVE;
+}
diff --git a/chrome/browser/idle_win.cc b/chrome/browser/idle_win.cc
new file mode 100644
index 0000000..0b9ce72
--- /dev/null
+++ b/chrome/browser/idle_win.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 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/idle.h"
+
+static bool IsScreensaverRunning();
+static bool IsWorkstationLocked();
+
+IdleState CalculateIdleState(unsigned int idle_threshold) {
+ if (IsScreensaverRunning() || IsWorkstationLocked())
+ return IDLE_STATE_LOCKED;
+
+ LASTINPUTINFO last_input_info = {0};
+ last_input_info.cbSize = sizeof(LASTINPUTINFO);
+ DWORD current_idle_time = 0;
+ if (::GetLastInputInfo(&last_input_info)) {
+ current_idle_time = ::GetTickCount() - last_input_info.dwTime;
+ // Will go -ve if we have been idle for a long time (2gb seconds).
+ if (current_idle_time < 0)
+ current_idle_time = INT_MAX;
+ // Convert from ms to seconds.
+ current_idle_time /= 1000;
+ }
+
+ if (current_idle_time >= idle_threshold)
+ return IDLE_STATE_IDLE;
+ return IDLE_STATE_ACTIVE;
+}
+
+bool IsScreensaverRunning() {
+ DWORD result = 0;
+ if (::SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &result, 0))
+ return result != FALSE;
+ return false;
+}
+
+bool IsWorkstationLocked() {
+ bool is_locked = true;
+ HDESK input_desk = ::OpenInputDesktop(0, 0, GENERIC_READ);
+ if (input_desk) {
+ wchar_t name[256] = {0};
+ DWORD needed = 0;
+ if (::GetUserObjectInformation(input_desk,
+ UOI_NAME,
+ name,
+ sizeof(name),
+ &needed)) {
+ is_locked = lstrcmpi(name, L"default") != 0;
+ }
+ ::CloseDesktop(input_desk);
+ }
+ return is_locked;
+}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 6dffe8b..22010e6 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -928,6 +928,10 @@
'browser/extensions/extension_host.h',
'browser/extensions/extension_host_mac.h',
'browser/extensions/extension_host_mac.mm',
+ 'browser/extensions/extension_idle_api.cc',
+ 'browser/extensions/extension_idle_api.h',
+ 'browser/extensions/extension_idle_api_constants.cc',
+ 'browser/extensions/extension_idle_api_constants.h',
'browser/extensions/extension_i18n_api.cc',
'browser/extensions/extension_i18n_api.h',
'browser/extensions/extension_install_ui.cc',
@@ -1349,6 +1353,9 @@
'browser/icon_manager_linux.cc',
'browser/icon_manager_mac.mm',
'browser/icon_manager_win.cc',
+ 'browser/idle_linux.cc',
+ 'browser/idle_mac.cc',
+ 'browser/idle_win.cc',
'browser/ime_input.cc',
'browser/ime_input.h',
'browser/important_file_writer.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 10f3fd8..9cb92f7 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1205,6 +1205,7 @@
'browser/extensions/extension_crash_recovery_browsertest.cc',
'browser/extensions/extension_geolocation_apitest.cc',
'browser/extensions/extension_history_apitest.cc',
+ 'browser/extensions/extension_idle_apitest.cc',
'browser/extensions/extension_i18n_apitest.cc',
'browser/extensions/extension_incognito_apitest.cc',
'browser/extensions/extension_javascript_url_apitest.cc',
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index c0042c0..a65aac8 100755
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -1825,6 +1825,49 @@
]
},
{
+ "namespace": "experimental.idle",
+ "nodoc": "true",
+ "types": [],
+ "functions": [
+ {
+ "name": "queryState",
+ "type": "function",
+ "description": "Returns the current state of the browser.",
+ "parameters": [
+ {
+ "name": "threshold",
+ "type": "integer",
+ "minimum": 15,
+ "description": "Threshold used to determine when a machine is in the idle state."
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "parameters": [
+ {
+ "type": "string",
+ "enum": ["active", "idle", "locked"]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "events": [
+ {
+ "name": "onStateChanged",
+ "type": "function",
+ "description": "Fired when the browser changes to an active state. Currently only reports the transition from idle to active.",
+ "parameters": [
+ {
+ "type": "string",
+ "enum": ["active"]
+ }
+ ]
+ }
+ ]
+ },
+ {
"namespace": "toolstrip",
"nodoc": true,
"types": [],
diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js
index e34285b..ba6f314 100644
--- a/chrome/renderer/resources/renderer_extension_bindings.js
+++ b/chrome/renderer/resources/renderer_extension_bindings.js
@@ -247,6 +247,7 @@ var chrome = chrome || {};
"experimental.accessibility",
"experimental.bookmarkManager",
"experimental.extension",
+ "experimental.idle",
"experimental.history",
"experimental.metrics",
"experimental.popup",
diff --git a/chrome/test/data/extensions/api_test/idle/manifest.json b/chrome/test/data/extensions/api_test/idle/manifest.json
new file mode 100644
index 0000000..5284e20
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/idle/manifest.json
@@ -0,0 +1,7 @@
+{
+ "name": "chrome.idle",
+ "version": "0.1",
+ "description": "end-to-end browser test for chrome.idle API",
+ "background_page": "test.html",
+ "permissions": ["experimental"]
+}
diff --git a/chrome/test/data/extensions/api_test/idle/test.html b/chrome/test/data/extensions/api_test/idle/test.html
new file mode 100644
index 0000000..46f4d74
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/idle/test.html
@@ -0,0 +1 @@
+<script src="test.js"></script>
diff --git a/chrome/test/data/extensions/api_test/idle/test.js b/chrome/test/data/extensions/api_test/idle/test.js
new file mode 100644
index 0000000..68dcded
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/idle/test.js
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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.
+
+// Idle api test for Chrome.
+// browser_tests.exe --gtest_filter=ExtensionApiTest.Idle
+
+// Due to the fact that browser tests are run in many different environments it
+// is not simple to be able to set the user input value before testing. For
+// these bvts we have chosen the minimal consistent tests.
+
+var pass = chrome.test.callbackPass;
+var fail = chrome.test.callbackFail;
+var assertEq = chrome.test.assertEq;
+
+chrome.test.runTests([
+ // Exercise querying the state. Querying the state multiple times within
+ // the same threshold exercises different code.
+ function queryState() {
+ chrome.experimental.idle.queryState(60, pass(function(state) {
+ var previous_state = state;
+ chrome.experimental.idle.queryState(120, pass(function(state) {
+ assertEq(previous_state, state);
+ chrome.test.succeed();
+ }));
+ }));
+ },
+
+ // Exercise the setting of the event listener.
+ function setCallback() {
+ chrome.experimental.idle.onStateChanged.addListener(function(state) {
+ window.console.log('current state: ' + state);
+
+ // The test has succeeded.
+ chrome.test.succeed();
+ });
+ }
+]);