// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/power/renderer_freezer.h"

#include <memory>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_system.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 "chromeos/dbus/power/fake_power_manager_client.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "content/public/browser/site_instance.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/mock_render_process_host.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_map.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "testing/gtest/include/gtest/gtest-death-test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash {

namespace {
// Class that delegates used in testing can inherit from to record calls that
// are made by the code being tested.
class ActionRecorder {
 public:
  ActionRecorder() = default;

  ActionRecorder(const ActionRecorder&) = delete;
  ActionRecorder& operator=(const ActionRecorder&) = delete;

  virtual ~ActionRecorder() = default;

  // Returns a comma-separated string describing the actions that were
  // requested since the previous call to GetActions() (i.e. results are
  // non-repeatable).
  std::string GetActions() {
    std::string actions = actions_;
    actions_.clear();
    return actions;
  }

 protected:
  // Appends |new_action| to |actions_|, using a comma as a separator if
  // other actions are already listed.
  void AppendAction(const std::string& new_action) {
    if (!actions_.empty())
      actions_ += ",";
    actions_ += new_action;
  }

 private:
  // Comma-separated list of actions that have been performed.
  std::string actions_;
};

// Actions that can be returned by TestDelegate::GetActions().
const char kSetShouldFreezeRenderer[] = "set_should_freeze_renderer";
const char kSetShouldNotFreezeRenderer[] = "set_should_not_freeze_renderer";
const char kFreezeRenderers[] = "freeze_renderers";
const char kThawRenderers[] = "thaw_renderers";
const char kNoActions[] = "";

// Test implementation of RendererFreezer::Delegate that records the actions it
// was asked to perform.
class TestDelegate : public RendererFreezer::Delegate, public ActionRecorder {
 public:
  TestDelegate()
      : can_freeze_renderers_(true),
        thaw_renderers_result_(true) {}

  TestDelegate(const TestDelegate&) = delete;
  TestDelegate& operator=(const TestDelegate&) = delete;

  ~TestDelegate() override = default;

  // RendererFreezer::Delegate overrides.
  void SetShouldFreezeRenderer(base::ProcessHandle handle,
                               bool frozen) override {
    AppendAction(frozen ? kSetShouldFreezeRenderer
                        : kSetShouldNotFreezeRenderer);
  }
  void FreezeRenderers() override {
    AppendAction(kFreezeRenderers);
  }
  void ThawRenderers(ResultCallback callback) override {
    AppendAction(kThawRenderers);

    std::move(callback).Run(thaw_renderers_result_);
  }
  void CheckCanFreezeRenderers(ResultCallback callback) override {
    std::move(callback).Run(can_freeze_renderers_);
  }

  void set_thaw_renderers_result(bool result) {
    thaw_renderers_result_ = result;
  }

  // Sets whether the delegate is capable of freezing renderers.  This also
  // changes |freeze_renderers_result_| and |thaw_renderers_result_|.
  void set_can_freeze_renderers(bool can_freeze) {
    can_freeze_renderers_ = can_freeze;

    thaw_renderers_result_ = can_freeze;
  }

 private:
  bool can_freeze_renderers_;
  bool thaw_renderers_result_;
};

}  // namespace

class RendererFreezerTest : public testing::Test {
 public:
  RendererFreezerTest() : test_delegate_(new TestDelegate()) {}

  RendererFreezerTest(const RendererFreezerTest&) = delete;
  RendererFreezerTest& operator=(const RendererFreezerTest&) = delete;

  ~RendererFreezerTest() override = default;

  // testing::Test:
  void SetUp() override { chromeos::PowerManagerClient::InitializeFake(); }

  void TearDown() override {
    DCHECK(renderer_freezer_);
    chromeos::PowerManagerClient::Shutdown();
    renderer_freezer_.reset();
  }

  void SimulateRenderProcessHostCreated(content::RenderProcessHost* rph) {
    renderer_freezer_->OnRenderProcessHostCreated(rph);
    renderer_freezer_->OnRenderProcessLaunched(rph);
  }

 protected:
  void Init() {
    renderer_freezer_ = std::make_unique<RendererFreezer>(
        std::unique_ptr<RendererFreezer::Delegate>(test_delegate_));
  }

  // Owned by |renderer_freezer_|.
  raw_ptr<TestDelegate, DanglingUntriaged> test_delegate_;
  std::unique_ptr<RendererFreezer> renderer_freezer_;

 private:
  content::BrowserTaskEnvironment task_environment_;
};

// Tests that the RendererFreezer freezes renderers on suspend and thaws them on
// resume.
TEST_F(RendererFreezerTest, SuspendResume) {
  Init();

  chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
      power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions());

  // The renderers should be thawed when we resume.
  chromeos::FakePowerManagerClient::Get()->SendSuspendDone();
  EXPECT_EQ(kThawRenderers, test_delegate_->GetActions());
}

// Tests that the renderer freezer does nothing if the delegate cannot freeze
// renderers.
TEST_F(RendererFreezerTest, DelegateCannotFreezeRenderers) {
  test_delegate_->set_can_freeze_renderers(false);
  Init();

  // Nothing happens on suspend.
  chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
      power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(kNoActions, test_delegate_->GetActions());

  // Nothing happens on resume.
  chromeos::FakePowerManagerClient::Get()->SendSuspendDone();
  EXPECT_EQ(kNoActions, test_delegate_->GetActions());
}

#if defined(GTEST_HAS_DEATH_TEST)
// Tests that the RendererFreezer crashes the browser if the freezing operation
// was successful but the thawing operation failed.
TEST_F(RendererFreezerTest, ErrorThawingRenderers) {
  // The "threadsafe" style of death test re-executes the unit test binary,
  // which in turn re-initializes some global state leading to failed CHECKs.
  // Instead, we use the "fast" style here to prevent re-initialization.
  GTEST_FLAG_SET(death_test_style, "fast");
  Init();
  test_delegate_->set_thaw_renderers_result(false);

  chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
      power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions());

  EXPECT_DEATH(chromeos::FakePowerManagerClient::Get()->SendSuspendDone(),
               "Unable to thaw");
}
#endif  // GTEST_HAS_DEATH_TEST

class RendererFreezerTestWithExtensions : public RendererFreezerTest {
 public:
  RendererFreezerTestWithExtensions() = default;

  RendererFreezerTestWithExtensions(const RendererFreezerTestWithExtensions&) =
      delete;
  RendererFreezerTestWithExtensions& operator=(
      const RendererFreezerTestWithExtensions&) = delete;

  ~RendererFreezerTestWithExtensions() override = default;

  // testing::Test overrides.
  void SetUp() override {
    RendererFreezerTest::SetUp();

    profile_manager_ = std::make_unique<TestingProfileManager>(
        TestingBrowserProcess::GetGlobal());

    // Must be called from testing::Test::SetUp.
    EXPECT_TRUE(profile_manager_->SetUp());

    profile_ = profile_manager_->CreateTestingProfile("RendererFreezerTest");

    extensions::TestExtensionSystem* extension_system =
        static_cast<extensions::TestExtensionSystem*>(
            extensions::ExtensionSystem::Get(profile_));
    extension_system->CreateExtensionService(
        base::CommandLine::ForCurrentProcess(),
        base::FilePath() /* install_directory */,
        false /* autoupdate_enabled*/);
  }
  void TearDown() override {
    profile_ = nullptr;

    profile_manager_->DeleteAllTestingProfiles();

    base::RunLoop().RunUntilIdle();

    profile_manager_.reset();

    RendererFreezerTest::TearDown();
  }

 protected:
  void CreateRenderProcessForExtension(const extensions::Extension* extension) {
    std::unique_ptr<content::MockRenderProcessHostFactory> rph_factory(
        new content::MockRenderProcessHostFactory());
    content::RenderProcessHost* rph = rph_factory->CreateRenderProcessHost(
        profile_, /*site_instance=*/nullptr);

    // Fake that the RenderProcessHost is hosting the gcm app.
    extensions::ProcessMap::Get(profile_)->Insert(extension->id(),
                                                  rph->GetDeprecatedID());

    SimulateRenderProcessHostCreated(rph);
  }

  // Owned by |profile_manager_|.
  raw_ptr<TestingProfile> profile_;
  std::unique_ptr<TestingProfileManager> profile_manager_;

 private:
  // Chrome OS needs the CrosSettings test helper.
  ScopedCrosSettingsTestHelper cros_settings_test_helper_;
};

// Tests that the RendererFreezer freezes renderers that are not hosting
// GCM extensions.
TEST_F(RendererFreezerTestWithExtensions, FreezesNonExtensionRenderers) {
  Init();

  // Create the mock RenderProcessHost.
  std::unique_ptr<content::MockRenderProcessHostFactory> rph_factory(
      new content::MockRenderProcessHostFactory());
  scoped_refptr<content::SiteInstance> site_instance(
      content::SiteInstance::Create(profile_));
  content::RenderProcessHost* rph =
      rph_factory->CreateRenderProcessHost(profile_, site_instance.get());

  SimulateRenderProcessHostCreated(rph);

  EXPECT_EQ(kSetShouldFreezeRenderer, test_delegate_->GetActions());
}

// Tests that the RendererFreezer does not freeze renderers that are hosting
// extensions that use GCM.
TEST_F(RendererFreezerTestWithExtensions, DoesNotFreezeGcmExtensionRenderers) {
  Init();

  // First build the GCM extension.
  scoped_refptr<const extensions::Extension> gcm_app =
      extensions::ExtensionBuilder()
          .SetManifest(
              base::Value::Dict()
                  .Set("name", "GCM App")
                  .Set("version", "1.0.0")
                  .Set("manifest_version", 2)
                  .Set("app", base::Value::Dict().Set(
                                  "background",
                                  base::Value::Dict().Set(
                                      "scripts", base::Value::List().Append(
                                                     "background.js"))))
                  .Set("permissions", base::Value::List().Append("gcm")))
          .Build();

  // Now install it and give it a renderer.
  extensions::ExtensionRegistrar::Get(profile_)->AddExtension(gcm_app.get());
  CreateRenderProcessForExtension(gcm_app.get());

  EXPECT_EQ(kSetShouldNotFreezeRenderer, test_delegate_->GetActions());
}

// Tests that the RendererFreezer freezes renderers that are hosting extensions
// that do not use GCM.
TEST_F(RendererFreezerTestWithExtensions, FreezesNonGcmExtensionRenderers) {
  Init();

  // First build the extension.
  scoped_refptr<const extensions::Extension> background_app =
      extensions::ExtensionBuilder()
          .SetManifest(
              base::Value::Dict()
                  .Set("name", "Background App")
                  .Set("version", "1.0.0")
                  .Set("manifest_version", 2)
                  .Set("app", base::Value::Dict().Set(
                                  "background",
                                  base::Value::Dict().Set(
                                      "scripts", base::Value::List().Append(
                                                     "background.js")))))
          .Build();

  // Now install it and give it a renderer.
  extensions::ExtensionRegistrar::Get(profile_)->AddExtension(
      background_app.get());
  CreateRenderProcessForExtension(background_app.get());

  EXPECT_EQ(kSetShouldFreezeRenderer, test_delegate_->GetActions());
}

}  // namespace ash
