// Copyright 2017 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/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/utility_process_host.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_service_registry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/common/power_monitor_test.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/device/public/mojom/power_monitor.mojom.h"
#include "services/service_manager/public/cpp/service_binding.h"

namespace content {

namespace {

void VerifyPowerStateInChildProcess(mojom::PowerMonitorTest* power_monitor_test,
                                    bool expected_state) {
  base::RunLoop run_loop;
  power_monitor_test->QueryNextState(base::BindOnce(
      [](const base::Closure& quit, bool expected_state,
         bool on_battery_power) {
        EXPECT_EQ(expected_state, on_battery_power);
        quit.Run();
      },
      run_loop.QuitClosure(), expected_state));
  run_loop.Run();
}

void StartUtilityProcessOnIOThread(mojom::PowerMonitorTestRequest request) {
  UtilityProcessHost* host = new UtilityProcessHost();
  host->SetMetricsName("test_process");
  host->SetName(base::ASCIIToUTF16("TestProcess"));
  EXPECT_TRUE(host->Start());

  BindInterface(host, std::move(request));
}

void BindInterfaceForGpuOnIOThread(mojom::PowerMonitorTestRequest request) {
  BindInterfaceInGpuProcess(std::move(request));
}

class MockPowerMonitorMessageBroadcaster : public device::mojom::PowerMonitor {
 public:
  MockPowerMonitorMessageBroadcaster() = default;
  ~MockPowerMonitorMessageBroadcaster() override = default;

  void Bind(device::mojom::PowerMonitorRequest request) {
    bindings_.AddBinding(this, std::move(request));
  }

  // device::mojom::PowerMonitor:
  void AddClient(
      device::mojom::PowerMonitorClientPtr power_monitor_client) override {
    power_monitor_client->PowerStateChange(on_battery_power_);
    clients_.AddPtr(std::move(power_monitor_client));
  }

  void OnPowerStateChange(bool on_battery_power) {
    on_battery_power_ = on_battery_power;
    clients_.ForAllPtrs(
        [&on_battery_power](device::mojom::PowerMonitorClient* client) {
          client->PowerStateChange(on_battery_power);
        });
  }

 private:
  bool on_battery_power_ = false;

  mojo::BindingSet<device::mojom::PowerMonitor> bindings_;
  mojo::InterfacePtrSet<device::mojom::PowerMonitorClient> clients_;

  DISALLOW_COPY_AND_ASSIGN(MockPowerMonitorMessageBroadcaster);
};

class PowerMonitorTest : public ContentBrowserTest {
 public:
  PowerMonitorTest() {
    // Because Device Service also runs in this process(browser process), we can
    // set our binder to intercept requests for PowerMonitor interface to it.
    service_manager::ServiceBinding::OverrideInterfaceBinderForTesting(
        device::mojom::kServiceName,
        base::Bind(&PowerMonitorTest::BindPowerMonitor,
                   base::Unretained(this)));
  }

  ~PowerMonitorTest() override {
    service_manager::ServiceBinding::ClearInterfaceBinderOverrideForTesting<
        device::mojom::PowerMonitor>(device::mojom::kServiceName);
  }

  void BindPowerMonitor(
      const service_manager::BindSourceInfo& source_info,
      mojo::PendingReceiver<device::mojom::PowerMonitor> receiver) {
    if (source_info.identity.name() == mojom::kRendererServiceName) {
      // We can receive binding requests for the spare RenderProcessHost - this
      // might happen before the test has provided the
      // |renderer_bound_closure_|.
      if (renderer_bound_closure_) {
        ++request_count_from_renderer_;
        std::move(renderer_bound_closure_).Run();
      } else {
        DCHECK(RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
      }
    } else if (source_info.identity.name() == mojom::kUtilityServiceName) {
      // If the network service is enabled, it will create utility processes
      // without a utility closure.
      if (utility_bound_closure_) {
        ++request_count_from_utility_;
        std::move(utility_bound_closure_).Run();
      }
    } else if (source_info.identity.name() == mojom::kGpuServiceName) {
      ++request_count_from_gpu_;

      // We ignore null gpu_bound_closure_ here for two possible scenarios:
      //  - TestRendererProcess and TestUtilityProcess also result in spinning
      //    up GPU processes as a side effect, but they do not set valid
      //    gpu_bound_closure_.
      //  - As GPU process is started during setup of browser test suite, so
      //    it's possible that TestGpuProcess execution may have not started
      //    yet when the PowerMonitor bind request comes here, in such case
      //    gpu_bound_closure_ will also be null.
      if (gpu_bound_closure_)
        std::move(gpu_bound_closure_).Run();
    }

    power_monitor_message_broadcaster_.Bind(std::move(receiver));
  }

 protected:
  void StartUtilityProcess(mojom::PowerMonitorTestPtr* power_monitor_test,
                           base::Closure utility_bound_closure) {
    utility_bound_closure_ = std::move(utility_bound_closure);
    base::PostTask(FROM_HERE, {BrowserThread::IO},
                   base::BindOnce(&StartUtilityProcessOnIOThread,
                                  mojo::MakeRequest(power_monitor_test)));
  }

  void set_renderer_bound_closure(base::Closure closure) {
    renderer_bound_closure_ = std::move(closure);
  }

  void set_gpu_bound_closure(base::Closure closure) {
    gpu_bound_closure_ = std::move(closure);
  }

  int request_count_from_renderer() { return request_count_from_renderer_; }
  int request_count_from_utility() { return request_count_from_utility_; }
  int request_count_from_gpu() { return request_count_from_gpu_; }

  void SimulatePowerStateChange(bool on_battery_power) {
    power_monitor_message_broadcaster_.OnPowerStateChange(on_battery_power);
  }

 private:
  int request_count_from_renderer_ = 0;
  int request_count_from_utility_ = 0;
  int request_count_from_gpu_ = 0;
  base::OnceClosure renderer_bound_closure_;
  base::OnceClosure gpu_bound_closure_;
  base::OnceClosure utility_bound_closure_;

  MockPowerMonitorMessageBroadcaster power_monitor_message_broadcaster_;

  DISALLOW_COPY_AND_ASSIGN(PowerMonitorTest);
};

IN_PROC_BROWSER_TEST_F(PowerMonitorTest, TestRendererProcess) {
  ASSERT_EQ(0, request_count_from_renderer());
  base::RunLoop run_loop;
  set_renderer_bound_closure(run_loop.QuitClosure());
  ASSERT_TRUE(NavigateToURL(shell(), GetTestUrl(".", "simple_page.html")));
  run_loop.Run();
  EXPECT_EQ(1, request_count_from_renderer());

  mojom::PowerMonitorTestPtr power_monitor_renderer;
  RenderProcessHost* rph =
      shell()->web_contents()->GetMainFrame()->GetProcess();
  BindInterface(rph, &power_monitor_renderer);

  // Ensure that the PowerMonitorTestImpl instance has been created and is
  // observing power state changes in the child process before simulating a
  // power state change.
  power_monitor_renderer.FlushForTesting();

  SimulatePowerStateChange(true);
  // Verify renderer process on_battery_power changed to true.
  VerifyPowerStateInChildProcess(power_monitor_renderer.get(), true);

  SimulatePowerStateChange(false);
  // Verify renderer process on_battery_power changed to false.
  VerifyPowerStateInChildProcess(power_monitor_renderer.get(), false);
}

IN_PROC_BROWSER_TEST_F(PowerMonitorTest, TestUtilityProcess) {
  mojom::PowerMonitorTestPtr power_monitor_utility;

  ASSERT_EQ(0, request_count_from_utility());
  base::RunLoop run_loop;
  StartUtilityProcess(&power_monitor_utility, run_loop.QuitClosure());
  run_loop.Run();
  EXPECT_EQ(1, request_count_from_utility());

  // Ensure that the PowerMonitorTestImpl instance has been created and is
  // observing power state changes in the child process before simulating a
  // power state change.
  power_monitor_utility.FlushForTesting();

  SimulatePowerStateChange(true);
  // Verify utility process on_battery_power changed to true.
  VerifyPowerStateInChildProcess(power_monitor_utility.get(), true);

  SimulatePowerStateChange(false);
  // Verify utility process on_battery_power changed to false.
  VerifyPowerStateInChildProcess(power_monitor_utility.get(), false);
}

IN_PROC_BROWSER_TEST_F(PowerMonitorTest, TestGpuProcess) {
  // As gpu process is started automatically during the setup period of browser
  // test suite, it may have already started and bound PowerMonitor interface to
  // Device Service before execution of this TestGpuProcess test. So here we
  // do not wait for the connection if we found it has already been established.
  if (request_count_from_gpu() != 1) {
    ASSERT_EQ(0, request_count_from_gpu());
    base::RunLoop run_loop;
    set_gpu_bound_closure(run_loop.QuitClosure());
    // Wait for the connection from gpu process.
    run_loop.Run();
  }
  EXPECT_EQ(1, request_count_from_gpu());

  mojom::PowerMonitorTestPtr power_monitor_gpu;
  base::PostTask(FROM_HERE, {BrowserThread::IO},
                 base::BindOnce(&BindInterfaceForGpuOnIOThread,
                                mojo::MakeRequest(&power_monitor_gpu)));

  // Ensure that the PowerMonitorTestImpl instance has been created and is
  // observing power state changes in the child process before simulating a
  // power state change.
  power_monitor_gpu.FlushForTesting();

  SimulatePowerStateChange(true);
  // Verify gpu process on_battery_power changed to true.
  VerifyPowerStateInChildProcess(power_monitor_gpu.get(), true);

  SimulatePowerStateChange(false);
  // Verify gpu process on_battery_power changed to false.
  VerifyPowerStateInChildProcess(power_monitor_gpu.get(), false);
}

}  //  namespace

}  //  namespace content
