<commit_before>// Copyright (c) 2011 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 "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/chromeos/login/base_login_display_host.h"
#include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_screen.h"
#include "chrome/browser/chromeos/login/enrollment/mock_enterprise_enrollment_screen.h"
#include "chrome/browser/chromeos/login/existing_user_controller.h"
#include "chrome/browser/chromeos/login/language_switch_menu.h"
#include "chrome/browser/chromeos/login/mock_authenticator.h"
#include "chrome/browser/chromeos/login/mock_eula_screen.h"
#include "chrome/browser/chromeos/login/mock_login_status_consumer.h"
#include "chrome/browser/chromeos/login/mock_network_screen.h"
#include "chrome/browser/chromeos/login/mock_update_screen.h"
#include "chrome/browser/chromeos/login/network_screen.h"
#include "chrome/browser/chromeos/login/user_image_screen.h"
#include "chrome/browser/chromeos/login/view_screen.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "grit/generated_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
#include "unicode/locid.h"

namespace chromeos {

namespace {
const char kUsername[] = "test_user@managedchrome.com";
const char kPassword[] = "test_password";
}  // namespace

using ::testing::_;

template <class T, class H>
class MockOutShowHide : public T {
 public:
  template <class P> explicit  MockOutShowHide(P p) : T(p) {}
  template <class P> MockOutShowHide(P p, H* actor)
      : T(p, actor), actor_(actor) {}
  MOCK_METHOD0(Show, void());
  MOCK_METHOD0(Hide, void());

 private:
  scoped_ptr<H> actor_;
};

#define MOCK(mock_var, screen_name, mocked_class, actor_class)                 \
  mock_var = new MockOutShowHide<mocked_class, actor_class>(                   \
      controller(), new actor_class);                                          \
  controller()->screen_name.reset(mock_var);                                   \
  EXPECT_CALL(*mock_var, Show()).Times(0);                                     \
  EXPECT_CALL(*mock_var, Hide()).Times(0);

class WizardControllerTest : public WizardInProcessBrowserTest {
 protected:
  WizardControllerTest() : WizardInProcessBrowserTest(
      WizardController::kTestNoScreenName) {}
  virtual ~WizardControllerTest() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(WizardControllerTest);
};

IN_PROC_BROWSER_TEST_F(WizardControllerTest, SwitchLanguage) {
  ASSERT_TRUE(controller() != NULL);
  controller()->ShowFirstScreen(WizardController::kNetworkScreenName);

  // Checking the default locale. Provided that the profile is cleared in SetUp.
  EXPECT_EQ("en-US", g_browser_process->GetApplicationLocale());
  EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage());
  EXPECT_FALSE(base::i18n::IsRTL());
  const std::wstring en_str =
      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));

  LanguageSwitchMenu::SwitchLanguage("fr");
  EXPECT_EQ("fr", g_browser_process->GetApplicationLocale());
  EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage());
  EXPECT_FALSE(base::i18n::IsRTL());
  const std::wstring fr_str =
      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));

  EXPECT_NE(en_str, fr_str);

  LanguageSwitchMenu::SwitchLanguage("ar");
  EXPECT_EQ("ar", g_browser_process->GetApplicationLocale());
  EXPECT_STREQ("ar", icu::Locale::getDefault().getLanguage());
  EXPECT_TRUE(base::i18n::IsRTL());
  const std::wstring ar_str =
      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));

  EXPECT_NE(fr_str, ar_str);
}

class WizardControllerFlowTest : public WizardControllerTest {
 protected:
  WizardControllerFlowTest() {}
  // Overriden from InProcessBrowserTest:
  virtual Browser* CreateBrowser(Profile* profile) {
    Browser* ret = WizardControllerTest::CreateBrowser(profile);

    // Make sure that OOBE is run as an "official" build.
    WizardController::default_controller()->is_official_build_ = true;

    // Set up the mocks for all screens.
    MOCK(mock_network_screen_, network_screen_,
         MockNetworkScreen, MockNetworkScreenActor);
    MOCK(mock_update_screen_, update_screen_,
         MockUpdateScreen, MockUpdateScreenActor);
    MOCK(mock_eula_screen_, eula_screen_, MockEulaScreen, MockEulaScreenActor);
    MOCK(mock_enterprise_enrollment_screen_, enterprise_enrollment_screen_,
         MockEnterpriseEnrollmentScreen, MockEnterpriseEnrollmentScreenActor);

    // Switch to the initial screen.
    EXPECT_EQ(NULL, controller()->current_screen());
    EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
    controller()->ShowFirstScreen(WizardController::kNetworkScreenName);

    return ret;
  }

  void OnExit(ScreenObserver::ExitCodes exit_code) {
    controller()->OnExit(exit_code);
  }

  MockOutShowHide<MockNetworkScreen, MockNetworkScreenActor>*
      mock_network_screen_;
  MockOutShowHide<MockUpdateScreen, MockUpdateScreenActor>* mock_update_screen_;
  MockOutShowHide<MockEulaScreen, MockEulaScreenActor>* mock_eula_screen_;
  MockOutShowHide<MockEnterpriseEnrollmentScreen,
    MockEnterpriseEnrollmentScreenActor>* mock_enterprise_enrollment_screen_;

 private:
  DISALLOW_COPY_AND_ASSIGN(WizardControllerFlowTest);
};

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowMain) {
  EXPECT_TRUE(ExistingUserController::current_controller() == NULL);
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
  OnExit(ScreenObserver::NETWORK_CONNECTED);

  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1);
  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
  OnExit(ScreenObserver::EULA_ACCEPTED);
  // Let update screen smooth time process (time = 0ms).
  ui_test_utils::RunAllPendingInMessageLoop();

  EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, Hide()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
  OnExit(ScreenObserver::UPDATE_INSTALLED);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorUpdate) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_update_screen_, Show()).Times(0);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
  OnExit(ScreenObserver::NETWORK_CONNECTED);

  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1);
  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
  OnExit(ScreenObserver::EULA_ACCEPTED);
  // Let update screen smooth time process (time = 0ms).
  ui_test_utils::RunAllPendingInMessageLoop();

  EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, Hide()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(0);  // last transition
  OnExit(ScreenObserver::UPDATE_ERROR_UPDATING);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEulaDeclined) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
  OnExit(ScreenObserver::NETWORK_CONNECTED);

  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(0);  // last transition
  OnExit(ScreenObserver::EULA_BACK);

  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
}

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorNetwork) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  OnExit(ScreenObserver::NETWORK_OFFLINE);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

#if !defined(GOOGLE_CHROME_BUILD)
// TODO(mnissler): These tests are not yet enabled for official builds. Remove
// the guards once we enable the enrollment feature for official builds.

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest,
                       ControlFlowEnterpriseEnrollmentCompleted) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
  EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);

  controller()->ShowEnterpriseEnrollmentScreen();
  EnterpriseEnrollmentScreen* screen =
      controller()->GetEnterpriseEnrollmentScreen();
  EXPECT_EQ(screen, controller()->current_screen());
  std::string user;
  EXPECT_FALSE(screen->IsAutoEnrollment(&user));
  OnExit(ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest,
                       ControlFlowEnterpriseAutoEnrollmentCompleted) {
  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kLoginScreen,
      WizardController::kLoginScreenName);

  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);

  LoginUtils::Set(new MockLoginUtils(kUsername, kPassword));
  MockConsumer mock_consumer;

  // Must have a pending signin to resume after auto-enrollment:
  BaseLoginDisplayHost::default_host()->StartSignInScreen();
  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  ExistingUserController::current_controller()->DoAutoEnrollment();
  ExistingUserController::current_controller()->set_login_status_consumer(
      &mock_consumer);
  // This calls StartWizard, destroying the current controller() and its mocks;
  // don't set expectations on those objects.
  ExistingUserController::current_controller()->CompleteLogin(kUsername,
                                                              kPassword);
  EnterpriseEnrollmentScreen* screen =
      controller()->GetEnterpriseEnrollmentScreen();
  EXPECT_EQ(screen, controller()->current_screen());
  std::string user;
  EXPECT_TRUE(screen->IsAutoEnrollment(&user));
  // This is the main expectation: after auto-enrollment, login is resumed.
  EXPECT_CALL(mock_consumer, OnLoginSuccess(_, _, _, _, _)).Times(1);
  OnExit(ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
  // Prevent browser launch when the profile is prepared:
  browser_shutdown::SetTryingToQuit(true);
  // Run the tasks posted to complete the login:
  MessageLoop::current()->RunAllPending();
  set_controller(NULL);
}
#endif

// TODO(nkostylev): Add test for WebUI accelerators http://crosbug.com/22571

COMPILE_ASSERT(ScreenObserver::EXIT_CODES_COUNT == 15,
               add_tests_for_new_control_flow_you_just_introduced);

}  // namespace chromeos
<commit_msg>[cros] Mark WizardControllerFlowTest.{ControlFlowMain|ControlFlowErrorUpdate} as flaky.<commit_after>// Copyright (c) 2012 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 "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/chromeos/login/base_login_display_host.h"
#include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_screen.h"
#include "chrome/browser/chromeos/login/enrollment/mock_enterprise_enrollment_screen.h"
#include "chrome/browser/chromeos/login/existing_user_controller.h"
#include "chrome/browser/chromeos/login/language_switch_menu.h"
#include "chrome/browser/chromeos/login/mock_authenticator.h"
#include "chrome/browser/chromeos/login/mock_eula_screen.h"
#include "chrome/browser/chromeos/login/mock_login_status_consumer.h"
#include "chrome/browser/chromeos/login/mock_network_screen.h"
#include "chrome/browser/chromeos/login/mock_update_screen.h"
#include "chrome/browser/chromeos/login/network_screen.h"
#include "chrome/browser/chromeos/login/user_image_screen.h"
#include "chrome/browser/chromeos/login/view_screen.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "grit/generated_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
#include "unicode/locid.h"

namespace chromeos {

namespace {
const char kUsername[] = "test_user@managedchrome.com";
const char kPassword[] = "test_password";
}  // namespace

using ::testing::_;

template <class T, class H>
class MockOutShowHide : public T {
 public:
  template <class P> explicit  MockOutShowHide(P p) : T(p) {}
  template <class P> MockOutShowHide(P p, H* actor)
      : T(p, actor), actor_(actor) {}
  MOCK_METHOD0(Show, void());
  MOCK_METHOD0(Hide, void());

 private:
  scoped_ptr<H> actor_;
};

#define MOCK(mock_var, screen_name, mocked_class, actor_class)                 \
  mock_var = new MockOutShowHide<mocked_class, actor_class>(                   \
      controller(), new actor_class);                                          \
  controller()->screen_name.reset(mock_var);                                   \
  EXPECT_CALL(*mock_var, Show()).Times(0);                                     \
  EXPECT_CALL(*mock_var, Hide()).Times(0);

class WizardControllerTest : public WizardInProcessBrowserTest {
 protected:
  WizardControllerTest() : WizardInProcessBrowserTest(
      WizardController::kTestNoScreenName) {}
  virtual ~WizardControllerTest() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(WizardControllerTest);
};

IN_PROC_BROWSER_TEST_F(WizardControllerTest, SwitchLanguage) {
  ASSERT_TRUE(controller() != NULL);
  controller()->ShowFirstScreen(WizardController::kNetworkScreenName);

  // Checking the default locale. Provided that the profile is cleared in SetUp.
  EXPECT_EQ("en-US", g_browser_process->GetApplicationLocale());
  EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage());
  EXPECT_FALSE(base::i18n::IsRTL());
  const std::wstring en_str =
      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));

  LanguageSwitchMenu::SwitchLanguage("fr");
  EXPECT_EQ("fr", g_browser_process->GetApplicationLocale());
  EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage());
  EXPECT_FALSE(base::i18n::IsRTL());
  const std::wstring fr_str =
      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));

  EXPECT_NE(en_str, fr_str);

  LanguageSwitchMenu::SwitchLanguage("ar");
  EXPECT_EQ("ar", g_browser_process->GetApplicationLocale());
  EXPECT_STREQ("ar", icu::Locale::getDefault().getLanguage());
  EXPECT_TRUE(base::i18n::IsRTL());
  const std::wstring ar_str =
      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));

  EXPECT_NE(fr_str, ar_str);
}

class WizardControllerFlowTest : public WizardControllerTest {
 protected:
  WizardControllerFlowTest() {}
  // Overriden from InProcessBrowserTest:
  virtual Browser* CreateBrowser(Profile* profile) {
    Browser* ret = WizardControllerTest::CreateBrowser(profile);

    // Make sure that OOBE is run as an "official" build.
    WizardController::default_controller()->is_official_build_ = true;

    // Set up the mocks for all screens.
    MOCK(mock_network_screen_, network_screen_,
         MockNetworkScreen, MockNetworkScreenActor);
    MOCK(mock_update_screen_, update_screen_,
         MockUpdateScreen, MockUpdateScreenActor);
    MOCK(mock_eula_screen_, eula_screen_, MockEulaScreen, MockEulaScreenActor);
    MOCK(mock_enterprise_enrollment_screen_, enterprise_enrollment_screen_,
         MockEnterpriseEnrollmentScreen, MockEnterpriseEnrollmentScreenActor);

    // Switch to the initial screen.
    EXPECT_EQ(NULL, controller()->current_screen());
    EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
    controller()->ShowFirstScreen(WizardController::kNetworkScreenName);

    return ret;
  }

  void OnExit(ScreenObserver::ExitCodes exit_code) {
    controller()->OnExit(exit_code);
  }

  MockOutShowHide<MockNetworkScreen, MockNetworkScreenActor>*
      mock_network_screen_;
  MockOutShowHide<MockUpdateScreen, MockUpdateScreenActor>* mock_update_screen_;
  MockOutShowHide<MockEulaScreen, MockEulaScreenActor>* mock_eula_screen_;
  MockOutShowHide<MockEnterpriseEnrollmentScreen,
    MockEnterpriseEnrollmentScreenActor>* mock_enterprise_enrollment_screen_;

 private:
  DISALLOW_COPY_AND_ASSIGN(WizardControllerFlowTest);
};

// Seems to be flaky http://crbug.com/110544.
IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, DISABLED_ControlFlowMain) {
  EXPECT_TRUE(ExistingUserController::current_controller() == NULL);
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
  OnExit(ScreenObserver::NETWORK_CONNECTED);

  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1);
  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
  OnExit(ScreenObserver::EULA_ACCEPTED);
  // Let update screen smooth time process (time = 0ms).
  ui_test_utils::RunAllPendingInMessageLoop();

  EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, Hide()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
  OnExit(ScreenObserver::UPDATE_INSTALLED);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

// Seems to be flaky http://crbug.com/110544.
IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest,
                       DISABLED_ControlFlowErrorUpdate) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_update_screen_, Show()).Times(0);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
  OnExit(ScreenObserver::NETWORK_CONNECTED);

  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1);
  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
  OnExit(ScreenObserver::EULA_ACCEPTED);
  // Let update screen smooth time process (time = 0ms).
  ui_test_utils::RunAllPendingInMessageLoop();

  EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, Hide()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(0);  // last transition
  OnExit(ScreenObserver::UPDATE_ERROR_UPDATING);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEulaDeclined) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
  OnExit(ScreenObserver::NETWORK_CONNECTED);

  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(0);  // last transition
  OnExit(ScreenObserver::EULA_BACK);

  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
}

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorNetwork) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  OnExit(ScreenObserver::NETWORK_OFFLINE);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

#if !defined(GOOGLE_CHROME_BUILD)
// TODO(mnissler): These tests are not yet enabled for official builds. Remove
// the guards once we enable the enrollment feature for official builds.

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest,
                       ControlFlowEnterpriseEnrollmentCompleted) {
  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
  EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1);
  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);

  controller()->ShowEnterpriseEnrollmentScreen();
  EnterpriseEnrollmentScreen* screen =
      controller()->GetEnterpriseEnrollmentScreen();
  EXPECT_EQ(screen, controller()->current_screen());
  std::string user;
  EXPECT_FALSE(screen->IsAutoEnrollment(&user));
  OnExit(ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED);

  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  set_controller(NULL);
}

IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest,
                       ControlFlowEnterpriseAutoEnrollmentCompleted) {
  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kLoginScreen,
      WizardController::kLoginScreenName);

  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);

  LoginUtils::Set(new MockLoginUtils(kUsername, kPassword));
  MockConsumer mock_consumer;

  // Must have a pending signin to resume after auto-enrollment:
  BaseLoginDisplayHost::default_host()->StartSignInScreen();
  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
  ExistingUserController::current_controller()->DoAutoEnrollment();
  ExistingUserController::current_controller()->set_login_status_consumer(
      &mock_consumer);
  // This calls StartWizard, destroying the current controller() and its mocks;
  // don't set expectations on those objects.
  ExistingUserController::current_controller()->CompleteLogin(kUsername,
                                                              kPassword);
  EnterpriseEnrollmentScreen* screen =
      controller()->GetEnterpriseEnrollmentScreen();
  EXPECT_EQ(screen, controller()->current_screen());
  std::string user;
  EXPECT_TRUE(screen->IsAutoEnrollment(&user));
  // This is the main expectation: after auto-enrollment, login is resumed.
  EXPECT_CALL(mock_consumer, OnLoginSuccess(_, _, _, _, _)).Times(1);
  OnExit(ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
  // Prevent browser launch when the profile is prepared:
  browser_shutdown::SetTryingToQuit(true);
  // Run the tasks posted to complete the login:
  MessageLoop::current()->RunAllPending();
  set_controller(NULL);
}
#endif

// TODO(nkostylev): Add test for WebUI accelerators http://crosbug.com/22571

COMPILE_ASSERT(ScreenObserver::EXIT_CODES_COUNT == 15,
               add_tests_for_new_control_flow_you_just_introduced);

}  // namespace chromeos
<|endoftext|>


<commit_before>/**
 * Copyright 2012 FAU (Friedrich Alexander University of Erlangen-Nuremberg)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "i6engine/core/messaging/MessagingController.h"

#include "i6engine/utils/Logger.h"

#ifdef ISIXE_WITH_PROFILING
	#include "i6engine/utils/Profiling.h"
#endif

#include "i6engine/core/messaging/MessageSubscriber.h"

#include "boost/thread.hpp"

namespace i6engine {
namespace core {

	MessagingController::MessagingController() : _objMessageTypeDictionary(), _dictionaryMutex(), _deliverThread(nullptr), _condVar(), _condMutex(), _running(true) {
		_deliverThread = new boost::thread(boost::bind(&MessagingController::deliverMessages, this));
	}

	MessagingController::~MessagingController() {
		_running = false;
		{
			std::unique_lock<std::mutex> ul(_condMutex);
			_condVar.notify_all();
		}
		_deliverThread->interrupt();
		_deliverThread->join();
		delete _deliverThread;
	}

	// Deliver all messages that are stored in the queue.
	void MessagingController::deliverMessages() {
		// Step 3
		// send Messages to the buffering method
		while (_running) {
			while (!_msgQueue.empty()) {
				deliverMessageToSubscribers(_msgQueue.poll());
			}
			std::unique_lock<std::mutex> ul(_condMutex);
			_condVar.wait(ul);
		}
	}

	void MessagingController::clear() {
		_msgQueue.clear();
	}

	void MessagingController::deliverMessageToSubscribers(const Message::Ptr & msg) const {
#ifdef ISIXE_WITH_PROFILING
		msg->insertTimestamp("MessagingController deliverMessageToSubscribers");
#endif /* ISIXE_WITH_PROFILING */
		uint16_t msgType = msg->getMessageType();

		std::lock_guard<std::mutex> lg(_dictionaryMutex);
		// Look up the message type in the dictionary (method suggested by Item 24 of Effective STL by Scott Meyers).
		auto it = _objMessageTypeDictionary.find(msgType);
		if (it != _objMessageTypeDictionary.end()) {
			// For each subscriber of the message type: Copy the message and store it in the local buffer of the receiver by calling receiveMessage.
			for (MessageSubscriber * msgSub : it->second) {
				msgSub->receiveMessage(msg);
			}
		} else {
			// if no one is subscribed to the message type, it's no error
			// uneccessary debugging messages
			ISIXE_LOG_INFO("Messaging", "Nobody registered for '" << msgType << "' maybe stop sending this message?\tSubtype is " << msg->getSubtype());
		}
	}

	void MessagingController::registerMessageType(uint16_t msgType, MessageSubscriber * subcriber) {
		std::lock_guard<std::mutex> lg(_dictionaryMutex);

		// Look up if the message type already exists in the dictionary (Suggested by Item 24 of Effective STL by Scott Meyers).
		auto itMsgType = _objMessageTypeDictionary.find(msgType);

		if (itMsgType != _objMessageTypeDictionary.end()) {
			// Look up if the method caller already subscribed for this message type.
			for (MessageSubscriber * sub : itMsgType->second) {
				if (sub == subcriber) {
					ISIXE_LOG_WARN("Messaging", "Message " << msgType << " already defined with the Message Subscriber");
					return;
				}
			}
			_objMessageTypeDictionary[msgType].push_back(subcriber);
		} else {
			// add the Subscriber to the list
			// operator[] will automatically create the new list
			_objMessageTypeDictionary[msgType].push_back(subcriber);
		}
	}

	void MessagingController::unregisterMessageType(uint16_t msgType, MessageSubscriber * subscriber) {
		std::lock_guard<std::mutex> lg(_dictionaryMutex);
		auto itMsgType = _objMessageTypeDictionary.find(msgType);
		// Look up if the message type exists in the dictionary (Suggested by Item 24 of Effective STL by Scott Meyers).
		if (itMsgType != _objMessageTypeDictionary.end()) {
			for (size_t i = 0; i < itMsgType->second.size(); ++i) {
				if (itMsgType->second[i] == subscriber) {
					itMsgType->second.erase(itMsgType->second.begin() + int(i));
				}
			}
			if (itMsgType->second.empty()) {
				_objMessageTypeDictionary.erase(itMsgType);
			}
		}
	}

	void MessagingController::deliverMessage(const Message::Ptr & msg) {
#ifdef ISIXE_WITH_PROFILING
		msg->insertTimestamp("MessagingController deliverMessage");
#endif /* ISIXE_WITH_PROFILING */
		// Step 1
		// entry point for other Threads
		// save Message
		_msgQueue.push(msg);
		// and than notify poll thread that there are new messages
		std::unique_lock<std::mutex> ul(_condMutex);
		_condVar.notify_all();
	}

} /* namespace core */
} /* namespace i6engine */
<commit_msg>ISIXE-909 optimized MessagingController<commit_after>/**
 * Copyright 2012 FAU (Friedrich Alexander University of Erlangen-Nuremberg)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "i6engine/core/messaging/MessagingController.h"

#include "i6engine/utils/Logger.h"

#ifdef ISIXE_WITH_PROFILING
	#include "i6engine/utils/Profiling.h"
#endif

#include "i6engine/core/messaging/MessageSubscriber.h"

#include "boost/thread.hpp"

namespace i6engine {
namespace core {

	MessagingController::MessagingController() : _objMessageTypeDictionary(), _dictionaryMutex(), _deliverThread(nullptr), _condVar(), _condMutex(), _running(true) {
		_deliverThread = new boost::thread(boost::bind(&MessagingController::deliverMessages, this));
	}

	MessagingController::~MessagingController() {
		_running = false;
		{
			std::unique_lock<std::mutex> ul(_condMutex);
			_condVar.notify_all();
		}
		_deliverThread->interrupt();
		_deliverThread->join();
		delete _deliverThread;
	}

	// Deliver all messages that are stored in the queue.
	void MessagingController::deliverMessages() {
		// Step 3
		// send Messages to the buffering method
		while (_running) {
			while (!_msgQueue.empty()) {
				deliverMessageToSubscribers(_msgQueue.poll());
			}
			std::unique_lock<std::mutex> ul(_condMutex);
			_condVar.wait(ul);
		}
	}

	void MessagingController::clear() {
		_msgQueue.clear();
	}

	void MessagingController::deliverMessageToSubscribers(const Message::Ptr & msg) const {
#ifdef ISIXE_WITH_PROFILING
		msg->insertTimestamp("MessagingController deliverMessageToSubscribers");
#endif /* ISIXE_WITH_PROFILING */
		uint16_t msgType = msg->getMessageType();

		std::lock_guard<std::mutex> lg(_dictionaryMutex);
		// Look up the message type in the dictionary (method suggested by Item 24 of Effective STL by Scott Meyers).
		auto it = _objMessageTypeDictionary.find(msgType);
		if (it != _objMessageTypeDictionary.end()) {
			// For each subscriber of the message type: Copy the message and store it in the local buffer of the receiver by calling receiveMessage.
			for (MessageSubscriber * msgSub : it->second) {
				msgSub->receiveMessage(msg);
			}
		} else {
			// if no one is subscribed to the message type, it's no error
			// uneccessary debugging messages
			ISIXE_LOG_INFO("Messaging", "Nobody registered for '" << msgType << "' maybe stop sending this message?\tSubtype is " << msg->getSubtype());
		}
	}

	void MessagingController::registerMessageType(uint16_t msgType, MessageSubscriber * subcriber) {
		std::lock_guard<std::mutex> lg(_dictionaryMutex);

		// Look up if the message type already exists in the dictionary (Suggested by Item 24 of Effective STL by Scott Meyers).
		auto itMsgType = _objMessageTypeDictionary.find(msgType);

		if (itMsgType != _objMessageTypeDictionary.end()) {
			// Look up if the method caller already subscribed for this message type.
			for (MessageSubscriber * sub : itMsgType->second) {
				if (sub == subcriber) {
					ISIXE_LOG_WARN("Messaging", "Message " << msgType << " already defined with the Message Subscriber");
					return;
				}
			}
			_objMessageTypeDictionary[msgType].push_back(subcriber);
		} else {
			// add the Subscriber to the list
			// operator[] will automatically create the new list
			_objMessageTypeDictionary[msgType].push_back(subcriber);
		}
	}

	void MessagingController::unregisterMessageType(uint16_t msgType, MessageSubscriber * subscriber) {
		std::lock_guard<std::mutex> lg(_dictionaryMutex);
		auto itMsgType = _objMessageTypeDictionary.find(msgType);
		// Look up if the message type exists in the dictionary (Suggested by Item 24 of Effective STL by Scott Meyers).
		if (itMsgType != _objMessageTypeDictionary.end()) {
			for (size_t i = 0; i < itMsgType->second.size(); ++i) {
				if (itMsgType->second[i] == subscriber) {
					itMsgType->second.erase(itMsgType->second.begin() + int(i));
				}
			}
			if (itMsgType->second.empty()) {
				_objMessageTypeDictionary.erase(itMsgType);
			}
		}
	}

	void MessagingController::deliverMessage(const Message::Ptr & msg) {
#ifdef ISIXE_WITH_PROFILING
		msg->insertTimestamp("MessagingController deliverMessage");
#endif /* ISIXE_WITH_PROFILING */
		// Step 1
		// entry point for other Threads
		// save Message
		std::unique_lock<std::mutex> ul(_condMutex);
		_msgQueue.push(msg);
		// and than notify poll thread that there are new messages
		_condVar.notify_all();
	}

} /* namespace core */
} /* namespace i6engine */
<|endoftext|>


<commit_before>// Copyright (c) 2012 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/views/widget/tooltip_manager_aura.h"

#include "base/logging.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/screen.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/public/tooltip_client.h"

namespace views {

////////////////////////////////////////////////////////////////////////////////
// TooltipManagerAura public:

TooltipManagerAura::TooltipManagerAura(Widget* widget) : widget_(widget) {
  aura::client::SetTooltipText(GetWindow(), &tooltip_text_);
}

TooltipManagerAura::~TooltipManagerAura() {
  aura::client::SetTooltipText(GetWindow(), NULL);
}

// static
const gfx::FontList& TooltipManagerAura::GetDefaultFontList() {
  return ui::ResourceBundle::GetSharedInstance().GetFontList(
      ui::ResourceBundle::BaseFont);
}

// static
void TooltipManagerAura::UpdateTooltipManagerForCapture(Widget* source) {
  if (!source->HasCapture())
    return;

  aura::Window* root_window = source->GetNativeView()->GetRootWindow();
  if (!root_window)
    return;

  gfx::Point screen_loc(
      root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot());
  aura::client::ScreenPositionClient* screen_position_client =
      aura::client::GetScreenPositionClient(root_window);
  if (!screen_position_client)
    return;
  screen_position_client->ConvertPointToScreen(root_window, &screen_loc);
  gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window);
  aura::Window* target = screen->GetWindowAtScreenPoint(screen_loc);
  if (!target)
    return;
  gfx::Point target_loc(screen_loc);
  screen_position_client =
      aura::client::GetScreenPositionClient(target->GetRootWindow());
  if (!screen_position_client)
    return;
  screen_position_client->ConvertPointFromScreen(target, &target_loc);
  target = target->GetEventHandlerForPoint(target_loc);
  while (target) {
    Widget* target_widget = Widget::GetWidgetForNativeView(target);
    if (target_widget == source)
      return;

    if (target_widget) {
      if (target_widget->GetTooltipManager())
        target_widget->GetTooltipManager()->UpdateTooltip();
      return;
    }
    target = target->parent();
  }
}

////////////////////////////////////////////////////////////////////////////////
// TooltipManagerAura, TooltipManager implementation:

const gfx::FontList& TooltipManagerAura::GetFontList() const {
  return GetDefaultFontList();
}

int TooltipManagerAura::GetMaxWidth(const gfx::Point& point,
                                    aura::Window* context) const {
  return aura::client::GetTooltipClient(context->GetRootWindow())->
      GetMaxWidth(point, context);
}

void TooltipManagerAura::UpdateTooltip() {
  aura::Window* root_window = GetWindow()->GetRootWindow();
  if (aura::client::GetTooltipClient(root_window)) {
    gfx::Point view_point =
        root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
    aura::Window::ConvertPointToTarget(root_window, GetWindow(), &view_point);
    View* view = GetViewUnderPoint(view_point);
    UpdateTooltipForTarget(view, view_point, root_window);
  }
}

void TooltipManagerAura::TooltipTextChanged(View* view)  {
  aura::Window* root_window = GetWindow()->GetRootWindow();
  if (aura::client::GetTooltipClient(root_window)) {
    gfx::Point view_point =
        root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
    aura::Window::ConvertPointToTarget(root_window, GetWindow(), &view_point);
    View* target = GetViewUnderPoint(view_point);
    if (target != view)
      return;
    UpdateTooltipForTarget(view, view_point, root_window);
  }
}

View* TooltipManagerAura::GetViewUnderPoint(const gfx::Point& point) {
  View* root_view = widget_->GetRootView();
  if (root_view)
    return root_view->GetTooltipHandlerForPoint(point);
  return NULL;
}

void TooltipManagerAura::UpdateTooltipForTarget(View* target,
                                                const gfx::Point& point,
                                                aura::Window* root_window) {
  if (target) {
    gfx::Point view_point = point;
    View::ConvertPointFromWidget(target, &view_point);
    base::string16 new_tooltip_text;
    if (!target->GetTooltipText(view_point, &new_tooltip_text))
      tooltip_text_.clear();
    else
      tooltip_text_ = new_tooltip_text;
  } else {
    tooltip_text_.clear();
  }

  aura::client::SetTooltipId(GetWindow(), target);

  aura::client::GetTooltipClient(root_window)->UpdateTooltip(GetWindow());
}

aura::Window* TooltipManagerAura::GetWindow() {
  return widget_->GetNativeView();
}

}  // namespace views.
<commit_msg>[Win] Don't crash when updating tooltip and the ClientView hasn't been added to the view hierarchy.<commit_after>// Copyright (c) 2012 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/views/widget/tooltip_manager_aura.h"

#include "base/logging.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/screen.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/public/tooltip_client.h"

namespace views {

////////////////////////////////////////////////////////////////////////////////
// TooltipManagerAura public:

TooltipManagerAura::TooltipManagerAura(Widget* widget) : widget_(widget) {
  aura::client::SetTooltipText(GetWindow(), &tooltip_text_);
}

TooltipManagerAura::~TooltipManagerAura() {
  aura::client::SetTooltipText(GetWindow(), NULL);
}

// static
const gfx::FontList& TooltipManagerAura::GetDefaultFontList() {
  return ui::ResourceBundle::GetSharedInstance().GetFontList(
      ui::ResourceBundle::BaseFont);
}

// static
void TooltipManagerAura::UpdateTooltipManagerForCapture(Widget* source) {
  if (!source->HasCapture())
    return;

  aura::Window* root_window = source->GetNativeView()->GetRootWindow();
  if (!root_window)
    return;

  gfx::Point screen_loc(
      root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot());
  aura::client::ScreenPositionClient* screen_position_client =
      aura::client::GetScreenPositionClient(root_window);
  if (!screen_position_client)
    return;
  screen_position_client->ConvertPointToScreen(root_window, &screen_loc);
  gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window);
  aura::Window* target = screen->GetWindowAtScreenPoint(screen_loc);
  if (!target)
    return;
  gfx::Point target_loc(screen_loc);
  screen_position_client =
      aura::client::GetScreenPositionClient(target->GetRootWindow());
  if (!screen_position_client)
    return;
  screen_position_client->ConvertPointFromScreen(target, &target_loc);
  target = target->GetEventHandlerForPoint(target_loc);
  while (target) {
    Widget* target_widget = Widget::GetWidgetForNativeView(target);
    if (target_widget == source)
      return;

    if (target_widget) {
      if (target_widget->GetTooltipManager())
        target_widget->GetTooltipManager()->UpdateTooltip();
      return;
    }
    target = target->parent();
  }
}

////////////////////////////////////////////////////////////////////////////////
// TooltipManagerAura, TooltipManager implementation:

const gfx::FontList& TooltipManagerAura::GetFontList() const {
  return GetDefaultFontList();
}

int TooltipManagerAura::GetMaxWidth(const gfx::Point& point,
                                    aura::Window* context) const {
  return aura::client::GetTooltipClient(context->GetRootWindow())->
      GetMaxWidth(point, context);
}

void TooltipManagerAura::UpdateTooltip() {
  aura::Window* root_window = GetWindow()->GetRootWindow();
  if (aura::client::GetTooltipClient(root_window)) {
    if (!widget_->IsVisible()) {
      UpdateTooltipForTarget(NULL, gfx::Point(), root_window);
      return;
    }
    gfx::Point view_point =
        root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
    aura::Window::ConvertPointToTarget(root_window, GetWindow(), &view_point);
    View* view = GetViewUnderPoint(view_point);
    UpdateTooltipForTarget(view, view_point, root_window);
  }
}

void TooltipManagerAura::TooltipTextChanged(View* view)  {
  aura::Window* root_window = GetWindow()->GetRootWindow();
  if (aura::client::GetTooltipClient(root_window)) {
    gfx::Point view_point =
        root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
    aura::Window::ConvertPointToTarget(root_window, GetWindow(), &view_point);
    View* target = GetViewUnderPoint(view_point);
    if (target != view)
      return;
    UpdateTooltipForTarget(view, view_point, root_window);
  }
}

View* TooltipManagerAura::GetViewUnderPoint(const gfx::Point& point) {
  View* root_view = widget_->GetRootView();
  if (root_view)
    return root_view->GetTooltipHandlerForPoint(point);
  return NULL;
}

void TooltipManagerAura::UpdateTooltipForTarget(View* target,
                                                const gfx::Point& point,
                                                aura::Window* root_window) {
  if (target) {
    gfx::Point view_point = point;
    View::ConvertPointFromWidget(target, &view_point);
    base::string16 new_tooltip_text;
    if (!target->GetTooltipText(view_point, &new_tooltip_text))
      tooltip_text_.clear();
    else
      tooltip_text_ = new_tooltip_text;
  } else {
    tooltip_text_.clear();
  }

  aura::client::SetTooltipId(GetWindow(), target);

  aura::client::GetTooltipClient(root_window)->UpdateTooltip(GetWindow());
}

aura::Window* TooltipManagerAura::GetWindow() {
  return widget_->GetNativeView();
}

}  // namespace views.
<|endoftext|>


<commit_before>/***********************************************************************
    filename:   CEGUIScrolledContainer.cpp
    created:    1/3/2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/widgets/ScrolledContainer.h"
#include "CEGUI/CoordConverter.h"
#include "CEGUI/RenderingSurface.h"

#if defined(_MSC_VER)
#   pragma warning(push)
#   pragma warning(disable : 4355)
#endif

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
const String ScrolledContainer::WidgetTypeName("ScrolledContainer");
const String ScrolledContainer::EventNamespace("ScrolledContainer");
const String ScrolledContainer::EventContentChanged("ContentChanged");
const String ScrolledContainer::EventAutoSizeSettingChanged("AutoSizeSettingChanged");

//----------------------------------------------------------------------------//
ScrolledContainer::ScrolledContainer(const String& type, const String& name) :
    Window(type, name),
    d_contentArea(0, 0, 0, 0),
    d_autosizePane(true),

    d_clientChildContentArea(this, static_cast<Element::CachedRectf::DataGenerator>(&ScrolledContainer::getClientChildContentArea_impl))
{
    addScrolledContainerProperties();
    setMouseInputPropagationEnabled(true);
}

//----------------------------------------------------------------------------//
ScrolledContainer::~ScrolledContainer(void)
{
}

//----------------------------------------------------------------------------//
bool ScrolledContainer::isContentPaneAutoSized(void) const
{
    return d_autosizePane;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::setContentPaneAutoSized(bool setting)
{
    if (d_autosizePane != setting)
    {
        d_autosizePane = setting;

        // Fire events
        WindowEventArgs args1(this);
        onAutoSizeSettingChanged(args1);
    }
}

//----------------------------------------------------------------------------//
const Rectf& ScrolledContainer::getContentArea(void) const
{
    return d_contentArea;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::setContentArea(const Rectf& area)
{
    if (!d_autosizePane)
    {
        d_contentArea = area;

        // Fire event
        WindowEventArgs args(this);
        onContentChanged(args);
   }

}

//----------------------------------------------------------------------------//
const Element::CachedRectf& ScrolledContainer::getClientChildContentArea() const
{
    return d_clientChildContentArea;
}

//----------------------------------------------------------------------------//
const Element::CachedRectf& ScrolledContainer::getNonClientChildContentArea() const
{
    return d_clientChildContentArea;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::notifyScreenAreaChanged(bool recursive)
{
    d_clientChildContentArea.invalidateCache();

    Window::notifyScreenAreaChanged(recursive);
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getChildExtentsArea(void) const
{
    Rectf extents(0, 0, 0, 0);

    const size_t childCount = getChildCount();
    if (childCount == 0)
        return extents;

    for (size_t i = 0; i < childCount; ++i)
    {
        const Window* const wnd = getChildAtIdx(i);
        const Rectf area(
            CoordConverter::asAbsolute(wnd->getPosition(), d_pixelSize),
            wnd->getPixelSize());

        if (area.d_min.d_x < extents.d_min.d_x)
            extents.d_min.d_x = area.d_min.d_x;

        if (area.d_min.d_y < extents.d_min.d_y)
            extents.d_min.d_y = area.d_min.d_y;

        if (area.d_max.d_x > extents.d_max.d_x)
            extents.d_max.d_x = area.d_max.d_x;

        if (area.d_max.d_y > extents.d_max.d_y)
            extents.d_max.d_y = area.d_max.d_y;
    }

    return extents;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onContentChanged(WindowEventArgs& e)
{
    if (d_autosizePane)
    {
        d_contentArea = getChildExtentsArea();
    }

    fireEvent(EventContentChanged, e, EventNamespace);
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onAutoSizeSettingChanged(WindowEventArgs& e)
{
    fireEvent(EventAutoSizeSettingChanged, e, EventNamespace);

    if (d_autosizePane)
    {
        WindowEventArgs args(this);
        onContentChanged(args);
    }
}

//----------------------------------------------------------------------------//
bool ScrolledContainer::handleChildSized(const EventArgs&)
{
    // Fire event that notifies that a child's area has changed.
    WindowEventArgs args(this);
    onContentChanged(args);
    return true;
}

//----------------------------------------------------------------------------//
bool ScrolledContainer::handleChildMoved(const EventArgs&)
{
    // Fire event that notifies that a child's area has changed.
    WindowEventArgs args(this);
    onContentChanged(args);
    return true;
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getUnclippedInnerRect_impl(bool skipAllPixelAlignment) const
{
    return d_parent ?
        (skipAllPixelAlignment ? d_parent->getUnclippedInnerRect().getFresh(true) : d_parent->getUnclippedInnerRect().get()) :
        Window::getUnclippedInnerRect_impl(skipAllPixelAlignment);
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getInnerRectClipper_impl() const
{
    return d_parent ?
        getParent()->getInnerRectClipper() :
        Window::getInnerRectClipper_impl();
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getHitTestRect_impl() const
{
    return d_parent ? getParent()->getHitTestRect() :
                      Window::getHitTestRect_impl();
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getClientChildContentArea_impl(bool skipAllPixelAlignment) const
{
    if (!d_parent)
    {
        return skipAllPixelAlignment ? Window::getUnclippedInnerRect().getFresh(true) : Window::getUnclippedInnerRect().get();
    }
    else
    {
        if (skipAllPixelAlignment)
        {
            return Rectf(getUnclippedOuterRect().getFresh(true).getPosition(),
                         getParent()->getUnclippedInnerRect().getFresh(true).getSize());
        }
        else
        {
            return Rectf(getUnclippedOuterRect().get().getPosition(),
                         getParent()->getUnclippedInnerRect().get().getSize());
        }
    }
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onChildAdded(ElementEventArgs& e)
{
    Window::onChildAdded(e);

    // subscribe to some events on this child
    d_eventConnections.insert(std::make_pair(static_cast<Window*>(e.element),
        static_cast<Window*>(e.element)->subscribeEvent(Window::EventSized,
            Event::Subscriber(&ScrolledContainer::handleChildSized, this))));
    d_eventConnections.insert(std::make_pair(static_cast<Window*>(e.element),
        static_cast<Window*>(e.element)->subscribeEvent(Window::EventMoved,
            Event::Subscriber(&ScrolledContainer::handleChildMoved, this))));

    // force window to update what it thinks it's screen / pixel areas are.
    static_cast<Window*>(e.element)->notifyScreenAreaChanged(false);

    // perform notification.
    WindowEventArgs args(this);
    onContentChanged(args);
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onChildRemoved(ElementEventArgs& e)
{
    Window::onChildRemoved(e);

    // disconnect from events for this window.
    ConnectionTracker::iterator conn;
    while ((conn = d_eventConnections.find(static_cast<Window*>(e.element))) != d_eventConnections.end())
    {
        conn->second->disconnect();
        d_eventConnections.erase(conn);
    }

    // perform notification only if we're not currently being destroyed
    if (!d_destructionStarted)
    {
        WindowEventArgs args(this);
        onContentChanged(args);
    }
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onParentSized(ElementEventArgs& e)
{
    Window::onParentSized(e);

    // perform notification.
    WindowEventArgs args(this);
    onContentChanged(args);
}

//----------------------------------------------------------------------------//
void ScrolledContainer::addScrolledContainerProperties(void)
{
    const String& propertyOrigin = WidgetTypeName;

    CEGUI_DEFINE_PROPERTY(ScrolledContainer, bool,
        "ContentPaneAutoSized", "Property to get/set the setting which controls whether the content pane will auto-size itself."
        "  Value is either \"True\" or \"False\".",
        &ScrolledContainer::setContentPaneAutoSized, &ScrolledContainer::isContentPaneAutoSized, true
    );

    CEGUI_DEFINE_PROPERTY(ScrolledContainer, Rectf,
        "ContentArea", "Property to get/set the current content area rectangle of the content pane."
        "  Value is \"l:[float] t:[float] r:[float] b:[float]\" (where l is left, t is top, r is right, and b is bottom).",
        &ScrolledContainer::setContentArea, &ScrolledContainer::getContentArea, Rectf::zero()
    );

    CEGUI_DEFINE_PROPERTY(ScrolledContainer, Rectf,
        "ChildExtentsArea", "Property to get the current content extents rectangle."
        "  Value is \"l:[float] t:[float] r:[float] b:[float]\" (where l is left, t is top, r is right, and b is bottom).",
        0, &ScrolledContainer::getChildExtentsArea, Rectf::zero()
    );
}

//----------------------------------------------------------------------------//
void ScrolledContainer::setArea_impl(const UVector2& pos, const USize& size,
                                     bool topLeftSizing, bool fireEvents)
{
    d_clientChildContentArea.invalidateCache();
    Window::setArea_impl(pos, size, topLeftSizing, fireEvents);
}

//----------------------------------------------------------------------------//

#if defined(_MSC_VER)
#   pragma warning(pop)
#endif

} // End of  CEGUI namespace section
<commit_msg>FIX: Fixing the content area calculation in the case of Center aligned windows<commit_after>/***********************************************************************
    filename:   CEGUIScrolledContainer.cpp
    created:    1/3/2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/widgets/ScrolledContainer.h"
#include "CEGUI/CoordConverter.h"
#include "CEGUI/RenderingSurface.h"

#if defined(_MSC_VER)
#   pragma warning(push)
#   pragma warning(disable : 4355)
#endif

// Start of CEGUI namespace section
namespace CEGUI
{
//----------------------------------------------------------------------------//
const String ScrolledContainer::WidgetTypeName("ScrolledContainer");
const String ScrolledContainer::EventNamespace("ScrolledContainer");
const String ScrolledContainer::EventContentChanged("ContentChanged");
const String ScrolledContainer::EventAutoSizeSettingChanged("AutoSizeSettingChanged");

//----------------------------------------------------------------------------//
ScrolledContainer::ScrolledContainer(const String& type, const String& name) :
    Window(type, name),
    d_contentArea(0, 0, 0, 0),
    d_autosizePane(true),

    d_clientChildContentArea(this, static_cast<Element::CachedRectf::DataGenerator>(&ScrolledContainer::getClientChildContentArea_impl))
{
    addScrolledContainerProperties();
    setMouseInputPropagationEnabled(true);
}

//----------------------------------------------------------------------------//
ScrolledContainer::~ScrolledContainer(void)
{
}

//----------------------------------------------------------------------------//
bool ScrolledContainer::isContentPaneAutoSized(void) const
{
    return d_autosizePane;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::setContentPaneAutoSized(bool setting)
{
    if (d_autosizePane != setting)
    {
        d_autosizePane = setting;

        // Fire events
        WindowEventArgs args1(this);
        onAutoSizeSettingChanged(args1);
    }
}

//----------------------------------------------------------------------------//
const Rectf& ScrolledContainer::getContentArea(void) const
{
    return d_contentArea;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::setContentArea(const Rectf& area)
{
    if (!d_autosizePane)
    {
        d_contentArea = area;

        // Fire event
        WindowEventArgs args(this);
        onContentChanged(args);
   }

}

//----------------------------------------------------------------------------//
const Element::CachedRectf& ScrolledContainer::getClientChildContentArea() const
{
    return d_clientChildContentArea;
}

//----------------------------------------------------------------------------//
const Element::CachedRectf& ScrolledContainer::getNonClientChildContentArea() const
{
    return d_clientChildContentArea;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::notifyScreenAreaChanged(bool recursive)
{
    d_clientChildContentArea.invalidateCache();

    Window::notifyScreenAreaChanged(recursive);
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getChildExtentsArea(void) const
{
    Rectf extents(0, 0, 0, 0);

    const size_t childCount = getChildCount();
    if (childCount == 0)
        return extents;

    for (size_t i = 0; i < childCount; ++i)
    {
        const Window* const wnd = getChildAtIdx(i);
        Rectf area(
            CoordConverter::asAbsolute(wnd->getPosition(), d_pixelSize),
            wnd->getPixelSize());

        if(wnd->getHorizontalAlignment() == HA_CENTRE)
            area.setPosition( area.getPosition() - CEGUI::Vector2f( area.getWidth() * 0.5f - d_pixelSize.d_width * 0.5f, 0.0f ) );
        if(wnd->getHorizontalAlignment() == VA_CENTRE)
            area.setPosition( area.getPosition() - CEGUI::Vector2f( 0.0f, area.getHeight() * 0.5f - d_pixelSize.d_height * 0.5f ) );

        if (area.d_min.d_x < extents.d_min.d_x)
            extents.d_min.d_x = area.d_min.d_x;

        if (area.d_min.d_y < extents.d_min.d_y)
            extents.d_min.d_y = area.d_min.d_y;

        if (area.d_max.d_x > extents.d_max.d_x)
            extents.d_max.d_x = area.d_max.d_x;

        if (area.d_max.d_y > extents.d_max.d_y)
            extents.d_max.d_y = area.d_max.d_y;
    }

    return extents;
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onContentChanged(WindowEventArgs& e)
{
    if (d_autosizePane)
    {
        d_contentArea = getChildExtentsArea();
    }

    fireEvent(EventContentChanged, e, EventNamespace);
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onAutoSizeSettingChanged(WindowEventArgs& e)
{
    fireEvent(EventAutoSizeSettingChanged, e, EventNamespace);

    if (d_autosizePane)
    {
        WindowEventArgs args(this);
        onContentChanged(args);
    }
}

//----------------------------------------------------------------------------//
bool ScrolledContainer::handleChildSized(const EventArgs&)
{
    // Fire event that notifies that a child's area has changed.
    WindowEventArgs args(this);
    onContentChanged(args);
    return true;
}

//----------------------------------------------------------------------------//
bool ScrolledContainer::handleChildMoved(const EventArgs&)
{
    // Fire event that notifies that a child's area has changed.
    WindowEventArgs args(this);
    onContentChanged(args);
    return true;
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getUnclippedInnerRect_impl(bool skipAllPixelAlignment) const
{
    return d_parent ?
        (skipAllPixelAlignment ? d_parent->getUnclippedInnerRect().getFresh(true) : d_parent->getUnclippedInnerRect().get()) :
        Window::getUnclippedInnerRect_impl(skipAllPixelAlignment);
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getInnerRectClipper_impl() const
{
    return d_parent ?
        getParent()->getInnerRectClipper() :
        Window::getInnerRectClipper_impl();
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getHitTestRect_impl() const
{
    return d_parent ? getParent()->getHitTestRect() :
                      Window::getHitTestRect_impl();
}

//----------------------------------------------------------------------------//
Rectf ScrolledContainer::getClientChildContentArea_impl(bool skipAllPixelAlignment) const
{
    if (!d_parent)
    {
        return skipAllPixelAlignment ? Window::getUnclippedInnerRect().getFresh(true) : Window::getUnclippedInnerRect().get();
    }
    else
    {
        if (skipAllPixelAlignment)
        {
            return Rectf(getUnclippedOuterRect().getFresh(true).getPosition(),
                         getParent()->getUnclippedInnerRect().getFresh(true).getSize());
        }
        else
        {
            return Rectf(getUnclippedOuterRect().get().getPosition(),
                         getParent()->getUnclippedInnerRect().get().getSize());
        }
    }
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onChildAdded(ElementEventArgs& e)
{
    Window::onChildAdded(e);

    // subscribe to some events on this child
    d_eventConnections.insert(std::make_pair(static_cast<Window*>(e.element),
        static_cast<Window*>(e.element)->subscribeEvent(Window::EventSized,
            Event::Subscriber(&ScrolledContainer::handleChildSized, this))));
    d_eventConnections.insert(std::make_pair(static_cast<Window*>(e.element),
        static_cast<Window*>(e.element)->subscribeEvent(Window::EventMoved,
            Event::Subscriber(&ScrolledContainer::handleChildMoved, this))));

    // force window to update what it thinks it's screen / pixel areas are.
    static_cast<Window*>(e.element)->notifyScreenAreaChanged(false);

    // perform notification.
    WindowEventArgs args(this);
    onContentChanged(args);
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onChildRemoved(ElementEventArgs& e)
{
    Window::onChildRemoved(e);

    // disconnect from events for this window.
    ConnectionTracker::iterator conn;
    while ((conn = d_eventConnections.find(static_cast<Window*>(e.element))) != d_eventConnections.end())
    {
        conn->second->disconnect();
        d_eventConnections.erase(conn);
    }

    // perform notification only if we're not currently being destroyed
    if (!d_destructionStarted)
    {
        WindowEventArgs args(this);
        onContentChanged(args);
    }
}

//----------------------------------------------------------------------------//
void ScrolledContainer::onParentSized(ElementEventArgs& e)
{
    Window::onParentSized(e);

    // perform notification.
    WindowEventArgs args(this);
    onContentChanged(args);
}

//----------------------------------------------------------------------------//
void ScrolledContainer::addScrolledContainerProperties(void)
{
    const String& propertyOrigin = WidgetTypeName;

    CEGUI_DEFINE_PROPERTY(ScrolledContainer, bool,
        "ContentPaneAutoSized", "Property to get/set the setting which controls whether the content pane will auto-size itself."
        "  Value is either \"True\" or \"False\".",
        &ScrolledContainer::setContentPaneAutoSized, &ScrolledContainer::isContentPaneAutoSized, true
    );

    CEGUI_DEFINE_PROPERTY(ScrolledContainer, Rectf,
        "ContentArea", "Property to get/set the current content area rectangle of the content pane."
        "  Value is \"l:[float] t:[float] r:[float] b:[float]\" (where l is left, t is top, r is right, and b is bottom).",
        &ScrolledContainer::setContentArea, &ScrolledContainer::getContentArea, Rectf::zero()
    );

    CEGUI_DEFINE_PROPERTY(ScrolledContainer, Rectf,
        "ChildExtentsArea", "Property to get the current content extents rectangle."
        "  Value is \"l:[float] t:[float] r:[float] b:[float]\" (where l is left, t is top, r is right, and b is bottom).",
        0, &ScrolledContainer::getChildExtentsArea, Rectf::zero()
    );
}

//----------------------------------------------------------------------------//
void ScrolledContainer::setArea_impl(const UVector2& pos, const USize& size,
                                     bool topLeftSizing, bool fireEvents)
{
    d_clientChildContentArea.invalidateCache();
    Window::setArea_impl(pos, size, topLeftSizing, fireEvents);
}

//----------------------------------------------------------------------------//

#if defined(_MSC_VER)
#   pragma warning(pop)
#endif

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 <map>

#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/test_management_policy.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/manifest.h"
#include "content/public/test/test_utils.h"

using extensions::Extension;
using extensions::Manifest;

namespace {

// Find a browser other than |browser|.
Browser* FindOtherBrowser(Browser* browser) {
  Browser* found = NULL;
  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
    if (*it == browser)
      continue;
    found = *it;
  }
  return found;
}

}  // namespace

class ExtensionManagementApiTest : public ExtensionApiTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    ExtensionApiTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kEnablePanels);
  }

  virtual void LoadExtensions() {
    base::FilePath basedir = test_data_dir_.AppendASCII("management");

    // Load 4 enabled items.
    LoadNamedExtension(basedir, "enabled_extension");
    LoadNamedExtension(basedir, "enabled_app");
    LoadNamedExtension(basedir, "description");
    LoadNamedExtension(basedir, "permissions");

    // Load 2 disabled items.
    LoadNamedExtension(basedir, "disabled_extension");
    DisableExtension(extension_ids_["disabled_extension"]);
    LoadNamedExtension(basedir, "disabled_app");
    DisableExtension(extension_ids_["disabled_app"]);
  }

  // Load an app, and wait for a message from app "management/launch_on_install"
  // indicating that the new app has been launched.
  void LoadAndWaitForLaunch(const std::string& app_path,
                            std::string* out_app_id) {
    ExtensionTestMessageListener launched_app("launched app", false);
    ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_path)));

    if (out_app_id)
      *out_app_id = last_loaded_extension_id_;

    ASSERT_TRUE(launched_app.WaitUntilSatisfied());
  }

 protected:
  void LoadNamedExtension(const base::FilePath& path,
                          const std::string& name) {
    const Extension* extension = LoadExtension(path.AppendASCII(name));
    ASSERT_TRUE(extension);
    extension_ids_[name] = extension->id();
  }

  void InstallNamedExtension(const base::FilePath& path,
                             const std::string& name,
                             Manifest::Location install_source) {
    const Extension* extension = InstallExtension(path.AppendASCII(name), 1,
                                                  install_source);
    ASSERT_TRUE(extension);
    extension_ids_[name] = extension->id();
  }

  // Maps installed extension names to their IDs.
  std::map<std::string, std::string> extension_ids_;
};

IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Basics) {
  LoadExtensions();

  base::FilePath basedir = test_data_dir_.AppendASCII("management");
  InstallNamedExtension(basedir, "internal_extension", Manifest::INTERNAL);
  InstallNamedExtension(basedir, "external_extension",
                        Manifest::EXTERNAL_PREF);
  InstallNamedExtension(basedir, "admin_extension",
                        Manifest::EXTERNAL_POLICY_DOWNLOAD);

  ASSERT_TRUE(RunExtensionSubtest("management/test", "basics.html"));
}

IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Uninstall) {
  LoadExtensions();
  ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html"));
}

// Tests actions on extensions when no management policy is in place.
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, ManagementPolicyAllowed) {
  LoadExtensions();
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();
  EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
                                        false));

  // Ensure that all actions are allowed.
  extensions::ExtensionSystem::Get(
      browser()->profile())->management_policy()->UnregisterAllProviders();

  ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
                                  "allowed.html"));
  // The last thing the test does is uninstall the "enabled_extension".
  EXPECT_FALSE(service->GetExtensionById(extension_ids_["enabled_extension"],
                                         true));
}

// Tests actions on extensions when management policy prohibits those actions.
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, ManagementPolicyProhibited) {
  LoadExtensions();
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();
  EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
                                        false));

  // Prohibit status changes.
  extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get(
      browser()->profile())->management_policy();
  policy->UnregisterAllProviders();
  extensions::TestManagementPolicyProvider provider(
    extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
  policy->RegisterProvider(&provider);
  ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
                                  "prohibited.html"));
}

IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, LaunchPanelApp) {
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();

  // Load an extension that calls launchApp() on any app that gets
  // installed.
  ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("management/launch_on_install")));
  ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());

  // Load an app with app.launch.container = "panel".
  std::string app_id;
  LoadAndWaitForLaunch("management/launch_app_panel", &app_id);
  ASSERT_FALSE(HasFatalFailure());  // Stop the test if any ASSERT failed.

  // Find the app's browser.  Check that it is a popup.
  ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  Browser* app_browser = FindOtherBrowser(browser());
  ASSERT_TRUE(app_browser->is_type_popup());
  ASSERT_TRUE(app_browser->is_app());

  // Close the app panel.
  content::WindowedNotificationObserver signal(
      chrome::NOTIFICATION_BROWSER_CLOSED,
      content::Source<Browser>(app_browser));

  chrome::CloseWindow(app_browser);
  signal.Wait();

  // Unload the extension.
  UninstallExtension(app_id);
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_FALSE(service->GetExtensionById(app_id, true));

  // Set a pref indicating that the user wants to launch in a regular tab.
  // This should be ignored, because panel apps always load in a popup.
  service->extension_prefs()->SetLaunchType(
      app_id, extensions::ExtensionPrefs::LAUNCH_REGULAR);

  // Load the extension again.
  std::string app_id_new;
  LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new);
  ASSERT_FALSE(HasFatalFailure());

  // If the ID changed, then the pref will not apply to the app.
  ASSERT_EQ(app_id, app_id_new);

  // Find the app's browser.  Apps that should load in a panel ignore
  // prefs, so we should still see the launch in a popup.
  ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  app_browser = FindOtherBrowser(browser());
  ASSERT_TRUE(app_browser->is_type_popup());
  ASSERT_TRUE(app_browser->is_app());
}

IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, LaunchTabApp) {
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();

  // Load an extension that calls launchApp() on any app that gets
  // installed.
  ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("management/launch_on_install")));
  ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());

  // Code below assumes that the test starts with a single browser window
  // hosting one tab.
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_EQ(1, browser()->tab_strip_model()->count());

  // Load an app with app.launch.container = "tab".
  std::string app_id;
  LoadAndWaitForLaunch("management/launch_app_tab", &app_id);
  ASSERT_FALSE(HasFatalFailure());

  // Check that the app opened in a new tab of the existing browser.
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

  // Unload the extension.
  UninstallExtension(app_id);
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_FALSE(service->GetExtensionById(app_id, true));

  // Set a pref indicating that the user wants to launch in a window.
  service->extension_prefs()->SetLaunchType(
      app_id, extensions::ExtensionPrefs::LAUNCH_WINDOW);

  std::string app_id_new;
  LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new);
  ASSERT_FALSE(HasFatalFailure());

  // If the ID changed, then the pref will not apply to the app.
  ASSERT_EQ(app_id, app_id_new);

#if defined(OS_MACOSX)
  // App windows are not yet implemented on mac os.  We should fall back
  // to a normal tab.
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_EQ(2, browser()->tab_strip_model()->count());
#else
  // Find the app's browser.  Opening in a new window will create
  // a new browser.
  ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  Browser* app_browser = FindOtherBrowser(browser());
  ASSERT_TRUE(app_browser->is_app());
#endif
}
<commit_msg>Revert 194464 "Re-enable various ExtensionManagementApiTest tests."<commit_after>// Copyright (c) 2012 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 <map>

#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/test_management_policy.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/manifest.h"
#include "content/public/test/test_utils.h"

using extensions::Extension;
using extensions::Manifest;

namespace {

// Find a browser other than |browser|.
Browser* FindOtherBrowser(Browser* browser) {
  Browser* found = NULL;
  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
    if (*it == browser)
      continue;
    found = *it;
  }
  return found;
}

}  // namespace

class ExtensionManagementApiTest : public ExtensionApiTest {
 public:
  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    ExtensionApiTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kEnablePanels);
  }

  virtual void LoadExtensions() {
    base::FilePath basedir = test_data_dir_.AppendASCII("management");

    // Load 4 enabled items.
    LoadNamedExtension(basedir, "enabled_extension");
    LoadNamedExtension(basedir, "enabled_app");
    LoadNamedExtension(basedir, "description");
    LoadNamedExtension(basedir, "permissions");

    // Load 2 disabled items.
    LoadNamedExtension(basedir, "disabled_extension");
    DisableExtension(extension_ids_["disabled_extension"]);
    LoadNamedExtension(basedir, "disabled_app");
    DisableExtension(extension_ids_["disabled_app"]);
  }

  // Load an app, and wait for a message from app "management/launch_on_install"
  // indicating that the new app has been launched.
  void LoadAndWaitForLaunch(const std::string& app_path,
                            std::string* out_app_id) {
    ExtensionTestMessageListener launched_app("launched app", false);
    ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_path)));

    if (out_app_id)
      *out_app_id = last_loaded_extension_id_;

    ASSERT_TRUE(launched_app.WaitUntilSatisfied());
  }

 protected:
  void LoadNamedExtension(const base::FilePath& path,
                          const std::string& name) {
    const Extension* extension = LoadExtension(path.AppendASCII(name));
    ASSERT_TRUE(extension);
    extension_ids_[name] = extension->id();
  }

  void InstallNamedExtension(const base::FilePath& path,
                             const std::string& name,
                             Manifest::Location install_source) {
    const Extension* extension = InstallExtension(path.AppendASCII(name), 1,
                                                  install_source);
    ASSERT_TRUE(extension);
    extension_ids_[name] = extension->id();
  }

  // Maps installed extension names to their IDs.
  std::map<std::string, std::string> extension_ids_;
};

IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Basics) {
  LoadExtensions();

  base::FilePath basedir = test_data_dir_.AppendASCII("management");
  InstallNamedExtension(basedir, "internal_extension", Manifest::INTERNAL);
  InstallNamedExtension(basedir, "external_extension",
                        Manifest::EXTERNAL_PREF);
  InstallNamedExtension(basedir, "admin_extension",
                        Manifest::EXTERNAL_POLICY_DOWNLOAD);

  ASSERT_TRUE(RunExtensionSubtest("management/test", "basics.html"));
}

// Disabled: http://crbug.com/174411
#if defined(OS_WIN)
#define MAYBE_Uninstall DISABLED_Uninstall
#else
#define MAYBE_Uninstall Uninstall
#endif

IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_Uninstall) {
  LoadExtensions();
  ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html"));
}

// Tests actions on extensions when no management policy is in place.
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, ManagementPolicyAllowed) {
  LoadExtensions();
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();
  EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
                                        false));

  // Ensure that all actions are allowed.
  extensions::ExtensionSystem::Get(
      browser()->profile())->management_policy()->UnregisterAllProviders();

  ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
                                  "allowed.html"));
  // The last thing the test does is uninstall the "enabled_extension".
  EXPECT_FALSE(service->GetExtensionById(extension_ids_["enabled_extension"],
                                         true));
}

// Tests actions on extensions when management policy prohibits those actions.
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, ManagementPolicyProhibited) {
  LoadExtensions();
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();
  EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
                                        false));

  // Prohibit status changes.
  extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get(
      browser()->profile())->management_policy();
  policy->UnregisterAllProviders();
  extensions::TestManagementPolicyProvider provider(
    extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
  policy->RegisterProvider(&provider);
  ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
                                  "prohibited.html"));
}

// Disabled. See http://crbug.com/176023
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, DISABLED_LaunchPanelApp) {
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();

  // Load an extension that calls launchApp() on any app that gets
  // installed.
  ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("management/launch_on_install")));
  ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());

  // Load an app with app.launch.container = "panel".
  std::string app_id;
  LoadAndWaitForLaunch("management/launch_app_panel", &app_id);
  ASSERT_FALSE(HasFatalFailure());  // Stop the test if any ASSERT failed.

  // Find the app's browser.  Check that it is a popup.
  ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  Browser* app_browser = FindOtherBrowser(browser());
  ASSERT_TRUE(app_browser->is_type_popup());
  ASSERT_TRUE(app_browser->is_app());

  // Close the app panel.
  content::WindowedNotificationObserver signal(
      chrome::NOTIFICATION_BROWSER_CLOSED,
      content::Source<Browser>(app_browser));

  chrome::CloseWindow(app_browser);
  signal.Wait();

  // Unload the extension.
  UninstallExtension(app_id);
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_FALSE(service->GetExtensionById(app_id, true));

  // Set a pref indicating that the user wants to launch in a regular tab.
  // This should be ignored, because panel apps always load in a popup.
  service->extension_prefs()->SetLaunchType(
      app_id, extensions::ExtensionPrefs::LAUNCH_REGULAR);

  // Load the extension again.
  std::string app_id_new;
  LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new);
  ASSERT_FALSE(HasFatalFailure());

  // If the ID changed, then the pref will not apply to the app.
  ASSERT_EQ(app_id, app_id_new);

  // Find the app's browser.  Apps that should load in a panel ignore
  // prefs, so we should still see the launch in a popup.
  ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  app_browser = FindOtherBrowser(browser());
  ASSERT_TRUE(app_browser->is_type_popup());
  ASSERT_TRUE(app_browser->is_app());
}

// Disabled: http://crbug.com/230165
#if defined(OS_WIN)
#define MAYBE_LaunchTabApp DISABLED_LaunchTabApp
#else
#define MAYBE_LaunchTabApp LaunchTabApp
#endif
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_LaunchTabApp) {
  ExtensionService* service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();

  // Load an extension that calls launchApp() on any app that gets
  // installed.
  ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("management/launch_on_install")));
  ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());

  // Code below assumes that the test starts with a single browser window
  // hosting one tab.
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_EQ(1, browser()->tab_strip_model()->count());

  // Load an app with app.launch.container = "tab".
  std::string app_id;
  LoadAndWaitForLaunch("management/launch_app_tab", &app_id);
  ASSERT_FALSE(HasFatalFailure());

  // Check that the app opened in a new tab of the existing browser.
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

  // Unload the extension.
  UninstallExtension(app_id);
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_FALSE(service->GetExtensionById(app_id, true));

  // Set a pref indicating that the user wants to launch in a window.
  service->extension_prefs()->SetLaunchType(
      app_id, extensions::ExtensionPrefs::LAUNCH_WINDOW);

  std::string app_id_new;
  LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new);
  ASSERT_FALSE(HasFatalFailure());

  // If the ID changed, then the pref will not apply to the app.
  ASSERT_EQ(app_id, app_id_new);

#if defined(OS_MACOSX)
  // App windows are not yet implemented on mac os.  We should fall back
  // to a normal tab.
  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  ASSERT_EQ(2, browser()->tab_strip_model()->count());
#else
  // Find the app's browser.  Opening in a new window will create
  // a new browser.
  ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
                                        browser()->host_desktop_type()));
  Browser* app_browser = FindOtherBrowser(browser());
  ASSERT_TRUE(app_browser->is_app());
#endif
}
<|endoftext|>