// 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/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/background/background_mode_manager.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/status_icons/status_icon_menu_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/message_center/message_center.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/users/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#endif

class BackgroundModeManagerTest : public testing::Test {
 public:
  BackgroundModeManagerTest() {}
  virtual ~BackgroundModeManagerTest() {}
  virtual void SetUp() {
    command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM));
  }
  scoped_ptr<CommandLine> command_line_;

 protected:
  scoped_refptr<extensions::Extension> CreateExtension(
      extensions::Manifest::Location location,
      const std::string& data,
      const std::string& id) {
    scoped_ptr<base::DictionaryValue> parsed_manifest(
        extension_function_test_utils::ParseDictionary(data));
    return extension_function_test_utils::CreateExtension(
        location,
        parsed_manifest.get(),
        id);
  }

  scoped_ptr<TestingProfileManager> CreateTestingProfileManager() {
    scoped_ptr<TestingProfileManager> profile_manager
        (new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
    EXPECT_TRUE(profile_manager->SetUp());
    return profile_manager.Pass();
  }

  // From views::MenuModelAdapter::IsCommandEnabled with modification.
  bool IsCommandEnabled(ui::MenuModel* model, int id) const {
    int index = 0;
    if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index))
      return model->IsEnabledAt(index);

    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BackgroundModeManagerTest);
};

class TestBackgroundModeManager : public BackgroundModeManager {
 public:
  TestBackgroundModeManager(
      CommandLine* command_line, ProfileInfoCache* cache, bool enabled)
      : BackgroundModeManager(command_line, cache),
        enabled_(enabled),
        app_count_(0),
        profile_app_count_(0),
        have_status_tray_(false),
        launch_on_startup_(false) {
    ResumeBackgroundMode();
  }
  virtual void EnableLaunchOnStartup(bool launch) OVERRIDE {
    launch_on_startup_ = launch;
  }
  virtual void DisplayAppInstalledNotification(
      const extensions::Extension* extension) OVERRIDE {}
  virtual void CreateStatusTrayIcon() OVERRIDE { have_status_tray_ = true; }
  virtual void RemoveStatusTrayIcon() OVERRIDE { have_status_tray_ = false; }
  virtual int GetBackgroundAppCount() const OVERRIDE { return app_count_; }
  virtual int GetBackgroundAppCountForProfile(
      Profile* const profile) const OVERRIDE {
    return profile_app_count_;
  }
  virtual bool IsBackgroundModePrefEnabled() const OVERRIDE { return enabled_; }
  void SetBackgroundAppCount(int count) { app_count_ = count; }
  void SetBackgroundAppCountForProfile(int count) {
    profile_app_count_ = count;
  }
  void SetEnabled(bool enabled) {
    enabled_ = enabled;
    OnBackgroundModeEnabledPrefChanged();
  }
  bool HaveStatusTray() const { return have_status_tray_; }
  bool IsLaunchOnStartup() const { return launch_on_startup_; }
 private:
  bool enabled_;
  int app_count_;
  int profile_app_count_;

  // Flags to track whether we are launching on startup/have a status tray.
  bool have_status_tray_;
  bool launch_on_startup_;
};

class TestStatusIcon : public StatusIcon {
  virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE {}
  virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE {}
  virtual void SetToolTip(const base::string16& tool_tip) OVERRIDE {}
  virtual void DisplayBalloon(const gfx::ImageSkia& icon,
                              const base::string16& title,
                              const base::string16& contents) OVERRIDE {}
  virtual void UpdatePlatformContextMenu(
      StatusIconMenuModel* menu) OVERRIDE {}
};

static void AssertBackgroundModeActive(
    const TestBackgroundModeManager& manager) {
  EXPECT_TRUE(chrome::WillKeepAlive());
  EXPECT_TRUE(manager.HaveStatusTray());
  EXPECT_TRUE(manager.IsLaunchOnStartup());
}

static void AssertBackgroundModeInactive(
    const TestBackgroundModeManager& manager) {
  EXPECT_FALSE(chrome::WillKeepAlive());
  EXPECT_FALSE(manager.HaveStatusTray());
  EXPECT_FALSE(manager.IsLaunchOnStartup());
}

static void AssertBackgroundModeSuspended(
    const TestBackgroundModeManager& manager) {
  EXPECT_FALSE(chrome::WillKeepAlive());
  EXPECT_FALSE(manager.HaveStatusTray());
  EXPECT_TRUE(manager.IsLaunchOnStartup());
}

TEST_F(BackgroundModeManagerTest, BackgroundAppLoadUnload) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile = profile_manager->CreateTestingProfile("p1");
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile);
  EXPECT_FALSE(chrome::WillKeepAlive());

  // Mimic app load.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.OnApplicationListChanged(profile);
  AssertBackgroundModeActive(manager);

  manager.SuspendBackgroundMode();
  AssertBackgroundModeSuspended(manager);
  manager.ResumeBackgroundMode();

  // Mimic app unload.
  manager.SetBackgroundAppCount(0);
  manager.OnApplicationListChanged(profile);
  AssertBackgroundModeInactive(manager);

  manager.SuspendBackgroundMode();
  AssertBackgroundModeInactive(manager);

  // Mimic app load while suspended, e.g. from sync. This should enable and
  // resume background mode.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.OnApplicationListChanged(profile);
  AssertBackgroundModeActive(manager);
}

// App installs while background mode is disabled should do nothing.
TEST_F(BackgroundModeManagerTest, BackgroundAppInstallUninstallWhileDisabled) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile = profile_manager->CreateTestingProfile("p1");
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile);
  // Turn off background mode.
  manager.SetEnabled(false);
  manager.DisableBackgroundMode();
  AssertBackgroundModeInactive(manager);

  // Status tray icons will not be created, launch on startup status will not
  // be modified.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.OnApplicationListChanged(profile);
  AssertBackgroundModeInactive(manager);

  manager.SetBackgroundAppCount(0);
  manager.OnApplicationListChanged(profile);
  AssertBackgroundModeInactive(manager);

  // Re-enable background mode.
  manager.SetEnabled(true);
  manager.EnableBackgroundMode();
  AssertBackgroundModeInactive(manager);
}


// App installs while disabled should do nothing until background mode is
// enabled..
TEST_F(BackgroundModeManagerTest, EnableAfterBackgroundAppInstall) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile = profile_manager->CreateTestingProfile("p1");
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile);

  // Install app, should show status tray icon.
  manager.OnBackgroundAppInstalled(NULL);
  // OnBackgroundAppInstalled does not actually add an app to the
  // BackgroundApplicationListModel which would result in another
  // call to CreateStatusTray.
  manager.SetBackgroundAppCount(1);
  manager.OnApplicationListChanged(profile);
  AssertBackgroundModeActive(manager);

  // Turn off background mode - should hide status tray icon.
  manager.SetEnabled(false);
  manager.DisableBackgroundMode();
  AssertBackgroundModeInactive(manager);

  // Turn back on background mode - again, no status tray icon
  // will show up since we didn't actually add anything to the list.
  manager.SetEnabled(true);
  manager.EnableBackgroundMode();
  AssertBackgroundModeActive(manager);

  // Uninstall app, should hide status tray icon again.
  manager.SetBackgroundAppCount(0);
  manager.OnApplicationListChanged(profile);
  AssertBackgroundModeInactive(manager);
}

TEST_F(BackgroundModeManagerTest, MultiProfile) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile1 = profile_manager->CreateTestingProfile("p1");
  TestingProfile* profile2 = profile_manager->CreateTestingProfile("p2");
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile1);
  manager.RegisterProfile(profile2);
  EXPECT_FALSE(chrome::WillKeepAlive());

  // Install app, should show status tray icon.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.OnApplicationListChanged(profile1);
  AssertBackgroundModeActive(manager);

  // Install app for other profile, hsould show other status tray icon.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(2);
  manager.OnApplicationListChanged(profile2);
  AssertBackgroundModeActive(manager);

  // Should hide both status tray icons.
  manager.SetEnabled(false);
  manager.DisableBackgroundMode();
  AssertBackgroundModeInactive(manager);

  // Turn back on background mode - should show both status tray icons.
  manager.SetEnabled(true);
  manager.EnableBackgroundMode();
  AssertBackgroundModeActive(manager);

  manager.SetBackgroundAppCount(1);
  manager.OnApplicationListChanged(profile2);
  // There is still one background app alive
  AssertBackgroundModeActive(manager);

  manager.SetBackgroundAppCount(0);
  manager.OnApplicationListChanged(profile1);
  AssertBackgroundModeInactive(manager);
}

TEST_F(BackgroundModeManagerTest, ProfileInfoCacheStorage) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile1 = profile_manager->CreateTestingProfile("p1");
  TestingProfile* profile2 = profile_manager->CreateTestingProfile("p2");
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile1);
  manager.RegisterProfile(profile2);
  EXPECT_FALSE(chrome::WillKeepAlive());

  ProfileInfoCache* cache = profile_manager->profile_info_cache();
  EXPECT_EQ(2u, cache->GetNumberOfProfiles());

  EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(0));
  EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(1));

  // Install app, should show status tray icon.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.SetBackgroundAppCountForProfile(1);
  manager.OnApplicationListChanged(profile1);

  // Install app for other profile.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.SetBackgroundAppCountForProfile(1);
  manager.OnApplicationListChanged(profile2);

  EXPECT_TRUE(cache->GetBackgroundStatusOfProfileAtIndex(0));
  EXPECT_TRUE(cache->GetBackgroundStatusOfProfileAtIndex(1));

  manager.SetBackgroundAppCountForProfile(0);
  manager.OnApplicationListChanged(profile1);

  size_t p1_index = cache->GetIndexOfProfileWithPath(profile1->GetPath());
  EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(p1_index));

  manager.SetBackgroundAppCountForProfile(0);
  manager.OnApplicationListChanged(profile2);

  size_t p2_index = cache->GetIndexOfProfileWithPath(profile1->GetPath());
  EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(p2_index));

  // Even though neither has background status on, there should still be two
  // profiles in the cache.
  EXPECT_EQ(2u, cache->GetNumberOfProfiles());
}

TEST_F(BackgroundModeManagerTest, ProfileInfoCacheObserver) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile1 = profile_manager->CreateTestingProfile("p1");
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile1);
  EXPECT_FALSE(chrome::WillKeepAlive());

  // Install app, should show status tray icon.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.SetBackgroundAppCountForProfile(1);
  manager.OnApplicationListChanged(profile1);

  manager.OnProfileNameChanged(
      profile1->GetPath(),
      manager.GetBackgroundModeData(profile1)->name());

  EXPECT_EQ(base::UTF8ToUTF16("p1"),
            manager.GetBackgroundModeData(profile1)->name());

  EXPECT_TRUE(chrome::WillKeepAlive());
  TestingProfile* profile2 = profile_manager->CreateTestingProfile("p2");
  manager.RegisterProfile(profile2);
  EXPECT_EQ(2, manager.NumberOfBackgroundModeData());

  manager.OnProfileAdded(profile2->GetPath());
  EXPECT_EQ(base::UTF8ToUTF16("p2"),
            manager.GetBackgroundModeData(profile2)->name());

  manager.OnProfileWillBeRemoved(profile2->GetPath());
  // Should still be in background mode after deleting profile.
  EXPECT_TRUE(chrome::WillKeepAlive());
  EXPECT_EQ(1, manager.NumberOfBackgroundModeData());

  // Check that the background mode data we think is in the map actually is.
  EXPECT_EQ(base::UTF8ToUTF16("p1"),
            manager.GetBackgroundModeData(profile1)->name());
}

TEST_F(BackgroundModeManagerTest, DeleteBackgroundProfile) {
  // Tests whether deleting the only profile when it is a BG profile works
  // or not (http://crbug.com/346214).
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile = profile_manager->CreateTestingProfile("p1");
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile);
  EXPECT_FALSE(chrome::WillKeepAlive());

  // Install app, should show status tray icon.
  manager.OnBackgroundAppInstalled(NULL);
  manager.SetBackgroundAppCount(1);
  manager.SetBackgroundAppCountForProfile(1);
  manager.OnApplicationListChanged(profile);

  manager.OnProfileNameChanged(
      profile->GetPath(),
      manager.GetBackgroundModeData(profile)->name());

  EXPECT_TRUE(chrome::WillKeepAlive());
  manager.SetBackgroundAppCount(0);
  manager.SetBackgroundAppCountForProfile(0);
  manager.OnProfileWillBeRemoved(profile->GetPath());
  EXPECT_FALSE(chrome::WillKeepAlive());
}

TEST_F(BackgroundModeManagerTest, DisableBackgroundModeUnderTestFlag) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile1 = profile_manager->CreateTestingProfile("p1");
  command_line_->AppendSwitch(switches::kKeepAliveForTest);
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), true);
  manager.RegisterProfile(profile1);
  EXPECT_TRUE(manager.ShouldBeInBackgroundMode());
  manager.SetEnabled(false);
  EXPECT_FALSE(manager.ShouldBeInBackgroundMode());
}

TEST_F(BackgroundModeManagerTest,
       BackgroundModeDisabledPreventsKeepAliveOnStartup) {
  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();
  TestingProfile* profile1 = profile_manager->CreateTestingProfile("p1");
  command_line_->AppendSwitch(switches::kKeepAliveForTest);
  TestBackgroundModeManager manager(
      command_line_.get(), profile_manager->profile_info_cache(), false);
  manager.RegisterProfile(profile1);
  EXPECT_FALSE(manager.ShouldBeInBackgroundMode());
}

TEST_F(BackgroundModeManagerTest, BackgroundMenuGeneration) {
  // Aura clears notifications from the message center at shutdown.
  message_center::MessageCenter::Initialize();

  // Required for extension service.
  content::TestBrowserThreadBundle thread_bundle;

  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();

  // BackgroundModeManager actually affects Chrome start/stop state,
  // tearing down our thread bundle before we've had chance to clean
  // everything up. Keeping Chrome alive prevents this.
  // We aren't interested in if the keep alive works correctly in this test.
  chrome::IncrementKeepAliveCount();
  TestingProfile* profile = profile_manager->CreateTestingProfile("p");

#if defined(OS_CHROMEOS)
  // ChromeOS needs extra services to run in the following order.
  chromeos::ScopedTestDeviceSettingsService test_device_settings_service;
  chromeos::ScopedTestCrosSettings test_cros_settings;
  chromeos::ScopedTestUserManager test_user_manager;

  // On ChromeOS shutdown, HandleAppExitingForPlatform will call
  // chrome::DecrementKeepAliveCount because it assumes the aura shell
  // called chrome::IncrementKeepAliveCount. Simulate the call here.
  chrome::IncrementKeepAliveCount();
#endif

  scoped_refptr<extensions::Extension> component_extension(
    CreateExtension(
        extensions::Manifest::COMPONENT,
        "{\"name\": \"Component Extension\","
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"]}",
        "ID-1"));

  scoped_refptr<extensions::Extension> component_extension_with_options(
    CreateExtension(
        extensions::Manifest::COMPONENT,
        "{\"name\": \"Component Extension with Options\","
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"],"
        "\"options_page\": \"test.html\"}",
        "ID-2"));

  scoped_refptr<extensions::Extension> regular_extension(
    CreateExtension(
        extensions::Manifest::COMMAND_LINE,
        "{\"name\": \"Regular Extension\", "
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"]}",
        "ID-3"));

  scoped_refptr<extensions::Extension> regular_extension_with_options(
    CreateExtension(
        extensions::Manifest::COMMAND_LINE,
        "{\"name\": \"Regular Extension with Options\","
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"],"
        "\"options_page\": \"test.html\"}",
        "ID-4"));

  static_cast<extensions::TestExtensionSystem*>(
      extensions::ExtensionSystem::Get(profile))->CreateExtensionService(
          CommandLine::ForCurrentProcess(),
          base::FilePath(),
          false);
  ExtensionService* service = profile->GetExtensionService();
  service->Init();

  service->AddComponentExtension(component_extension);
  service->AddComponentExtension(component_extension_with_options);
  service->AddExtension(regular_extension);
  service->AddExtension(regular_extension_with_options);

  scoped_ptr<TestBackgroundModeManager> manager(new TestBackgroundModeManager(
      command_line_.get(), profile_manager->profile_info_cache(), true));
  manager->RegisterProfile(profile);

  scoped_ptr<StatusIconMenuModel> menu(new StatusIconMenuModel(NULL));
  scoped_ptr<StatusIconMenuModel> submenu(new StatusIconMenuModel(NULL));
  BackgroundModeManager::BackgroundModeData* bmd =
      manager->GetBackgroundModeData(profile);
  bmd->BuildProfileMenu(submenu.get(), menu.get());
  EXPECT_TRUE(
      submenu->GetLabelAt(0) ==
          base::UTF8ToUTF16("Component Extension"));
  EXPECT_FALSE(submenu->IsCommandIdEnabled(submenu->GetCommandIdAt(0)));
  EXPECT_TRUE(
      submenu->GetLabelAt(1) ==
          base::UTF8ToUTF16("Component Extension with Options"));
  EXPECT_TRUE(submenu->IsCommandIdEnabled(submenu->GetCommandIdAt(1)));
  EXPECT_TRUE(
      submenu->GetLabelAt(2) ==
          base::UTF8ToUTF16("Regular Extension"));
  EXPECT_TRUE(submenu->IsCommandIdEnabled(submenu->GetCommandIdAt(2)));
  EXPECT_TRUE(
      submenu->GetLabelAt(3) ==
          base::UTF8ToUTF16("Regular Extension with Options"));
  EXPECT_TRUE(submenu->IsCommandIdEnabled(submenu->GetCommandIdAt(3)));

  // We have to destroy the profile now because we created it with real thread
  // state. This causes a lot of machinery to spin up that stops working
  // when we tear down our thread state at the end of the test.
  profile_manager->DeleteTestingProfile("p");

  // We're getting ready to shutdown the message loop. Clear everything out!
  base::MessageLoop::current()->RunUntilIdle();
  chrome::DecrementKeepAliveCount();  // Matching the above
                                      // chrome::IncrementKeepAliveCount().

  // TestBackgroundModeManager has dependencies on the infrastructure.
  // It should get cleared first.
  manager.reset();

  // The Profile Manager references the Browser Process.
  // The Browser Process references the Notification UI Manager.
  // The Notification UI Manager references the Message Center.
  // As a result, we have to clear the browser process state here
  // before tearing down the Message Center.
  profile_manager.reset();

  // Message Center shutdown must occur after the DecrementKeepAliveCount
  // because DecrementKeepAliveCount will end up referencing the message
  // center during cleanup.
  message_center::MessageCenter::Shutdown();

  // Clear the shutdown flag to isolate the remaining effect of this test.
  browser_shutdown::SetTryingToQuit(false);
}

TEST_F(BackgroundModeManagerTest, BackgroundMenuGenerationMultipleProfile) {
  // Aura clears notifications from the message center at shutdown.
  message_center::MessageCenter::Initialize();

  // Required for extension service.
  content::TestBrowserThreadBundle thread_bundle;

  scoped_ptr<TestingProfileManager> profile_manager =
      CreateTestingProfileManager();

  // BackgroundModeManager actually affects Chrome start/stop state,
  // tearing down our thread bundle before we've had chance to clean
  // everything up. Keeping Chrome alive prevents this.
  // We aren't interested in if the keep alive works correctly in this test.
  chrome::IncrementKeepAliveCount();
  TestingProfile* profile1 = profile_manager->CreateTestingProfile("p1");
  TestingProfile* profile2 = profile_manager->CreateTestingProfile("p2");

#if defined(OS_CHROMEOS)
  // ChromeOS needs extensionsra services to run in the following order.
  chromeos::ScopedTestDeviceSettingsService test_device_settings_service;
  chromeos::ScopedTestCrosSettings test_cros_settings;
  chromeos::ScopedTestUserManager test_user_manager;

  // On ChromeOS shutdown, HandleAppExitingForPlatform will call
  // chrome::DecrementKeepAliveCount because it assumes the aura shell
  // called chrome::IncrementKeepAliveCount. Simulate the call here.
  chrome::IncrementKeepAliveCount();
#endif

  scoped_refptr<extensions::Extension> component_extension(
    CreateExtension(
        extensions::Manifest::COMPONENT,
        "{\"name\": \"Component Extension\","
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"]}",
        "ID-1"));

  scoped_refptr<extensions::Extension> component_extension_with_options(
    CreateExtension(
        extensions::Manifest::COMPONENT,
        "{\"name\": \"Component Extension with Options\","
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"],"
        "\"options_page\": \"test.html\"}",
        "ID-2"));

  scoped_refptr<extensions::Extension> regular_extension(
    CreateExtension(
        extensions::Manifest::COMMAND_LINE,
        "{\"name\": \"Regular Extension\", "
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"]}",
        "ID-3"));

  scoped_refptr<extensions::Extension> regular_extension_with_options(
    CreateExtension(
        extensions::Manifest::COMMAND_LINE,
        "{\"name\": \"Regular Extension with Options\","
        "\"version\": \"1.0\","
        "\"manifest_version\": 2,"
        "\"permissions\": [\"background\"],"
        "\"options_page\": \"test.html\"}",
        "ID-4"));

  static_cast<extensions::TestExtensionSystem*>(
      extensions::ExtensionSystem::Get(profile1))->CreateExtensionService(
          CommandLine::ForCurrentProcess(),
          base::FilePath(),
          false);
  ExtensionService* service1 = profile1->GetExtensionService();
  service1->Init();

  service1->AddComponentExtension(component_extension);
  service1->AddComponentExtension(component_extension_with_options);
  service1->AddExtension(regular_extension);
  service1->AddExtension(regular_extension_with_options);

  static_cast<extensions::TestExtensionSystem*>(
      extensions::ExtensionSystem::Get(profile2))->CreateExtensionService(
          CommandLine::ForCurrentProcess(),
          base::FilePath(),
          false);
  ExtensionService* service2 = profile2->GetExtensionService();
  service2->Init();

  service2->AddComponentExtension(component_extension);
  service2->AddExtension(regular_extension);
  service2->AddExtension(regular_extension_with_options);

  scoped_ptr<TestBackgroundModeManager> manager(new TestBackgroundModeManager(
      command_line_.get(), profile_manager->profile_info_cache(), true));
  manager->RegisterProfile(profile1);
  manager->RegisterProfile(profile2);

  manager->status_icon_ = new TestStatusIcon();
  manager->UpdateStatusTrayIconContextMenu();
  StatusIconMenuModel* context_menu = manager->context_menu_;
  EXPECT_TRUE(context_menu != NULL);

  // Background Profile Enable Checks
  EXPECT_TRUE(context_menu->GetLabelAt(3) == base::UTF8ToUTF16("p1"));
  EXPECT_TRUE(
      context_menu->IsCommandIdEnabled(context_menu->GetCommandIdAt(3)));
  EXPECT_TRUE(context_menu->GetCommandIdAt(3) == 4);

  EXPECT_TRUE(context_menu->GetLabelAt(4) == base::UTF8ToUTF16("p2"));
  EXPECT_TRUE(
      context_menu->IsCommandIdEnabled(context_menu->GetCommandIdAt(4)));
  EXPECT_TRUE(context_menu->GetCommandIdAt(4) == 8);

  // Profile 1 Submenu Checks
  StatusIconMenuModel* profile1_submenu =
      static_cast<StatusIconMenuModel*>(context_menu->GetSubmenuModelAt(3));
  EXPECT_TRUE(
      profile1_submenu->GetLabelAt(0) ==
          base::UTF8ToUTF16("Component Extension"));
  EXPECT_FALSE(
      profile1_submenu->IsCommandIdEnabled(
          profile1_submenu->GetCommandIdAt(0)));
  EXPECT_TRUE(profile1_submenu->GetCommandIdAt(0) == 0);
  EXPECT_TRUE(
      profile1_submenu->GetLabelAt(1) ==
          base::UTF8ToUTF16("Component Extension with Options"));
  EXPECT_TRUE(
      profile1_submenu->IsCommandIdEnabled(
          profile1_submenu->GetCommandIdAt(1)));
  EXPECT_TRUE(profile1_submenu->GetCommandIdAt(1) == 1);
  EXPECT_TRUE(
      profile1_submenu->GetLabelAt(2) ==
          base::UTF8ToUTF16("Regular Extension"));
  EXPECT_TRUE(
      profile1_submenu->IsCommandIdEnabled(
          profile1_submenu->GetCommandIdAt(2)));
  EXPECT_TRUE(profile1_submenu->GetCommandIdAt(2) == 2);
  EXPECT_TRUE(
      profile1_submenu->GetLabelAt(3) ==
          base::UTF8ToUTF16("Regular Extension with Options"));
  EXPECT_TRUE(
      profile1_submenu->IsCommandIdEnabled(
          profile1_submenu->GetCommandIdAt(3)));
  EXPECT_TRUE(profile1_submenu->GetCommandIdAt(3) == 3);

  // Profile 2 Submenu Checks
  StatusIconMenuModel* profile2_submenu =
      static_cast<StatusIconMenuModel*>(context_menu->GetSubmenuModelAt(4));
  EXPECT_TRUE(
      profile2_submenu->GetLabelAt(0) ==
          base::UTF8ToUTF16("Component Extension"));
  EXPECT_FALSE(
      profile2_submenu->IsCommandIdEnabled(
          profile2_submenu->GetCommandIdAt(0)));
  EXPECT_TRUE(profile2_submenu->GetCommandIdAt(0) == 5);
  EXPECT_TRUE(
      profile2_submenu->GetLabelAt(1) ==
          base::UTF8ToUTF16("Regular Extension"));
  EXPECT_TRUE(
      profile2_submenu->IsCommandIdEnabled(
          profile2_submenu->GetCommandIdAt(1)));
  EXPECT_TRUE(profile2_submenu->GetCommandIdAt(1) == 6);
  EXPECT_TRUE(
      profile2_submenu->GetLabelAt(2) ==
          base::UTF8ToUTF16("Regular Extension with Options"));
  EXPECT_TRUE(
      profile2_submenu->IsCommandIdEnabled(
          profile2_submenu->GetCommandIdAt(2)));
  EXPECT_TRUE(profile2_submenu->GetCommandIdAt(2) == 7);

  // Model Adapter Checks for crbug.com/315164
  // P1: Profile 1 Menu Item
  // P2: Profile 2 Menu Item
  // CE: Component Extension Menu Item
  // CEO: Component Extenison with Options Menu Item
  // RE: Regular Extension Menu Item
  // REO: Regular Extension with Options Menu Item
  EXPECT_FALSE(IsCommandEnabled(context_menu, 0)); // P1 - CE
  EXPECT_TRUE(IsCommandEnabled(context_menu, 1));  // P1 - CEO
  EXPECT_TRUE(IsCommandEnabled(context_menu, 2));  // P1 - RE
  EXPECT_TRUE(IsCommandEnabled(context_menu, 3));  // P1 - REO
  EXPECT_TRUE(IsCommandEnabled(context_menu, 4));  // P1
  EXPECT_FALSE(IsCommandEnabled(context_menu, 5)); // P2 - CE
  EXPECT_TRUE(IsCommandEnabled(context_menu, 6));  // P2 - RE
  EXPECT_TRUE(IsCommandEnabled(context_menu, 7));  // P2 - REO
  EXPECT_TRUE(IsCommandEnabled(context_menu, 8));  // P2

  // Clean up the status icon. If this is not done before profile deletes,
  // the context menu updates will DCHECK with the now deleted profiles.
  StatusIcon* status_icon = manager->status_icon_;
  manager->status_icon_ = NULL;
  delete status_icon;

  // We have to destroy the profiles now because we created them with real
  // thread state. This causes a lot of machinery to spin up that stops working
  // when we tear down our thread state at the end of the test.
  profile_manager->DeleteTestingProfile("p2");
  profile_manager->DeleteTestingProfile("p1");

  // We're getting ready to shutdown the message loop. Clear everything out!
  base::MessageLoop::current()->RunUntilIdle();
  chrome::DecrementKeepAliveCount();  // Matching the above
                                      // chrome::IncrementKeepAliveCount().

  // TestBackgroundModeManager has dependencies on the infrastructure.
  // It should get cleared first.
  manager.reset();

  // The Profile Manager references the Browser Process.
  // The Browser Process references the Notification UI Manager.
  // The Notification UI Manager references the Message Center.
  // As a result, we have to clear the browser process state here
  // before tearing down the Message Center.
  profile_manager.reset();

  // Message Center shutdown must occur after the DecrementKeepAliveCount
  // because DecrementKeepAliveCount will end up referencing the message
  // center during cleanup.
  message_center::MessageCenter::Shutdown();

  // Clear the shutdown flag to isolate the remaining effect of this test.
  browser_shutdown::SetTryingToQuit(false);
}
