// Copyright 2013 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 "content/browser/renderer_host/media/media_stream_ui_proxy.h"

#include <string>
#include <utility>

#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/public/common/content_features.h"
#include "content/public/test/test_browser_thread.h"
#include "content/test/test_render_frame_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"
#include "url/origin.h"

using testing::_;
using testing::Return;
using testing::SaveArg;

namespace content {

namespace {
class MockRenderFrameHostDelegate : public RenderFrameHostDelegate {
 public:
  void RequestMediaAccessPermission(const MediaStreamRequest& request,
                                    MediaResponseCallback callback) {
    return RequestMediaAccessPermission(request, &callback);
  }
  MOCK_METHOD2(RequestMediaAccessPermission,
               void(const MediaStreamRequest& request,
                    MediaResponseCallback* callback));
  MOCK_METHOD3(CheckMediaAccessPermission,
               bool(RenderFrameHost* render_frame_host,
                    const url::Origin& security_origin,
                    MediaStreamType type));
};

class MockResponseCallback {
 public:
  MOCK_METHOD2(OnAccessRequestResponse,
               void(const MediaStreamDevices& devices,
               content::MediaStreamRequestResult result));
  MOCK_METHOD1(OnCheckResponse, void(bool have_access));
};

class MockMediaStreamUI : public MediaStreamUI {
 public:
  MOCK_METHOD1(OnStarted, gfx::NativeViewId(const base::Closure& stop));
};

class MockStopStreamHandler {
 public:
  MOCK_METHOD0(OnStop, void());
  MOCK_METHOD1(OnWindowId, void(gfx::NativeViewId window_id));
};


}  // namespace

class MediaStreamUIProxyTest : public testing::Test {
 public:
  MediaStreamUIProxyTest()
      : ui_thread_(BrowserThread::UI, &message_loop_),
        io_thread_(BrowserThread::IO, &message_loop_) {
    proxy_ = MediaStreamUIProxy::CreateForTests(&delegate_);
  }

  ~MediaStreamUIProxyTest() override {
    proxy_.reset();
    base::RunLoop().RunUntilIdle();
  }

 protected:
  base::MessageLoop message_loop_;
  TestBrowserThread ui_thread_;
  TestBrowserThread io_thread_;

  MockRenderFrameHostDelegate delegate_;
  MockResponseCallback response_callback_;
  std::unique_ptr<MediaStreamUIProxy> proxy_;
};

MATCHER_P(SameRequest, expected, "") {
  return
    expected->render_process_id == arg.render_process_id &&
    expected->render_frame_id == arg.render_frame_id &&
    expected->security_origin == arg.security_origin &&
    expected->request_type == arg.request_type &&
    expected->requested_audio_device_id == arg.requested_audio_device_id &&
    expected->requested_video_device_id == arg.requested_video_device_id &&
    expected->audio_type == arg.audio_type &&
    expected->video_type == arg.video_type;
}

// These tests are flaky on Linux. https://crbug.com/826483
#if defined(OS_LINUX)
#define MAYBE_DeleteBeforeAccepted DISABLED_DeleteBeforeAccepted
#define MAYBE_Deny DISABLED_Deny
#define MAYBE_AcceptAndStart DISABLED_AcceptAndStart
#define MAYBE_StopFromUI DISABLED_StopFromUI
#define MAYBE_WindowIdCallbackCalled DISABLED_WindowIdCallbackCalled
#else
#define MAYBE_DeleteBeforeAccepted DeleteBeforeAccepted
#define MAYBE_Deny Deny
#define MAYBE_AcceptAndStart AcceptAndStart
#define MAYBE_StopFromUI StopFromUI
#define MAYBE_WindowIdCallbackCalled WindowIdCallbackCalled
#endif

TEST_F(MediaStreamUIProxyTest, MAYBE_Deny) {
  std::unique_ptr<MediaStreamRequest> request(new MediaStreamRequest(
      0, 0, 0, GURL("http://origin/"), false, MEDIA_GENERATE_STREAM,
      std::string(), std::string(), MEDIA_DEVICE_AUDIO_CAPTURE,
      MEDIA_DEVICE_VIDEO_CAPTURE, false));
  MediaStreamRequest* request_ptr = request.get();
  proxy_->RequestAccess(
      std::move(request),
      base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
                     base::Unretained(&response_callback_)));
  MediaResponseCallback callback;
  EXPECT_CALL(delegate_,
              RequestMediaAccessPermission(SameRequest(request_ptr), _))
      .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
        callback = std::move(*cb);
      });
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(callback.is_null());

  MediaStreamDevices devices;
  std::move(callback).Run(devices, MEDIA_DEVICE_OK,
                          std::unique_ptr<MediaStreamUI>());

  MediaStreamDevices response;
  EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
    .WillOnce(SaveArg<0>(&response));
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(response.empty());
}

TEST_F(MediaStreamUIProxyTest, MAYBE_AcceptAndStart) {
  std::unique_ptr<MediaStreamRequest> request(new MediaStreamRequest(
      0, 0, 0, GURL("http://origin/"), false, MEDIA_GENERATE_STREAM,
      std::string(), std::string(), MEDIA_DEVICE_AUDIO_CAPTURE,
      MEDIA_DEVICE_VIDEO_CAPTURE, false));
  MediaStreamRequest* request_ptr = request.get();
  proxy_->RequestAccess(
      std::move(request),
      base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
                     base::Unretained(&response_callback_)));
  MediaResponseCallback callback;
  EXPECT_CALL(delegate_,
              RequestMediaAccessPermission(SameRequest(request_ptr), _))
      .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
        callback = std::move(*cb);
      });
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(callback.is_null());

  MediaStreamDevices devices;
  devices.push_back(
      MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
  std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
  EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(0));
  std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));

  MediaStreamDevices response;
  EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
    .WillOnce(SaveArg<0>(&response));
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(response.empty());

  proxy_->OnStarted(base::Closure(), MediaStreamUIProxy::WindowIdCallback());
  base::RunLoop().RunUntilIdle();
}

// Verify that the proxy can be deleted before the request is processed.
TEST_F(MediaStreamUIProxyTest, MAYBE_DeleteBeforeAccepted) {
  std::unique_ptr<MediaStreamRequest> request(new MediaStreamRequest(
      0, 0, 0, GURL("http://origin/"), false, MEDIA_GENERATE_STREAM,
      std::string(), std::string(), MEDIA_DEVICE_AUDIO_CAPTURE,
      MEDIA_DEVICE_VIDEO_CAPTURE, false));
  MediaStreamRequest* request_ptr = request.get();
  proxy_->RequestAccess(
      std::move(request),
      base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
                     base::Unretained(&response_callback_)));
  MediaResponseCallback callback;
  EXPECT_CALL(delegate_,
              RequestMediaAccessPermission(SameRequest(request_ptr), _))
      .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
        callback = std::move(*cb);
      });
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(callback.is_null());

  proxy_.reset();

  MediaStreamDevices devices;
  std::unique_ptr<MediaStreamUI> ui;
  std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));
}

TEST_F(MediaStreamUIProxyTest, MAYBE_StopFromUI) {
  std::unique_ptr<MediaStreamRequest> request(new MediaStreamRequest(
      0, 0, 0, GURL("http://origin/"), false, MEDIA_GENERATE_STREAM,
      std::string(), std::string(), MEDIA_DEVICE_AUDIO_CAPTURE,
      MEDIA_DEVICE_VIDEO_CAPTURE, false));
  MediaStreamRequest* request_ptr = request.get();
  proxy_->RequestAccess(
      std::move(request),
      base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
                     base::Unretained(&response_callback_)));
  MediaResponseCallback callback;
  EXPECT_CALL(delegate_,
              RequestMediaAccessPermission(SameRequest(request_ptr), _))
      .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
        callback = std::move(*cb);
      });
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(callback.is_null());

  base::Closure stop_callback;

  MediaStreamDevices devices;
  devices.push_back(
      MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
  std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
  EXPECT_CALL(*ui, OnStarted(_))
      .WillOnce(testing::DoAll(SaveArg<0>(&stop_callback), Return(0)));
  std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));

  MediaStreamDevices response;
  EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
    .WillOnce(SaveArg<0>(&response));
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(response.empty());

  MockStopStreamHandler stop_handler;
  proxy_->OnStarted(base::BindOnce(&MockStopStreamHandler::OnStop,
                                   base::Unretained(&stop_handler)),
                    MediaStreamUIProxy::WindowIdCallback());
  base::RunLoop().RunUntilIdle();

  ASSERT_FALSE(stop_callback.is_null());
  EXPECT_CALL(stop_handler, OnStop());
  stop_callback.Run();
  base::RunLoop().RunUntilIdle();
}

TEST_F(MediaStreamUIProxyTest, MAYBE_WindowIdCallbackCalled) {
  std::unique_ptr<MediaStreamRequest> request(new MediaStreamRequest(
      0, 0, 0, GURL("http://origin/"), false, MEDIA_GENERATE_STREAM,
      std::string(), std::string(), MEDIA_NO_SERVICE,
      MEDIA_GUM_DESKTOP_VIDEO_CAPTURE, false));
  MediaStreamRequest* request_ptr = request.get();

  proxy_->RequestAccess(
      std::move(request),
      base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
                     base::Unretained(&response_callback_)));
  MediaResponseCallback callback;
  EXPECT_CALL(delegate_,
              RequestMediaAccessPermission(SameRequest(request_ptr), _))
      .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
        callback = std::move(*cb);
      });
  base::RunLoop().RunUntilIdle();

  const int kWindowId = 1;
  std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
  EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(kWindowId));

  std::move(callback).Run(MediaStreamDevices(), MEDIA_DEVICE_OK, std::move(ui));
  EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _));

  MockStopStreamHandler handler;
  EXPECT_CALL(handler, OnWindowId(kWindowId));

  proxy_->OnStarted(base::BindOnce(&MockStopStreamHandler::OnStop,
                                   base::Unretained(&handler)),
                    base::BindOnce(&MockStopStreamHandler::OnWindowId,
                                   base::Unretained(&handler)));
  base::RunLoop().RunUntilIdle();
}

// Basic tests for feature policy checks through the MediaStreamUIProxy. These
// tests are not meant to cover every edge case as the FeaturePolicy class
// itself is tested thoroughly in feature_policy_unittest.cc and in
// render_frame_host_feature_policy_unittest.cc.
class MediaStreamUIProxyFeaturePolicyTest
    : public RenderViewHostImplTestHarness {
 public:
  void SetUp() override {
    RenderViewHostImplTestHarness::SetUp();
    NavigateAndCommit(GURL("https://example.com"));
  }

 protected:
  // The header policy should only be set once on page load, so we refresh the
  // page to simulate that.
  void RefreshPageAndSetHeaderPolicy(RenderFrameHost* rfh,
                                     blink::mojom::FeaturePolicyFeature feature,
                                     bool enabled) {
    NavigateAndCommit(rfh->GetLastCommittedURL());
    std::vector<url::Origin> whitelist;
    if (enabled)
      whitelist.push_back(rfh->GetLastCommittedOrigin());
    RenderFrameHostTester::For(rfh)->SimulateFeaturePolicyHeader(feature,
                                                                 whitelist);
  }

  void GetResultForRequest(std::unique_ptr<MediaStreamRequest> request,
                           MediaStreamDevices* devices_out,
                           MediaStreamRequestResult* result_out) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    base::RunLoop run_loop;
    quit_closure_ = run_loop.QuitClosure();
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::BindOnce(
            &MediaStreamUIProxyFeaturePolicyTest::GetResultForRequestOnIOThread,
            base::Unretained(this), std::move(request)));
    run_loop.Run();
    *devices_out = devices_;
    *result_out = result_;
  }

  std::unique_ptr<MediaStreamRequest> CreateRequest(RenderFrameHost* rfh,
                                                    MediaStreamType mic_type,
                                                    MediaStreamType cam_type) {
    return std::make_unique<MediaStreamRequest>(
        rfh->GetProcess()->GetID(), rfh->GetRoutingID(), 0,
        rfh->GetLastCommittedURL(), false, MEDIA_GENERATE_STREAM, std::string(),
        std::string(), mic_type, cam_type, false);
  }

 private:
  class TestRFHDelegate : public RenderFrameHostDelegate {
    void RequestMediaAccessPermission(const MediaStreamRequest& request,
                                      MediaResponseCallback callback) override {
      MediaStreamDevices devices;
      if (request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) {
        devices.push_back(
            MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
      }
      if (request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) {
        devices.push_back(
            MediaStreamDevice(MEDIA_DEVICE_VIDEO_CAPTURE, "Camera", "Camera"));
      }
      std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
      std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));
    }
  };

  void GetResultForRequestOnIOThread(
      std::unique_ptr<MediaStreamRequest> request) {
    DCHECK_CURRENTLY_ON(BrowserThread::IO);
    proxy_ = MediaStreamUIProxy::CreateForTests(&delegate_);
    proxy_->RequestAccess(
        std::move(request),
        base::BindOnce(
            &MediaStreamUIProxyFeaturePolicyTest::FinishedGetResultOnIOThread,
            base::Unretained(this)));
  }

  void FinishedGetResultOnIOThread(const MediaStreamDevices& devices,
                                   MediaStreamRequestResult result) {
    DCHECK_CURRENTLY_ON(BrowserThread::IO);
    proxy_.reset();
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::BindOnce(&MediaStreamUIProxyFeaturePolicyTest::FinishedGetResult,
                       base::Unretained(this), devices, result));
  }

  void FinishedGetResult(const MediaStreamDevices& devices,
                         MediaStreamRequestResult result) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    devices_ = devices;
    result_ = result;
    quit_closure_.Run();
  }

  // These should only be accessed on the UI thread.
  MediaStreamDevices devices_;
  MediaStreamRequestResult result_;
  base::Closure quit_closure_;

  // These should only be accessed on the IO thread.
  TestRFHDelegate delegate_;
  std::unique_ptr<MediaStreamUIProxy> proxy_;
};

TEST_F(MediaStreamUIProxyFeaturePolicyTest, FeaturePolicy) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kUseFeaturePolicyForPermissions);
  MediaStreamDevices devices;
  MediaStreamRequestResult result;

  // Default FP.
  GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
                                    MEDIA_DEVICE_VIDEO_CAPTURE),
                      &devices, &result);
  EXPECT_EQ(MEDIA_DEVICE_OK, result);
  ASSERT_EQ(2u, devices.size());
  EXPECT_EQ(MEDIA_DEVICE_AUDIO_CAPTURE, devices[0].type);
  EXPECT_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, devices[1].type);

  // Mic disabled.
  RefreshPageAndSetHeaderPolicy(main_rfh(),
                                blink::mojom::FeaturePolicyFeature::kMicrophone,
                                /*enabled=*/false);
  GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
                                    MEDIA_DEVICE_VIDEO_CAPTURE),
                      &devices, &result);
  EXPECT_EQ(MEDIA_DEVICE_OK, result);
  ASSERT_EQ(1u, devices.size());
  EXPECT_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, devices[0].type);

  // Camera disabled.
  RefreshPageAndSetHeaderPolicy(main_rfh(),
                                blink::mojom::FeaturePolicyFeature::kCamera,
                                /*enabled=*/false);
  GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
                                    MEDIA_DEVICE_VIDEO_CAPTURE),
                      &devices, &result);
  EXPECT_EQ(MEDIA_DEVICE_OK, result);
  ASSERT_EQ(1u, devices.size());
  EXPECT_EQ(MEDIA_DEVICE_AUDIO_CAPTURE, devices[0].type);

  // Camera disabled resulting in no devices being returned.
  RefreshPageAndSetHeaderPolicy(main_rfh(),
                                blink::mojom::FeaturePolicyFeature::kCamera,
                                /*enabled=*/false);
  GetResultForRequest(
      CreateRequest(main_rfh(), MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE),
      &devices, &result);
  EXPECT_EQ(MEDIA_DEVICE_PERMISSION_DENIED, result);
  ASSERT_EQ(0u, devices.size());

  // Ensure that the policy is ignored if kUseFeaturePolicyForPermissions is
  // disabled.
  base::test::ScopedFeatureList empty_feature_list;
  empty_feature_list.InitAndDisableFeature(
      features::kUseFeaturePolicyForPermissions);
  GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
                                    MEDIA_DEVICE_VIDEO_CAPTURE),
                      &devices, &result);
  EXPECT_EQ(MEDIA_DEVICE_OK, result);
  ASSERT_EQ(2u, devices.size());
  EXPECT_EQ(MEDIA_DEVICE_AUDIO_CAPTURE, devices[0].type);
  EXPECT_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, devices[1].type);
}

}  // namespace content
