Commit e1201996 authored by Achuith Bhandarkar's avatar Achuith Bhandarkar Committed by Commit Bot

Introduce usersPrivate.getLoginStatus

This method is intended to be used by the smart-card extension to monitor login
status.

* cros-specific usersPrivate.getLoginStatus returns a dictionary with
data members isLoggedIn and isScreenLocked.
* tests for logged-in user, and screenlock cases.

Bug: 777356
Test: browser_tests --gtest_filter=UsersPrivateApiLo\*
Cq-Include-Trybots: luci.chromium.try:closure_compilation
Change-Id: Ib0ba29d3c715fb0ce162ba234ca9be657d40582c
Reviewed-on: https://chromium-review.googlesource.com/1094203
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarAchuith Bhandarkar <achuith@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576235}
parent 83d9049b
achuith@chromium.org
alemate@chromium.org
emaxx@chromium.org
michaelpg@chromium.org michaelpg@chromium.org
stevenjb@chromium.org stevenjb@chromium.org
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/users_private.h" #include "chrome/common/extensions/api/users_private.h"
#include "chromeos/settings/cros_settings_names.h" #include "chromeos/settings/cros_settings_names.h"
#include "components/session_manager/core/session_manager.h"
#include "components/user_manager/user.h" #include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "components/user_manager/user_names.h" #include "components/user_manager/user_names.h"
...@@ -278,4 +279,25 @@ ExtensionFunction::ResponseAction UsersPrivateGetCurrentUserFunction::Run() { ...@@ -278,4 +279,25 @@ ExtensionFunction::ResponseAction UsersPrivateGetCurrentUserFunction::Run() {
: RespondNow(Error("No Current User")); : RespondNow(Error("No Current User"));
} }
////////////////////////////////////////////////////////////////////////////////
// UsersPrivateGetLoginStatusFunction
UsersPrivateGetLoginStatusFunction::UsersPrivateGetLoginStatusFunction() =
default;
UsersPrivateGetLoginStatusFunction::~UsersPrivateGetLoginStatusFunction() =
default;
ExtensionFunction::ResponseAction UsersPrivateGetLoginStatusFunction::Run() {
const user_manager::UserManager* user_manager =
user_manager::UserManager::Get();
const bool is_logged_in = user_manager && user_manager->IsUserLoggedIn();
const bool is_screen_locked =
session_manager::SessionManager::Get()->IsScreenLocked();
auto result = std::make_unique<base::DictionaryValue>();
result->SetKey("isLoggedIn", base::Value(is_logged_in));
result->SetKey("isScreenLocked", base::Value(is_screen_locked));
return RespondNow(OneArgument(std::move(result)));
}
} // namespace extensions } // namespace extensions
...@@ -110,6 +110,21 @@ class UsersPrivateGetCurrentUserFunction : public UIThreadExtensionFunction { ...@@ -110,6 +110,21 @@ class UsersPrivateGetCurrentUserFunction : public UIThreadExtensionFunction {
DISALLOW_COPY_AND_ASSIGN(UsersPrivateGetCurrentUserFunction); DISALLOW_COPY_AND_ASSIGN(UsersPrivateGetCurrentUserFunction);
}; };
class UsersPrivateGetLoginStatusFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("usersPrivate.getLoginStatus",
USERSPRIVATE_GETLOGINSTATUS)
UsersPrivateGetLoginStatusFunction();
private:
~UsersPrivateGetLoginStatusFunction() override;
// ExtensionFunction overrides.
ResponseAction Run() override;
DISALLOW_COPY_AND_ASSIGN(UsersPrivateGetLoginStatusFunction);
};
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_USERS_PRIVATE_USERS_PRIVATE_API_H_ #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_USERS_PRIVATE_USERS_PRIVATE_API_H_
...@@ -9,14 +9,25 @@ ...@@ -9,14 +9,25 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/values.h" #include "base/values.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/extensions/users_private/users_private_delegate.h" #include "chrome/browser/chromeos/extensions/users_private/users_private_delegate.h"
#include "chrome/browser/chromeos/extensions/users_private/users_private_delegate_factory.h" #include "chrome/browser/chromeos/extensions/users_private/users_private_delegate_factory.h"
#include "chrome/browser/chromeos/login/lock/screen_locker.h"
#include "chrome/browser/chromeos/login/lock/screen_locker_tester.h"
#include "chrome/browser/chromeos/login/test/oobe_base_test.h"
#include "chrome/browser/extensions/api/settings_private/prefs_util.h" #include "chrome/browser/extensions/api/settings_private/prefs_util.h"
#include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/users_private.h" #include "chrome/common/extensions/api/users_private.h"
#include "chromeos/chromeos_switches.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/session_manager/core/session_manager.h"
#include "components/session_manager/session_manager_types.h"
#include "content/public/browser/notification_service.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "extensions/browser/api/test/test_api.h"
#include "extensions/common/switches.h" #include "extensions/common/switches.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -166,6 +177,51 @@ class UsersPrivateApiTest : public ExtensionApiTest { ...@@ -166,6 +177,51 @@ class UsersPrivateApiTest : public ExtensionApiTest {
// static // static
TestDelegate* UsersPrivateApiTest::s_test_delegate_ = NULL; TestDelegate* UsersPrivateApiTest::s_test_delegate_ = NULL;
class LoginStatusTestConfig {
public:
LoginStatusTestConfig() = default;
~LoginStatusTestConfig() = default;
void Init() {
extensions::TestGetConfigFunction::set_test_config_state(&test_config_);
}
void Reset() {
extensions::TestGetConfigFunction::set_test_config_state(nullptr);
}
void SetConfig(bool logged_in, bool screen_locked) {
test_config_.SetPath({"loginStatus", "isLoggedIn"}, base::Value(logged_in));
test_config_.SetPath({"loginStatus", "isScreenLocked"},
base::Value(screen_locked));
}
private:
base::DictionaryValue test_config_;
};
class UsersPrivateApiLoginStatusTest : public ExtensionApiTest {
protected:
void SetUpOnMainThread() override {
ExtensionApiTest::SetUpOnMainThread();
test_config_.Init();
test_config_.SetConfig(true /*logged_in*/, false /*screen_locked*/);
}
void TearDownOnMainThread() override {
ExtensionApiTest::TearDownOnMainThread();
test_config_.Reset();
}
LoginStatusTestConfig test_config_;
};
class UsersPrivateApiLockStatusTest : public UsersPrivateApiLoginStatusTest {
protected:
void SetUpOnMainThread() override {
UsersPrivateApiLoginStatusTest::SetUpOnMainThread();
test_config_.SetConfig(true /*logged_in*/, true /*screen_locked*/);
}
};
} // namespace } // namespace
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -182,4 +238,31 @@ IN_PROC_BROWSER_TEST_F(UsersPrivateApiTest, IsOwner) { ...@@ -182,4 +238,31 @@ IN_PROC_BROWSER_TEST_F(UsersPrivateApiTest, IsOwner) {
} }
#endif #endif
// User profile - logged in, screen not locked.
IN_PROC_BROWSER_TEST_F(UsersPrivateApiLoginStatusTest, User) {
EXPECT_TRUE(RunExtensionSubtest("users_private", "main.html?getLoginStatus",
kFlagLoadAsComponent))
<< message_;
}
// TODO(achuith): Signin profile - not logged in, screen not locked.
// Screenlock - logged in, screen locked.
IN_PROC_BROWSER_TEST_F(UsersPrivateApiLockStatusTest, ScreenLock) {
chromeos::ScreenLocker::Show();
std::unique_ptr<chromeos::test::ScreenLockerTester> tester(
chromeos::ScreenLocker::GetTester());
tester->EmulateWindowManagerReady();
content::WindowedNotificationObserver lock_state_observer(
chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
content::NotificationService::AllSources());
if (!tester->IsLocked())
lock_state_observer.Wait();
EXPECT_EQ(session_manager::SessionState::LOCKED,
session_manager::SessionManager::Get()->session_state());
EXPECT_TRUE(RunExtensionSubtest("users_private", "main.html?getLoginStatus",
kFlagLoadAsComponent))
<< message_;
}
} // namespace extensions } // namespace extensions
...@@ -753,7 +753,8 @@ ...@@ -753,7 +753,8 @@
}, },
"usersPrivate": [{ "usersPrivate": [{
"dependencies": ["permission:usersPrivate"], "dependencies": ["permission:usersPrivate"],
"contexts": ["blessed_extension"] "contexts": ["blessed_extension"],
"platforms": ["chromeos"]
}, { }, {
"channel": "stable", "channel": "stable",
"contexts": ["webui"], "contexts": ["webui"],
......
...@@ -814,8 +814,12 @@ ...@@ -814,8 +814,12 @@
}, },
"usersPrivate": { "usersPrivate": {
"channel": "trunk", "channel": "trunk",
"platforms": ["chromeos"],
"extension_types": ["extension", "platform_app"], "extension_types": ["extension", "platform_app"],
"location": "component" "whitelist": [
// ChromeOS Autotest extension.
"0D209B5E4401BB8E7873B5AB5B1346A1CB067015"
]
}, },
"wallpaper": { "wallpaper": {
"channel": "stable", "channel": "stable",
......
...@@ -27,11 +27,20 @@ namespace usersPrivate { ...@@ -27,11 +27,20 @@ namespace usersPrivate {
boolean isChild; boolean isChild;
}; };
dictionary LoginStatusDict {
// True if a user is logged in (including guest, public session, etc).
boolean isLoggedIn;
// True if the screen is locked.
boolean isScreenLocked;
};
callback UsersCallback = void (User[] users); callback UsersCallback = void (User[] users);
callback UserAddedCallback = void (boolean success); callback UserAddedCallback = void (boolean success);
callback UserRemovedCallback = void (boolean success); callback UserRemovedCallback = void (boolean success);
callback ManagedCallback = void (boolean managed); callback ManagedCallback = void (boolean managed);
callback UserCallback = void (User user); callback UserCallback = void (User user);
callback LoginStatusCallback = void (LoginStatusDict status);
interface Functions { interface Functions {
// Gets a list of the currently whitelisted users. // Gets a list of the currently whitelisted users.
...@@ -54,5 +63,8 @@ namespace usersPrivate { ...@@ -54,5 +63,8 @@ namespace usersPrivate {
// Returns the current user. // Returns the current user.
static void getCurrentUser(UserCallback callback); static void getCurrentUser(UserCallback callback);
// Get login status.
static void getLoginStatus(LoginStatusCallback callback);
}; };
}; };
...@@ -74,6 +74,31 @@ var availableTests = [ ...@@ -74,6 +74,31 @@ var availableTests = [
chrome.test.succeed(); chrome.test.succeed();
}); });
}, },
function getLoginStatus() {
chrome.test.getConfig(chrome.test.callbackPass(function(config) {
// Validate the config.
chrome.test.assertTrue(config.hasOwnProperty("loginStatus"));
chrome.test.assertTrue(config.loginStatus.hasOwnProperty("isLoggedIn"));
chrome.test.assertTrue(
config.loginStatus.hasOwnProperty("isScreenLocked"));
chrome.usersPrivate.getLoginStatus(
chrome.test.callbackPass(function(status) {
chrome.test.assertEq(typeof(status), 'object');
chrome.test.assertTrue(status.hasOwnProperty("isLoggedIn"));
chrome.test.assertTrue(status.hasOwnProperty("isScreenLocked"));
console.log(status.isLoggedIn);
console.log(config.loginStatus.isLoggedIn);
chrome.test.assertEq(
status.isLoggedIn, config.loginStatus.isLoggedIn);
console.log(status.isScreenLocked);
console.log(config.loginStatus.isScreenLocked);
chrome.test.assertEq(
status.isScreenLocked, config.loginStatus.isScreenLocked);
}));
}));
},
]; ];
var testToRun = window.location.search.substring(1); var testToRun = window.location.search.substring(1);
......
...@@ -1322,6 +1322,7 @@ enum HistogramValue { ...@@ -1322,6 +1322,7 @@ enum HistogramValue {
SYSTEM_POWER_SOURCE_GETPOWERSOURCEINFO = 1259, SYSTEM_POWER_SOURCE_GETPOWERSOURCEINFO = 1259,
SYSTEM_POWER_SOURCE_REQUESTSTATUSUPDATE = 1260, SYSTEM_POWER_SOURCE_REQUESTSTATUSUPDATE = 1260,
INPUTMETHODPRIVATE_GETSURROUNDINGTEXT = 1261, INPUTMETHODPRIVATE_GETSURROUNDINGTEXT = 1261,
USERSPRIVATE_GETLOGINSTATUS = 1262,
// Last entry: Add new entries above, then run: // Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py // python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY ENUM_BOUNDARY
......
...@@ -65,6 +65,23 @@ ...@@ -65,6 +65,23 @@
"type": "boolean", "type": "boolean",
"optional": true, "optional": true,
"description": "Whether native extension bindings are enabled." "description": "Whether native extension bindings are enabled."
},
"loginStatus": {
"type": "object",
"optional": true,
"description": "Login status.",
"properties": {
"isLoggedIn": {
"type": "boolean",
"optional": true,
"description": "Whether there's a logged-in user."
},
"isScreenLocked": {
"type": "boolean",
"optional": true,
"description": "Whether the screen is locked."
}
}
} }
} }
} }
......
...@@ -28,6 +28,14 @@ chrome.usersPrivate = {}; ...@@ -28,6 +28,14 @@ chrome.usersPrivate = {};
*/ */
chrome.usersPrivate.User; chrome.usersPrivate.User;
/**
* @typedef {{
* isLoggedIn: boolean,
* isScreenLocked: boolean
* }}
*/
chrome.usersPrivate.LoginStatusDict;
/** /**
* Gets a list of the currently whitelisted users. * Gets a list of the currently whitelisted users.
* @param {function(!Array<!chrome.usersPrivate.User>):void} callback * @param {function(!Array<!chrome.usersPrivate.User>):void} callback
...@@ -64,3 +72,9 @@ chrome.usersPrivate.isWhitelistManaged = function(callback) {}; ...@@ -64,3 +72,9 @@ chrome.usersPrivate.isWhitelistManaged = function(callback) {};
* @param {function(!chrome.usersPrivate.User):void} callback * @param {function(!chrome.usersPrivate.User):void} callback
*/ */
chrome.usersPrivate.getCurrentUser = function(callback) {}; chrome.usersPrivate.getCurrentUser = function(callback) {};
/**
* Get login status.
* @param {function(!chrome.usersPrivate.LoginStatusDict):void} callback
*/
chrome.usersPrivate.getLoginStatus = function(callback) {};
...@@ -16077,6 +16077,7 @@ Called by update_net_error_codes.py.--> ...@@ -16077,6 +16077,7 @@ Called by update_net_error_codes.py.-->
<int value="1259" label="SYSTEM_POWER_SOURCE_GETPOWERSOURCEINFO"/> <int value="1259" label="SYSTEM_POWER_SOURCE_GETPOWERSOURCEINFO"/>
<int value="1260" label="SYSTEM_POWER_SOURCE_REQUESTSTATUSUPDATE"/> <int value="1260" label="SYSTEM_POWER_SOURCE_REQUESTSTATUSUPDATE"/>
<int value="1261" label="INPUTMETHODPRIVATE_GETSURROUNDINGTEXT"/> <int value="1261" label="INPUTMETHODPRIVATE_GETSURROUNDINGTEXT"/>
<int value="1262" label="USERSPRIVATE_GETLOGINSTATUS"/>
</enum> </enum>
<enum name="ExtensionIconState"> <enum name="ExtensionIconState">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment