Commit 123c026c authored by tengs@chromium.org's avatar tengs@chromium.org

Add kiosk browser tests for network configuration.

BUG=242589
TEST=existing kiosk tests pass

Review URL: https://chromiumcodereview.appspot.com/23449023

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221848 0039d316-1c4b-4281-b951-d872f2087c98
parent 827d38ae
...@@ -64,6 +64,11 @@ StartupAppLauncher::StartupAppLauncher(Profile* profile, ...@@ -64,6 +64,11 @@ StartupAppLauncher::StartupAppLauncher(Profile* profile,
} }
StartupAppLauncher::~StartupAppLauncher() { StartupAppLauncher::~StartupAppLauncher() {
// StartupAppLauncher can be deleted at anytime during the launch process
// through a user bailout shortcut.
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
->RemoveObserver(this);
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
} }
void StartupAppLauncher::Start() { void StartupAppLauncher::Start() {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/chromeos/login/app_launch_controller.h" #include "chrome/browser/chromeos/login/app_launch_controller.h"
#include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/json/json_file_value_serializer.h" #include "base/json/json_file_value_serializer.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -34,6 +35,9 @@ const int kAppInstallSplashScreenMinTimeMS = 3000; ...@@ -34,6 +35,9 @@ const int kAppInstallSplashScreenMinTimeMS = 3000;
// static // static
bool AppLaunchController::skip_splash_wait_ = false; bool AppLaunchController::skip_splash_wait_ = false;
int AppLaunchController::network_wait_time_ = 10;
base::Closure* AppLaunchController::network_timeout_callback_ = NULL;
UserManager* AppLaunchController::test_user_manager_ = NULL;
AppLaunchController::AppLaunchController(const std::string& app_id, AppLaunchController::AppLaunchController(const std::string& app_id,
LoginDisplayHost* host, LoginDisplayHost* host,
...@@ -46,8 +50,11 @@ AppLaunchController::AppLaunchController(const std::string& app_id, ...@@ -46,8 +50,11 @@ AppLaunchController::AppLaunchController(const std::string& app_id,
oobe_display_->GetAppLaunchSplashScreenActor()), oobe_display_->GetAppLaunchSplashScreenActor()),
error_screen_actor_(oobe_display_->GetErrorScreenActor()), error_screen_actor_(oobe_display_->GetErrorScreenActor()),
waiting_for_network_(false), waiting_for_network_(false),
network_wait_timedout_(false),
showing_network_dialog_(false), showing_network_dialog_(false),
launch_splash_start_time_(0) { launch_splash_start_time_(0) {
signin_screen_.reset(new AppLaunchSigninScreen(
static_cast<OobeUI*>(oobe_display_), this));
} }
AppLaunchController::~AppLaunchController() { AppLaunchController::~AppLaunchController() {
...@@ -66,18 +73,29 @@ void AppLaunchController::StartAppLaunch() { ...@@ -66,18 +73,29 @@ void AppLaunchController::StartAppLaunch() {
kiosk_profile_loader_->Start(); kiosk_profile_loader_->Start();
} }
// static
void AppLaunchController::SkipSplashWaitForTesting() { void AppLaunchController::SkipSplashWaitForTesting() {
skip_splash_wait_ = true; skip_splash_wait_ = true;
} }
void AppLaunchController::SetNetworkWaitForTesting(int wait_time_secs) {
network_wait_time_ = wait_time_secs;
}
void AppLaunchController::SetNetworkTimeoutCallbackForTesting(
base::Closure* callback) {
network_timeout_callback_ = callback;
}
void AppLaunchController::SetUserManagerForTesting(UserManager* user_manager) {
test_user_manager_ = user_manager;
AppLaunchSigninScreen::SetUserManagerForTesting(user_manager);
}
void AppLaunchController::OnConfigureNetwork() { void AppLaunchController::OnConfigureNetwork() {
DCHECK(profile_); DCHECK(profile_);
showing_network_dialog_ = true; showing_network_dialog_ = true;
const std::string& owner_email = UserManager::Get()->GetOwnerEmail(); const std::string& owner_email = GetUserManager()->GetOwnerEmail();
if (!owner_email.empty()) { if (!owner_email.empty()) {
signin_screen_.reset(new AppLaunchSigninScreen(
static_cast<OobeUI*>(oobe_display_), this));
signin_screen_->Show(); signin_screen_->Show();
} else { } else {
// If kiosk mode was configured through enterprise policy, we may // If kiosk mode was configured through enterprise policy, we may
...@@ -145,10 +163,9 @@ void AppLaunchController::OnInitializingNetwork() { ...@@ -145,10 +163,9 @@ void AppLaunchController::OnInitializingNetwork() {
// Show the network configration dialog if network is not initialized // Show the network configration dialog if network is not initialized
// after a brief wait time. // after a brief wait time.
waiting_for_network_ = true; waiting_for_network_ = true;
const int kNetworkConfigWaitSeconds = 10;
network_wait_timer_.Start( network_wait_timer_.Start(
FROM_HERE, FROM_HERE,
base::TimeDelta::FromSeconds(kNetworkConfigWaitSeconds), base::TimeDelta::FromSeconds(network_wait_time_),
this, &AppLaunchController::OnNetworkWaitTimedout); this, &AppLaunchController::OnNetworkWaitTimedout);
} }
...@@ -156,7 +173,10 @@ void AppLaunchController::OnNetworkWaitTimedout() { ...@@ -156,7 +173,10 @@ void AppLaunchController::OnNetworkWaitTimedout() {
DCHECK(waiting_for_network_); DCHECK(waiting_for_network_);
LOG(WARNING) << "OnNetworkWaitTimedout... connection = " LOG(WARNING) << "OnNetworkWaitTimedout... connection = "
<< net::NetworkChangeNotifier::GetConnectionType(); << net::NetworkChangeNotifier::GetConnectionType();
network_wait_timedout_ = true;
app_launch_splash_screen_actor_->ToggleNetworkConfig(true); app_launch_splash_screen_actor_->ToggleNetworkConfig(true);
if (network_timeout_callback_)
network_timeout_callback_->Run();
} }
void AppLaunchController::OnInstallingApp() { void AppLaunchController::OnInstallingApp() {
...@@ -206,4 +226,8 @@ void AppLaunchController::OnLaunchFailed(KioskAppLaunchError::Error error) { ...@@ -206,4 +226,8 @@ void AppLaunchController::OnLaunchFailed(KioskAppLaunchError::Error error) {
Cleanup(); Cleanup();
} }
UserManager* AppLaunchController::GetUserManager() {
return test_user_manager_ ? test_user_manager_ : UserManager::Get();
}
} // namespace chromeos } // namespace chromeos
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
...@@ -24,6 +25,7 @@ namespace chromeos { ...@@ -24,6 +25,7 @@ namespace chromeos {
class LoginDisplayHost; class LoginDisplayHost;
class OobeDisplay; class OobeDisplay;
class UserManager;
// Controller for the kiosk app launch process, responsible for // Controller for the kiosk app launch process, responsible for
// coordinating loading the kiosk profile, launching the app, and // coordinating loading the kiosk profile, launching the app, and
...@@ -43,11 +45,20 @@ class AppLaunchController ...@@ -43,11 +45,20 @@ class AppLaunchController
void StartAppLaunch(); void StartAppLaunch();
bool waiting_for_network() { return waiting_for_network_; }
bool network_wait_timedout() { return network_wait_timedout_; }
bool showing_network_dialog() { return showing_network_dialog_; }
// Customize controller for testing purposes.
static void SkipSplashWaitForTesting(); static void SkipSplashWaitForTesting();
static void SetNetworkTimeoutCallbackForTesting(base::Closure* callback);
static void SetNetworkWaitForTesting(int wait_time_secs);
static void SetUserManagerForTesting(UserManager* user_manager);
private: private:
void Cleanup(); void Cleanup();
void OnNetworkWaitTimedout(); void OnNetworkWaitTimedout();
UserManager* GetUserManager();
// KioskProfileLoader::Delegate overrides: // KioskProfileLoader::Delegate overrides:
virtual void OnProfileLoaded(Profile* profile) OVERRIDE; virtual void OnProfileLoaded(Profile* profile) OVERRIDE;
...@@ -80,10 +91,14 @@ class AppLaunchController ...@@ -80,10 +91,14 @@ class AppLaunchController
base::OneShotTimer<AppLaunchController> network_wait_timer_; base::OneShotTimer<AppLaunchController> network_wait_timer_;
bool waiting_for_network_; bool waiting_for_network_;
bool network_wait_timedout_;
bool showing_network_dialog_; bool showing_network_dialog_;
int64 launch_splash_start_time_; int64 launch_splash_start_time_;
static bool skip_splash_wait_; static bool skip_splash_wait_;
static int network_wait_time_;
static base::Closure* network_timeout_callback_;
static UserManager* test_user_manager_;
DISALLOW_COPY_AND_ASSIGN(AppLaunchController); DISALLOW_COPY_AND_ASSIGN(AppLaunchController);
}; };
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
namespace chromeos { namespace chromeos {
UserManager* AppLaunchSigninScreen::test_user_manager_ = NULL;
AppLaunchSigninScreen::AppLaunchSigninScreen( AppLaunchSigninScreen::AppLaunchSigninScreen(
OobeUI* oobe_ui, Delegate* delegate) OobeUI* oobe_ui, Delegate* delegate)
: oobe_ui_(oobe_ui), : oobe_ui_(oobe_ui),
...@@ -30,7 +32,7 @@ void AppLaunchSigninScreen::Show() { ...@@ -30,7 +32,7 @@ void AppLaunchSigninScreen::Show() {
} }
void AppLaunchSigninScreen::InitOwnerUserList() { void AppLaunchSigninScreen::InitOwnerUserList() {
UserManager* user_manager = UserManager::Get(); UserManager* user_manager = GetUserManager();
const std::string& owner_email = user_manager->GetOwnerEmail(); const std::string& owner_email = user_manager->GetOwnerEmail();
const UserList& all_users = user_manager->GetUsers(); const UserList& all_users = user_manager->GetUsers();
...@@ -46,6 +48,16 @@ void AppLaunchSigninScreen::InitOwnerUserList() { ...@@ -46,6 +48,16 @@ void AppLaunchSigninScreen::InitOwnerUserList() {
} }
} }
// static
void AppLaunchSigninScreen::SetUserManagerForTesting(
UserManager* user_manager) {
test_user_manager_ = user_manager;
}
UserManager* AppLaunchSigninScreen::GetUserManager() {
return test_user_manager_ ? test_user_manager_ : UserManager::Get();
}
void AppLaunchSigninScreen::CancelPasswordChangedFlow() { void AppLaunchSigninScreen::CancelPasswordChangedFlow() {
NOTREACHED(); NOTREACHED();
} }
......
...@@ -42,8 +42,11 @@ class AppLaunchSigninScreen ...@@ -42,8 +42,11 @@ class AppLaunchSigninScreen
void Show(); void Show();
static void SetUserManagerForTesting(UserManager* user_manager);
private: private:
void InitOwnerUserList(); void InitOwnerUserList();
UserManager* GetUserManager();
// SigninScreenHandlerDelegate implementation: // SigninScreenHandlerDelegate implementation:
virtual void CancelPasswordChangedFlow() OVERRIDE; virtual void CancelPasswordChangedFlow() OVERRIDE;
...@@ -93,6 +96,8 @@ class AppLaunchSigninScreen ...@@ -93,6 +96,8 @@ class AppLaunchSigninScreen
// This list should have at most one user, and that user should be the owner. // This list should have at most one user, and that user should be the owner.
UserList owner_user_list_; UserList owner_user_list_;
static UserManager* test_user_manager_;
DISALLOW_COPY_AND_ASSIGN(AppLaunchSigninScreen); DISALLOW_COPY_AND_ASSIGN(AppLaunchSigninScreen);
}; };
......
...@@ -15,10 +15,14 @@ ...@@ -15,10 +15,14 @@
#include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include "chrome/browser/chromeos/login/app_launch_controller.h" #include "chrome/browser/chromeos/login/app_launch_controller.h"
#include "chrome/browser/chromeos/login/app_launch_signin_screen.h"
#include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/existing_user_controller.h"
#include "chrome/browser/chromeos/login/login_display_host_impl.h" #include "chrome/browser/chromeos/login/login_display_host_impl.h"
#include "chrome/browser/chromeos/login/mock_user_manager.h"
#include "chrome/browser/chromeos/login/webui_login_display.h" #include "chrome/browser/chromeos/login/webui_login_display.h"
#include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/lifetime/application_lifetime.h"
...@@ -39,6 +43,7 @@ ...@@ -39,6 +43,7 @@
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "google_apis/gaia/gaia_switches.h" #include "google_apis/gaia/gaia_switches.h"
#include "net/base/host_port_pair.h" #include "net/base/host_port_pair.h"
#include "net/base/network_change_notifier.h"
#include "net/dns/mock_host_resolver.h" #include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_request.h"
...@@ -60,6 +65,12 @@ const base::FilePath kServiceLogin("chromeos/service_login.html"); ...@@ -60,6 +65,12 @@ const base::FilePath kServiceLogin("chromeos/service_login.html");
// detail/ggbflgnkafappblpkiflbgpmkfdpnhhe // detail/ggbflgnkafappblpkiflbgpmkfdpnhhe
const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe"; const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe";
// Timeout while waiting for network connectivity during tests.
const int kTestNetworkTimeoutSeconds = 1;
// Email of owner account for test.
const char kTestOwnerEmail[] = "owner@example.com";
// Helper function for GetConsumerKioskModeStatusCallback. // Helper function for GetConsumerKioskModeStatusCallback.
void ConsumerKioskModeStatusCheck( void ConsumerKioskModeStatusCheck(
KioskAppManager::ConsumerKioskModeStatus* out_status, KioskAppManager::ConsumerKioskModeStatus* out_status,
...@@ -75,13 +86,100 @@ void ConsumerKioskModeLockCheck( ...@@ -75,13 +86,100 @@ void ConsumerKioskModeLockCheck(
bool* out_locked, bool* out_locked,
const base::Closure& runner_quit_task, const base::Closure& runner_quit_task,
bool in_locked) { bool in_locked) {
LOG(INFO) << "kioks locked = " << in_locked; LOG(INFO) << "kiosk locked = " << in_locked;
*out_locked = in_locked; *out_locked = in_locked;
runner_quit_task.Run(); runner_quit_task.Run();
} }
// Helper function for WaitForNetworkTimeOut.
void OnNetworkWaitTimedOut(const base::Closure& runner_quit_task) {
runner_quit_task.Run();
}
} // namespace } // namespace
// Fake NetworkChangeNotifier used to simulate network connectivity.
class FakeNetworkChangeNotifier : public net::NetworkChangeNotifier {
public:
FakeNetworkChangeNotifier() : connection_type_(CONNECTION_NONE) {}
virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
return connection_type_;
}
void GoOnline() {
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
}
void GoOffline() {
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE);
}
void SetConnectionType(ConnectionType type) {
connection_type_ = type;
NotifyObserversOfNetworkChange(type);
base::RunLoop().RunUntilIdle();
}
virtual ~FakeNetworkChangeNotifier() {}
private:
ConnectionType connection_type_;
DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifier);
};
// A waiter that blocks until the expected oobe screen is reached.
class OobeScreenWaiter : public OobeUI::Observer {
public:
explicit OobeScreenWaiter(OobeDisplay::Screen expected_screen)
: waiting_for_screen_(false),
expected_screen_(expected_screen) {
}
virtual ~OobeScreenWaiter() {
if (waiting_for_screen_) {
GetOobeUI()->RemoveObserver(this);
}
}
void Wait() {
if (GetOobeUI()->current_screen() == expected_screen_) {
return;
}
waiting_for_screen_ = true;
GetOobeUI()->AddObserver(this);
runner_ = new content::MessageLoopRunner;
runner_->Run();
ASSERT_EQ(expected_screen_, GetOobeUI()->current_screen());
ASSERT_FALSE(waiting_for_screen_);
}
// OobeUI::Observer implementation:
virtual void OnCurrentScreenChanged(
OobeDisplay::Screen current_screen,
OobeDisplay::Screen new_screen) OVERRIDE {
if (waiting_for_screen_ && new_screen == expected_screen_) {
runner_->Quit();
waiting_for_screen_ = false;
GetOobeUI()->RemoveObserver(this);
}
}
OobeUI* GetOobeUI() {
OobeUI* oobe_ui = static_cast<chromeos::LoginDisplayHostImpl*>(
chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI();
CHECK(oobe_ui);
return oobe_ui;
}
private:
bool waiting_for_screen_;
OobeDisplay::Screen expected_screen_;
scoped_refptr<content::MessageLoopRunner> runner_;
};
class KioskTest : public InProcessBrowserTest, class KioskTest : public InProcessBrowserTest,
// Param defining is multi-profiles enabled. // Param defining is multi-profiles enabled.
public testing::WithParamInterface<bool> { public testing::WithParamInterface<bool> {
...@@ -105,9 +203,20 @@ class KioskTest : public InProcessBrowserTest, ...@@ -105,9 +203,20 @@ class KioskTest : public InProcessBrowserTest,
const GURL gaia_url("http://localhost:" + test_server_->base_url().port()); const GURL gaia_url("http://localhost:" + test_server_->base_url().port());
CommandLine::ForCurrentProcess()->AppendSwitchASCII( CommandLine::ForCurrentProcess()->AppendSwitchASCII(
::switches::kGaiaUrl, gaia_url.spec()); ::switches::kGaiaUrl, gaia_url.spec());
mock_user_manager_.reset(new MockUserManager);
AppLaunchController::SkipSplashWaitForTesting();
AppLaunchController::SetNetworkWaitForTesting(kTestNetworkTimeoutSeconds);
} }
virtual void CleanUpOnMainThread() OVERRIDE { virtual void CleanUpOnMainThread() OVERRIDE {
// We need to clean up these objects in this specific order.
fake_network_notifier_.reset(NULL);
disable_network_notifier_.reset(NULL);
AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
AppLaunchController::SetUserManagerForTesting(NULL);
// If the login display is still showing, exit gracefully. // If the login display is still showing, exit gracefully.
if (LoginDisplayHostImpl::default_host()) { if (LoginDisplayHostImpl::default_host()) {
base::MessageLoop::current()->PostTask(FROM_HERE, base::MessageLoop::current()->PostTask(FROM_HERE,
...@@ -196,6 +305,87 @@ class KioskTest : public InProcessBrowserTest, ...@@ -196,6 +305,87 @@ class KioskTest : public InProcessBrowserTest,
KioskAppManager::Get()->SetAutoLaunchApp(kTestKioskApp); KioskAppManager::Get()->SetAutoLaunchApp(kTestKioskApp);
} }
void StartAppLaunchFromLoginScreen(bool has_connectivity) {
EnableConsumerKioskMode();
// Start UI, find menu entry for this app and launch it.
content::WindowedNotificationObserver login_signal(
chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
content::NotificationService::AllSources());
chromeos::WizardController::SkipPostLoginScreensForTesting();
chromeos::WizardController* wizard_controller =
chromeos::WizardController::default_controller();
CHECK(wizard_controller);
wizard_controller->SkipToLoginForTesting();
login_signal.Wait();
// Wait for the Kiosk App configuration to reload, then launch the app.
content::WindowedNotificationObserver apps_loaded_signal(
chrome::NOTIFICATION_KIOSK_APPS_LOADED,
content::NotificationService::AllSources());
ReloadKioskApps();
apps_loaded_signal.Wait();
if (!has_connectivity)
SimulateNetworkOffline();
GetLoginUI()->CallJavascriptFunction(
"login.AppsMenuButton.runAppForTesting",
base::StringValue(kTestKioskApp));
}
void WaitForAppLaunchSuccess() {
SimulateNetworkOnline();
// Wait for the Kiosk App to launch.
content::WindowedNotificationObserver(
chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
content::NotificationService::AllSources()).Wait();
// Check installer status.
EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
chromeos::KioskAppLaunchError::Get());
// Check if the kiosk webapp is really installed for the default profile.
ASSERT_TRUE(ProfileManager::GetDefaultProfile());
const extensions::Extension* app =
extensions::ExtensionSystem::Get(ProfileManager::GetDefaultProfile())->
extension_service()->GetInstalledExtension(kTestKioskApp);
EXPECT_TRUE(app);
// Wait until the app terminates.
content::RunMessageLoop();
}
void SimulateNetworkOffline() {
disable_network_notifier_.reset(
new net::NetworkChangeNotifier::DisableForTest);
fake_network_notifier_.reset(new FakeNetworkChangeNotifier);
}
void SimulateNetworkOnline() {
if (fake_network_notifier_.get())
fake_network_notifier_->GoOnline();
}
void WaitForAppLaunchNetworkTimeout() {
if (GetAppLaunchController()->network_wait_timedout())
return;
scoped_refptr<content::MessageLoopRunner> runner =
new content::MessageLoopRunner;
base::Closure callback = base::Bind(
&OnNetworkWaitTimedOut, runner->QuitClosure());
AppLaunchController::SetNetworkTimeoutCallbackForTesting(&callback);
runner->Run();
CHECK(GetAppLaunchController()->network_wait_timedout());
AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
}
void EnableConsumerKioskMode() { void EnableConsumerKioskMode() {
scoped_ptr<bool> locked(new bool(false)); scoped_ptr<bool> locked(new bool(false));
scoped_refptr<content::MessageLoopRunner> runner = scoped_refptr<content::MessageLoopRunner> runner =
...@@ -227,47 +417,72 @@ class KioskTest : public InProcessBrowserTest, ...@@ -227,47 +417,72 @@ class KioskTest : public InProcessBrowserTest,
chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui(); chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui();
} }
AppLaunchController* GetAppLaunchController() {
return chromeos::LoginDisplayHostImpl::default_host()
->GetAppLaunchController();
}
std::string service_login_response_; std::string service_login_response_;
scoped_ptr<EmbeddedTestServer> test_server_; scoped_ptr<EmbeddedTestServer> test_server_;
scoped_ptr<net::NetworkChangeNotifier::DisableForTest>
disable_network_notifier_;
scoped_ptr<FakeNetworkChangeNotifier> fake_network_notifier_;
scoped_ptr<MockUserManager> mock_user_manager_;
}; };
IN_PROC_BROWSER_TEST_P(KioskTest, InstallAndLaunchApp) { IN_PROC_BROWSER_TEST_P(KioskTest, InstallAndLaunchApp) {
EnableConsumerKioskMode(); StartAppLaunchFromLoginScreen(true);
chromeos::AppLaunchController::SkipSplashWaitForTesting(); WaitForAppLaunchSuccess();
// Start UI, find menu entry for this app and launch it. }
chromeos::WizardController::SkipPostLoginScreensForTesting();
chromeos::WizardController* wizard_controller =
chromeos::WizardController::default_controller();
CHECK(wizard_controller);
wizard_controller->SkipToLoginForTesting();
ReloadKioskApps();
// Wait for the Kiosk App configuration to reload, then launch the app.
content::WindowedNotificationObserver(
chrome::NOTIFICATION_KIOSK_APPS_LOADED,
content::NotificationService::AllSources()).Wait();
GetLoginUI()->CallJavascriptFunction("login.AppsMenuButton.runAppForTesting",
base::StringValue(kTestKioskApp));
// Wait for the Kiosk App to launch. IN_PROC_BROWSER_TEST_P(KioskTest, LaunchAppNetworkDown) {
content::WindowedNotificationObserver( // Start app launch and wait for network connectivity timeout.
chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, StartAppLaunchFromLoginScreen(false);
content::NotificationService::AllSources()).Wait(); OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
splash_waiter.Wait();
WaitForAppLaunchNetworkTimeout();
// Set up fake user manager with an owner for the test.
mock_user_manager_->SetActiveUser(kTestOwnerEmail);
AppLaunchController::SetUserManagerForTesting(mock_user_manager_.get());
static_cast<LoginDisplayHostImpl*>(LoginDisplayHostImpl::default_host())
->GetOobeUI()->ShowOobeUI(false);
// Configure network should bring up lock screen for owner.
OobeScreenWaiter lock_screen_waiter(OobeDisplay::SCREEN_ACCOUNT_PICKER);
static_cast<AppLaunchSplashScreenActor::Delegate*>(GetAppLaunchController())
->OnConfigureNetwork();
lock_screen_waiter.Wait();
// A network error screen should be shown after authenticating.
content::WindowedNotificationObserver network_error_signal(
chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN,
content::NotificationService::AllSources());
static_cast<AppLaunchSigninScreen::Delegate*>(GetAppLaunchController())
->OnOwnerSigninSuccess();
network_error_signal.Wait();
ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog());
WaitForAppLaunchSuccess();
}
// Check installer status. IN_PROC_BROWSER_TEST_P(KioskTest, LaunchAppUserCancel) {
EXPECT_EQ(chromeos::KioskAppLaunchError::NONE, StartAppLaunchFromLoginScreen(false);
OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
splash_waiter.Wait();
CrosSettings::Get()->SetBoolean(
kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, true);
LOG(ERROR) << "BAILOUT!";
content::WindowedNotificationObserver signal(
chrome::NOTIFICATION_APP_TERMINATING,
content::NotificationService::AllSources());
GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
base::StringValue("app_launch_bailout"));
signal.Wait();
EXPECT_EQ(chromeos::KioskAppLaunchError::USER_CANCEL,
chromeos::KioskAppLaunchError::Get()); chromeos::KioskAppLaunchError::Get());
// Check if the kiosk webapp is really installed for the default profile.
ASSERT_TRUE(ProfileManager::GetDefaultProfile());
const extensions::Extension* app =
extensions::ExtensionSystem::Get(ProfileManager::GetDefaultProfile())->
extension_service()->GetInstalledExtension(kTestKioskApp);
EXPECT_TRUE(app);
// Wait until the app terminates.
content::RunMessageLoop();
} }
IN_PROC_BROWSER_TEST_P(KioskTest, AutolaunchWarningCancel) { IN_PROC_BROWSER_TEST_P(KioskTest, AutolaunchWarningCancel) {
......
...@@ -20,6 +20,7 @@ class Widget; ...@@ -20,6 +20,7 @@ class Widget;
namespace chromeos { namespace chromeos {
class AppLaunchController;
class WebUILoginView; class WebUILoginView;
class WizardController; class WizardController;
...@@ -82,6 +83,10 @@ class LoginDisplayHost { ...@@ -82,6 +83,10 @@ class LoginDisplayHost {
// Result should not be stored. // Result should not be stored.
virtual WizardController* GetWizardController() = 0; virtual WizardController* GetWizardController() = 0;
// Returns current AppLaunchController, if it exists.
// Result should not be stored.
virtual AppLaunchController* GetAppLaunchController() = 0;
// Starts screen for adding user into session. // Starts screen for adding user into session.
// |completion_callback| called before display host shutdown. // |completion_callback| called before display host shutdown.
// |completion_callback| can be null. // |completion_callback| can be null.
......
...@@ -410,6 +410,10 @@ WizardController* LoginDisplayHostImpl::GetWizardController() { ...@@ -410,6 +410,10 @@ WizardController* LoginDisplayHostImpl::GetWizardController() {
return wizard_controller_.get(); return wizard_controller_.get();
} }
AppLaunchController* LoginDisplayHostImpl::GetAppLaunchController() {
return app_launch_controller_.get();
}
void LoginDisplayHostImpl::StartUserAdding( void LoginDisplayHostImpl::StartUserAdding(
const base::Closure& completion_callback) { const base::Closure& completion_callback) {
restore_path_ = RESTORE_ADD_USER_INTO_SESSION; restore_path_ = RESTORE_ADD_USER_INTO_SESSION;
......
...@@ -67,6 +67,7 @@ class LoginDisplayHostImpl : public LoginDisplayHost, ...@@ -67,6 +67,7 @@ class LoginDisplayHostImpl : public LoginDisplayHost,
const std::string& first_screen_name, const std::string& first_screen_name,
scoped_ptr<DictionaryValue> screen_parameters) OVERRIDE; scoped_ptr<DictionaryValue> screen_parameters) OVERRIDE;
virtual WizardController* GetWizardController() OVERRIDE; virtual WizardController* GetWizardController() OVERRIDE;
virtual AppLaunchController* GetAppLaunchController() OVERRIDE;
virtual void StartUserAdding( virtual void StartUserAdding(
const base::Closure& completion_callback) OVERRIDE; const base::Closure& completion_callback) OVERRIDE;
virtual void StartSignInScreen() OVERRIDE; virtual void StartSignInScreen() OVERRIDE;
......
...@@ -37,6 +37,7 @@ class MockLoginDisplayHost : public LoginDisplayHost { ...@@ -37,6 +37,7 @@ class MockLoginDisplayHost : public LoginDisplayHost {
virtual void StartWizard(const std::string& name, virtual void StartWizard(const std::string& name,
scoped_ptr<base::DictionaryValue> value) OVERRIDE; scoped_ptr<base::DictionaryValue> value) OVERRIDE;
MOCK_METHOD0(GetWizardController, WizardController*(void)); MOCK_METHOD0(GetWizardController, WizardController*(void));
MOCK_METHOD0(GetAppLaunchController, AppLaunchController*(void));
MOCK_METHOD1(StartUserAdding, void(const base::Closure&)); MOCK_METHOD1(StartUserAdding, void(const base::Closure&));
MOCK_METHOD0(StartSignInScreen, void(void)); MOCK_METHOD0(StartSignInScreen, void(void));
MOCK_METHOD0(ResumeSignInScreen, void(void)); MOCK_METHOD0(ResumeSignInScreen, void(void));
......
...@@ -13,6 +13,10 @@ MockUserManager::~MockUserManager() { ...@@ -13,6 +13,10 @@ MockUserManager::~MockUserManager() {
delete user_; delete user_;
} }
const UserList& MockUserManager::GetUsers() const {
return user_list_;
}
const User* MockUserManager::GetLoggedInUser() const { const User* MockUserManager::GetLoggedInUser() const {
return user_; return user_;
} }
...@@ -21,6 +25,10 @@ User* MockUserManager::GetLoggedInUser() { ...@@ -21,6 +25,10 @@ User* MockUserManager::GetLoggedInUser() {
return user_; return user_;
} }
const std::string& MockUserManager::GetOwnerEmail() {
return user_->email();
}
const User* MockUserManager::GetActiveUser() const { const User* MockUserManager::GetActiveUser() const {
return user_; return user_;
} }
...@@ -37,6 +45,8 @@ UserImageManager* MockUserManager::GetUserImageManager() { ...@@ -37,6 +45,8 @@ UserImageManager* MockUserManager::GetUserImageManager() {
void MockUserManager::SetActiveUser(const std::string& email) { void MockUserManager::SetActiveUser(const std::string& email) {
delete user_; delete user_;
user_ = User::CreateRegularUser(email); user_ = User::CreateRegularUser(email);
user_list_.clear();
user_list_.push_back(user_);
} }
UserFlow* MockUserManager::GetCurrentUserFlow() const { UserFlow* MockUserManager::GetCurrentUserFlow() const {
...@@ -50,6 +60,8 @@ UserFlow* MockUserManager::GetUserFlow(const std::string&) const { ...@@ -50,6 +60,8 @@ UserFlow* MockUserManager::GetUserFlow(const std::string&) const {
User* MockUserManager::CreatePublicAccountUser(const std::string& email) { User* MockUserManager::CreatePublicAccountUser(const std::string& email) {
delete user_; delete user_;
user_ = User::CreatePublicAccountUser(email); user_ = User::CreatePublicAccountUser(email);
user_list_.clear();
user_list_.push_back(user_);
return user_; return user_;
} }
......
...@@ -24,11 +24,9 @@ class MockUserManager : public UserManager { ...@@ -24,11 +24,9 @@ class MockUserManager : public UserManager {
virtual ~MockUserManager(); virtual ~MockUserManager();
MOCK_METHOD0(Shutdown, void(void)); MOCK_METHOD0(Shutdown, void(void));
MOCK_CONST_METHOD0(GetUsers, const UserList&(void));
MOCK_CONST_METHOD0(GetUsersAdmittedForMultiProfile, UserList(void)); MOCK_CONST_METHOD0(GetUsersAdmittedForMultiProfile, UserList(void));
MOCK_CONST_METHOD0(GetLoggedInUsers, const UserList&(void)); MOCK_CONST_METHOD0(GetLoggedInUsers, const UserList&(void));
MOCK_METHOD0(GetLRULoggedInUsers, const UserList&(void)); MOCK_METHOD0(GetLRULoggedInUsers, const UserList&(void));
MOCK_METHOD0(GetOwnerEmail, const std::string&(void));
MOCK_METHOD3(UserLoggedIn, void( MOCK_METHOD3(UserLoggedIn, void(
const std::string&, const std::string&, bool)); const std::string&, const std::string&, bool));
MOCK_METHOD1(SwitchActiveUser, void(const std::string& email)); MOCK_METHOD1(SwitchActiveUser, void(const std::string& email));
...@@ -103,7 +101,9 @@ class MockUserManager : public UserManager { ...@@ -103,7 +101,9 @@ class MockUserManager : public UserManager {
// You can't mock these functions easily because nobody can create // You can't mock these functions easily because nobody can create
// User objects but the UserManagerImpl and us. // User objects but the UserManagerImpl and us.
virtual const UserList& GetUsers() const OVERRIDE;
virtual const User* GetLoggedInUser() const OVERRIDE; virtual const User* GetLoggedInUser() const OVERRIDE;
virtual const std::string& GetOwnerEmail() OVERRIDE;
virtual User* GetLoggedInUser() OVERRIDE; virtual User* GetLoggedInUser() OVERRIDE;
virtual const User* GetActiveUser() const OVERRIDE; virtual const User* GetActiveUser() const OVERRIDE;
virtual User* GetActiveUser() OVERRIDE; virtual User* GetActiveUser() OVERRIDE;
...@@ -123,6 +123,7 @@ class MockUserManager : public UserManager { ...@@ -123,6 +123,7 @@ class MockUserManager : public UserManager {
User* user_; User* user_;
scoped_ptr<MockUserImageManager> user_image_manager_; scoped_ptr<MockUserImageManager> user_image_manager_;
scoped_ptr<UserFlow> user_flow_; scoped_ptr<UserFlow> user_flow_;
UserList user_list_;
}; };
} // namespace chromeos } // namespace chromeos
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/memory/ref_counted_memory.h" #include "base/memory/ref_counted_memory.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/browser_about_handler.h" #include "chrome/browser/browser_about_handler.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
#include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h" #include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h"
#include "chrome/browser/chromeos/login/login_display_host_impl.h" #include "chrome/browser/chromeos/login/login_display_host_impl.h"
...@@ -459,6 +460,15 @@ void OobeUI::ResetSigninScreenHandlerDelegate() { ...@@ -459,6 +460,15 @@ void OobeUI::ResetSigninScreenHandlerDelegate() {
signin_screen_handler_->SetNativeWindowDelegate(NULL); signin_screen_handler_->SetNativeWindowDelegate(NULL);
} }
void OobeUI::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void OobeUI::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
const std::string& OobeUI::GetScreenName(Screen screen) const { const std::string& OobeUI::GetScreenName(Screen screen) const {
DCHECK(screen >= 0 && screen < SCREEN_UNKNOWN); DCHECK(screen >= 0 && screen < SCREEN_UNKNOWN);
return screen_names_[static_cast<size_t>(screen)]; return screen_names_[static_cast<size_t>(screen)];
...@@ -466,7 +476,11 @@ const std::string& OobeUI::GetScreenName(Screen screen) const { ...@@ -466,7 +476,11 @@ const std::string& OobeUI::GetScreenName(Screen screen) const {
void OobeUI::OnCurrentScreenChanged(const std::string& screen) { void OobeUI::OnCurrentScreenChanged(const std::string& screen) {
if (screen_ids_.count(screen)) { if (screen_ids_.count(screen)) {
current_screen_ = screen_ids_[screen]; Screen new_screen = screen_ids_[screen];
FOR_EACH_OBSERVER(Observer,
observer_list_,
OnCurrentScreenChanged(current_screen_, new_screen));
current_screen_ = new_screen;
} else { } else {
NOTREACHED() << "Screen should be registered in InitializeScreenMaps()"; NOTREACHED() << "Screen should be registered in InitializeScreenMaps()";
current_screen_ = SCREEN_UNKNOWN; current_screen_ = SCREEN_UNKNOWN;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "chrome/browser/chromeos/login/oobe_display.h" #include "chrome/browser/chromeos/login/oobe_display.h"
#include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h" #include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h"
#include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_controller.h"
...@@ -41,6 +42,13 @@ class OobeUI : public OobeDisplay, ...@@ -41,6 +42,13 @@ class OobeUI : public OobeDisplay,
public content::WebUIController, public content::WebUIController,
public CoreOobeHandler::Delegate { public CoreOobeHandler::Delegate {
public: public:
class Observer {
public:
virtual ~Observer() {}
virtual void OnCurrentScreenChanged(
Screen current_screen, Screen new_screen) = 0;
};
// JS oobe/login screens names. // JS oobe/login screens names.
static const char kScreenOobeNetwork[]; static const char kScreenOobeNetwork[];
static const char kScreenOobeEula[]; static const char kScreenOobeEula[];
...@@ -108,6 +116,10 @@ class OobeUI : public OobeDisplay, ...@@ -108,6 +116,10 @@ class OobeUI : public OobeDisplay,
// Resets the delegate set in ShowSigninScreen. // Resets the delegate set in ShowSigninScreen.
void ResetSigninScreenHandlerDelegate(); void ResetSigninScreenHandlerDelegate();
// Add and remove observers for screen change events.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
Screen current_screen() const { return current_screen_; } Screen current_screen() const { return current_screen_; }
const std::string& GetScreenName(Screen screen) const; const std::string& GetScreenName(Screen screen) const;
...@@ -179,6 +191,9 @@ class OobeUI : public OobeDisplay, ...@@ -179,6 +191,9 @@ class OobeUI : public OobeDisplay,
// Callbacks to notify when JS part is fully loaded and ready to accept calls. // Callbacks to notify when JS part is fully loaded and ready to accept calls.
std::vector<base::Closure> ready_callbacks_; std::vector<base::Closure> ready_callbacks_;
// List of registered observers.
ObserverList<Observer> observer_list_;
DISALLOW_COPY_AND_ASSIGN(OobeUI); DISALLOW_COPY_AND_ASSIGN(OobeUI);
}; };
......
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