// Copyright 2023 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/video_conference/video_conference_app_service_client.h"

#include <cstdlib>
#include <utility>
#include <vector>

#include "ash/constants/ash_features.h"
#include "ash/constants/ash_switches.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/system/video_conference/fake_video_conference_tray_controller.h"
#include "ash/system/video_conference/video_conference_common.h"
#include "ash/test/test_window_builder.h"
#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/unguessable_token.h"
#include "chrome/browser/apps/app_service/app_service_proxy_ash.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/ash/crosapi/crosapi_ash.h"
#include "chrome/browser/ash/crosapi/crosapi_manager.h"
#include "chrome/browser/ash/video_conference/video_conference_manager_ash.h"
#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/crosapi/mojom/video_conference.mojom.h"
#include "components/services/app_service/public/cpp/app_capability_access_cache_wrapper.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "components/services/app_service/public/cpp/capability_access_update.h"
#include "components/services/app_service/public/cpp/instance_registry.h"
#include "components/user_manager/user_manager.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_utils.h"

namespace ash {
namespace {

using AppIdString = std::string;

constexpr char kAppId1[] = "random_app_id_1";
constexpr char kAppName1[] = "random_app_name_1";
constexpr char kAppId2[] = "random_app_id_2";
constexpr char kAppName2[] = "random_app_name_2";

// Creates an app with given id and permissions.
apps::AppPtr MakeApp(const AppIdString& app_id,
                     bool has_camera_permission,
                     bool has_microphone_permission,
                     apps::AppType app_type) {
  apps::AppPtr app = std::make_unique<apps::App>(app_type, app_id);
  if (app_id == kAppId1) {
    app->name = kAppName1;
  }
  if (app_id == kAppId2) {
    app->name = kAppName2;
  }
  if (base::Contains(::video_conference::kSkipAppIds, app_id)) {
    app->name = base::StrCat({"AppName-", app_id});
  }

  app->publisher_id = app_id;

  app->permissions.push_back(std::make_unique<apps::Permission>(
      apps::PermissionType::kCamera,
      std::make_unique<apps::PermissionValue>(has_camera_permission),
      /*is_managed=*/false));
  app->permissions.push_back(std::make_unique<apps::Permission>(
      apps::PermissionType::kMicrophone,
      std::make_unique<apps::PermissionValue>(has_microphone_permission),
      /*is_managed=*/false));
  return app;
}

// This fake instance class simulates the creation, destruction, hiding and
// showing an app instance.
class FakeAppInstance {
 public:
  FakeAppInstance(apps::InstanceRegistry* instance_registry,
                  const AppIdString& app_id) {
    instance_registry_ = instance_registry;
    window_ = TestWindowBuilder().Build();
    instance_ = std::make_unique<apps::Instance>(
        app_id, base::UnguessableToken::Create(), window_.get());
  }

  aura::Window* window() { return window_.get(); }

  void Start() {
    auto instance = instance_->Clone();
    instance->UpdateState(apps::InstanceState::kStarted, base::Time::Now());
    instance_registry_->OnInstance(std::move(instance));
  }

  void Close() {
    auto instance = instance_->Clone();
    instance->UpdateState(apps::InstanceState::kDestroyed, base::Time::Now());
    instance_registry_->OnInstance(std::move(instance));
  }

  void Show() {
    window_->Show();
    // Ideally, the following should be automatically triggered by showing the
    // window_; but that is not the case for now.
    auto instance = instance_->Clone();
    instance->UpdateState(apps::InstanceState::kActive, base::Time::Now());
    instance_registry_->OnInstance(std::move(instance));
  }

  void Hide() {
    window_->Hide();
    // Ideally, the following should be automatically triggered by hiding the
    // window_; but that is not the case for now.
    auto instance = instance_->Clone();
    instance->UpdateState(apps::InstanceState::kHidden, base::Time::Now());
    instance_registry_->OnInstance(std::move(instance));
  }

 private:
  std::unique_ptr<aura::Window> window_;
  std::unique_ptr<apps::Instance> instance_;
  base::raw_ptr<apps::InstanceRegistry> instance_registry_;
};

}  // namespace

class VideoConferenceAppServiceClientTest : public InProcessBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(
        ::ash::switches::kCameraEffectsSupportedByHardware);
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();

    client_ = VideoConferenceAppServiceClient::GetForTesting();

    Profile* profile = ProfileManager::GetActiveUserProfile();
    instance_registry_ = &apps::AppServiceProxyFactory::GetForProfile(profile)
                              ->InstanceRegistry();
    app_registry_cache_ = &apps::AppServiceProxyFactory::GetForProfile(profile)
                               ->AppRegistryCache();
    capability_cache_ =
        apps::AppCapabilityAccessCacheWrapper::Get()
            .GetAppCapabilityAccessCache(user_manager::UserManager::Get()
                                             ->GetActiveUser()
                                             ->GetAccountId());
  }

  // This function creates an app with given id and name, and adds the app into
  // AppRegistryCache of current profile.
  void InstallApp(const std::string& app_id,
                  apps::AppType app_type = apps::AppType::kArc) {
    std::vector<apps::AppPtr> deltas;
    deltas.push_back(MakeApp(app_id, /*has_camera_permission=*/false,
                             /*has_microphone_permission=*/false, app_type));
    app_registry_cache_->OnApps(std::move(deltas), apps::AppType::kUnknown,
                                /*should_notify_initialized=*/false);
  }

  // Update the permission of current `app_id`.
  void UpdateAppPermision(const std::string& app_id,
                          bool has_camera_permission,
                          bool has_microphone_permission) {
    std::vector<apps::AppPtr> deltas;
    deltas.push_back(MakeApp(app_id, has_camera_permission,
                             has_microphone_permission, GetAppType(app_id)));
    app_registry_cache_->OnApps(std::move(deltas), apps::AppType::kUnknown,
                                /*should_notify_initialized=*/false);
  }

  // Set the camera/michrophone accessing info for app with `app_id`.
  void SetAppCapabilityAccess(const AppIdString& app_id,
                              bool is_capturing_camera,
                              bool is_capturing_microphone) {
    auto delta = std::make_unique<apps::CapabilityAccess>(app_id);
    delta->camera = is_capturing_camera;
    delta->microphone = is_capturing_microphone;

    std::vector<apps::CapabilityAccessPtr> deltas;
    deltas.push_back(std::move(delta));

    capability_cache_->OnCapabilityAccesses(std::move(deltas));
  }

  // Adds {id, state} pair to client_->id_to_app_state_.
  void AddAppState(const AppIdString& app_id,
                   const VideoConferenceAppServiceClient::AppState& state) {
    (client_->id_to_app_state_)[app_id] = state;
  }

  std::string GetAppName(const AppIdString& app_id) {
    return client_->GetAppName(app_id);
  }

  apps::AppType GetAppType(const AppIdString& app_id) {
    return client_->GetAppType(app_id);
  }

  VideoConferenceAppServiceClient::VideoConferencePermissions GetAppPermission(
      const AppIdString& app_id) {
    return client_->GetAppPermission(app_id);
  }

  std::vector<crosapi::mojom::VideoConferenceMediaAppInfoPtr> GetMediaApps() {
    std::vector<crosapi::mojom::VideoConferenceMediaAppInfoPtr> media_app_info;

    client_->GetMediaApps(base::BindLambdaForTesting(
        [&media_app_info](
            std::vector<crosapi::mojom::VideoConferenceMediaAppInfoPtr>
                result) { media_app_info = std::move(result); }));

    return media_app_info;
  }

  // Returns current VideoConferenceMediaState in the VideoConferenceManagerAsh
  VideoConferenceMediaState GetMediaStateInVideoConferenceManagerAsh() {
    return crosapi::CrosapiManager::Get()
        ->crosapi_ash()
        ->video_conference_manager_ash()
        ->GetAggregatedState();
  }

 protected:
  raw_ptr<apps::InstanceRegistry, ExperimentalAsh> instance_registry_ = nullptr;
  raw_ptr<apps::AppRegistryCache, ExperimentalAsh> app_registry_cache_ =
      nullptr;
  raw_ptr<apps::AppCapabilityAccessCache, ExperimentalAsh> capability_cache_ =
      nullptr;
  raw_ptr<VideoConferenceAppServiceClient, ExperimentalAsh> client_ = nullptr;

  base::test::ScopedFeatureList scoped_feature_list_{
      ash::features::kVideoConference};
};

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, GetAppName) {
  // AppName should be empty if it is not installed.
  EXPECT_EQ(GetAppName(kAppId1), std::string());

  InstallApp(kAppId1);

  // AppName should be correct if installed.
  EXPECT_EQ(GetAppName(kAppId1), kAppName1);
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, GetAppType) {
  // AppType should be kUnknown if it is not installed.
  EXPECT_EQ(GetAppType(kAppId1), apps::AppType::kUnknown);

  InstallApp(kAppId1);

  // AppType for the test app installed should be Arc.
  EXPECT_EQ(GetAppType(kAppId1), apps::AppType::kArc);
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, GetAppPermission) {
  InstallApp(kAppId1);

  VideoConferenceAppServiceClient::VideoConferencePermissions permission =
      GetAppPermission(kAppId1);
  EXPECT_FALSE(permission.has_camera_permission);
  EXPECT_FALSE(permission.has_microphone_permission);

  UpdateAppPermision(kAppId1, /*has_camera_permission=*/false,
                     /*has_microphone_permission=*/true);
  permission = GetAppPermission(kAppId1);
  EXPECT_FALSE(permission.has_camera_permission);
  EXPECT_TRUE(permission.has_microphone_permission);

  UpdateAppPermision(kAppId1, /*has_camera_permission=*/true,
                     /*has_microphone_permission=*/true);
  permission = GetAppPermission(kAppId1);
  EXPECT_TRUE(permission.has_camera_permission);
  EXPECT_TRUE(permission.has_microphone_permission);

  UpdateAppPermision(kAppId1, /*has_camera_permission=*/true,
                     /*has_microphone_permission=*/false);
  permission = GetAppPermission(kAppId1);
  EXPECT_TRUE(permission.has_camera_permission);
  EXPECT_FALSE(permission.has_microphone_permission);

  UpdateAppPermision(kAppId1, /*has_camera_permission=*/false,
                     /*has_microphone_permission=*/false);
  permission = GetAppPermission(kAppId1);
  EXPECT_FALSE(permission.has_camera_permission);
  EXPECT_FALSE(permission.has_microphone_permission);
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, GetMediaApps) {
  // Add {kAppId1, state1} pair to the client_.
  const base::UnguessableToken token1 = base::UnguessableToken::Create();
  const VideoConferenceAppServiceClient::AppState state1{
      token1, base::Time::Now(), true, true};
  AddAppState(kAppId1, state1);

  // Add {kAppId2, state2} pair to the client_.
  const base::UnguessableToken token2 = base::UnguessableToken::Create();
  const VideoConferenceAppServiceClient::AppState state2{
      token2, base::Time::Now(), true, false};
  AddAppState(kAppId2, state2);

  std::vector<crosapi::mojom::VideoConferenceMediaAppInfoPtr> media_app_info =
      GetMediaApps();

  // GetMediaApps will not return anything because unrecognized apps will be
  // skipped.
  EXPECT_TRUE(media_app_info.empty());

  InstallApp(kAppId1);

  // GetMediaApps should return kAppId1 since it is installed.
  media_app_info = GetMediaApps();
  ASSERT_EQ(media_app_info.size(), 1u);

  crosapi::mojom::VideoConferenceMediaAppInfoPtr expected_media_app_info =
      crosapi::mojom::VideoConferenceMediaAppInfo::New(
          /*id=*/token1,
          /*last_activity_time=*/state1.last_activity_time,
          /*is_capturing_camera=*/state1.is_capturing_camera,
          /*is_capturing_microphone=*/state1.is_capturing_microphone,
          /*is_capturing_screen=*/false,
          /*title=*/base::UTF8ToUTF16(std::string(kAppName1)),
          /*url=*/absl::nullopt,
          /*app_type=*/crosapi::mojom::VideoConferenceAppType::kArcApp);

  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, ReturnToApp) {
  // Add two instance for kAppId1.
  FakeAppInstance instance1(instance_registry_, kAppId1);
  instance1.Start();
  FakeAppInstance instance2(instance_registry_, kAppId1);
  instance2.Start();

  aura::Window* window1 = instance1.window();
  aura::Window* window2 = instance2.window();
  window1->Hide();
  window2->Hide();

  const base::UnguessableToken token1 = base::UnguessableToken::Create();
  bool reactivated_app = false;

  // Return to token1 should not do anything since the token1 is not in the
  // client_->id_to_app_state_.
  client_->ReturnToApp(
      token1, base::BindLambdaForTesting([&reactivated_app](bool result) {
        reactivated_app = result;
      }));

  EXPECT_FALSE(reactivated_app);
  EXPECT_FALSE(window1->IsVisible());
  EXPECT_FALSE(window2->IsVisible());

  // Add pair {token1, state1} to client_->id_to_app_state_.
  const VideoConferenceAppServiceClient::AppState state1{
      token1, base::Time::Now(), true, true};
  AddAppState(kAppId1, state1);

  // Return to token1 should show all instances associated with kAppId1.
  client_->ReturnToApp(
      token1, base::BindLambdaForTesting([&reactivated_app](bool result) {
        reactivated_app = result;
      }));

  EXPECT_TRUE(reactivated_app);
  EXPECT_TRUE(window1->IsVisible());
  EXPECT_TRUE(window2->IsVisible());
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, MediaCapturing) {
  // Install two apps so that they will can be tracked inside GetMediaApps.
  InstallApp(kAppId1);
  InstallApp(kAppId2);
  FakeAppInstance instance1(instance_registry_, kAppId1);
  instance1.Start();
  FakeAppInstance instance2(instance_registry_, kAppId2);
  instance2.Start();

  // no-camera, no-mic should not start a tracking of the app.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/false);
  EXPECT_TRUE(GetMediaApps().empty());

  std::vector<crosapi::mojom::VideoConferenceMediaAppInfoPtr> media_app_info;

  // has-camera, no-mic should start the tracking of the app.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/false);
  media_app_info = GetMediaApps();
  crosapi::mojom::VideoConferenceMediaAppInfoPtr expected_media_app_info =
      crosapi::mojom::VideoConferenceMediaAppInfo::New(
          /*id=*/media_app_info[0]->id,
          /*last_activity_time=*/media_app_info[0]->last_activity_time,
          /*is_capturing_camera=*/true,
          /*is_capturing_microphone=*/false,
          /*is_capturing_screen=*/false,
          /*title=*/media_app_info[0]->title, /*url=*/absl::nullopt,
          /*app_type=*/crosapi::mojom::VideoConferenceAppType::kArcApp);
  ASSERT_EQ(media_app_info.size(), 1u);
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));

  // has-camera, has-mic should change the value of GetMediaApps.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/true);
  media_app_info = GetMediaApps();
  ASSERT_EQ(media_app_info.size(), 1u);
  expected_media_app_info->is_capturing_microphone = true;
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));

  // no-camera, has-mic should change the value of GetMediaApps.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/true);
  media_app_info = GetMediaApps();
  ASSERT_EQ(media_app_info.size(), 1u);
  expected_media_app_info->is_capturing_camera = false;
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));

  // no-camera, no-mic should change the value of GetMediaApps; but not removing
  // the tracking app.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/false);
  media_app_info = GetMediaApps();
  ASSERT_EQ(media_app_info.size(), 1u);
  expected_media_app_info->is_capturing_microphone = false;
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, LastActivityTime) {
  // Start an instance of kAppId1.
  InstallApp(kAppId1);
  FakeAppInstance instance1(instance_registry_, kAppId1);
  instance1.Start();

  // has-camera, has-mic should start tracking of the kAppId1.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/true);

  std::vector<crosapi::mojom::VideoConferenceMediaAppInfoPtr> media_app_info;

  media_app_info = GetMediaApps();
  crosapi::mojom::VideoConferenceMediaAppInfoPtr expected_media_app_info =
      crosapi::mojom::VideoConferenceMediaAppInfo::New(
          /*id=*/media_app_info[0]->id,
          /*last_activity_time=*/media_app_info[0]->last_activity_time,
          /*is_capturing_camera=*/true,
          /*is_capturing_microphone=*/true,
          /*is_capturing_screen=*/false,
          /*title=*/media_app_info[0]->title, /*url=*/absl::nullopt,
          /*app_type=*/crosapi::mojom::VideoConferenceAppType::kArcApp);
  ASSERT_EQ(media_app_info.size(), 1u);
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));

  // Hide should not update last activity time.
  instance1.Hide();
  media_app_info = GetMediaApps();
  ASSERT_EQ(media_app_info.size(), 1u);
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));

  // Show should update last activity time.
  instance1.Show();
  media_app_info = GetMediaApps();
  ASSERT_EQ(media_app_info.size(), 1u);
  EXPECT_GT(media_app_info[0]->last_activity_time,
            expected_media_app_info->last_activity_time);
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, CloseApp) {
  // Start two instance of kAppId1.
  InstallApp(kAppId1);
  FakeAppInstance instance1(instance_registry_, kAppId1);
  instance1.Start();
  FakeAppInstance instance2(instance_registry_, kAppId1);
  instance2.Start();

  // No media app should be recorded till now.
  EXPECT_TRUE(GetMediaApps().empty());

  // has-camera, has-mic should start a tracking of the app.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/true);

  std::vector<crosapi::mojom::VideoConferenceMediaAppInfoPtr> media_app_info;

  media_app_info = GetMediaApps();
  crosapi::mojom::VideoConferenceMediaAppInfoPtr expected_media_app_info =
      crosapi::mojom::VideoConferenceMediaAppInfo::New(
          /*id=*/media_app_info[0]->id,
          /*last_activity_time=*/media_app_info[0]->last_activity_time,
          /*is_capturing_camera=*/true,
          /*is_capturing_microphone=*/true,
          /*is_capturing_screen=*/false,
          /*title=*/media_app_info[0]->title, /*url=*/absl::nullopt,
          /*app_type=*/crosapi::mojom::VideoConferenceAppType::kArcApp);
  ASSERT_EQ(media_app_info.size(), 1u);
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));

  // Closing instance1 should not remove tracking of kAppId1.
  instance1.Close();
  // Wait for the VideoConferenceAppServiceClient::MaybeRemoveApp to be called
  // in the PostTask.
  base::RunLoop().RunUntilIdle();
  media_app_info = GetMediaApps();
  ASSERT_EQ(media_app_info.size(), 1u);
  EXPECT_TRUE(media_app_info[0].Equals(expected_media_app_info));

  // Closing instance2 should remove trackingg of kAppId1.
  instance2.Close();
  // Wait for the VideoConferenceAppServiceClient::MaybeRemoveApp to be called
  // in the PostTask.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(GetMediaApps().empty());

  // This should not add the app tracking back because there is no running
  // instance.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/true);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(GetMediaApps().empty());

  // This should not add the app tracking back because there is no running
  // instance.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/false);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(GetMediaApps().empty());
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest,
                       HandleMediaUsageUpdate) {
  // Install two apps with permissions.
  InstallApp(kAppId1);
  InstallApp(kAppId2);
  UpdateAppPermision(kAppId1, /*has_camera_permission=*/true,
                     /*has_microphone_permission=*/false);
  UpdateAppPermision(kAppId2, /*has_camera_permission=*/false,
                     /*has_microphone_permission=*/true);

  // Start two running instance.
  FakeAppInstance instance1(instance_registry_, kAppId1);
  instance1.Start();
  FakeAppInstance instance2(instance_registry_, kAppId2);
  instance2.Start();

  VideoConferenceMediaState state = GetMediaStateInVideoConferenceManagerAsh();
  EXPECT_FALSE(state.has_media_app);
  EXPECT_FALSE(state.has_camera_permission);
  EXPECT_FALSE(state.has_microphone_permission);
  EXPECT_FALSE(state.is_capturing_camera);
  EXPECT_FALSE(state.is_capturing_microphone);
  EXPECT_FALSE(state.is_capturing_screen);

  // Accessing camera should start a tracking of the kAppId1.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/false);

  state = GetMediaStateInVideoConferenceManagerAsh();
  EXPECT_TRUE(state.has_media_app);
  EXPECT_TRUE(state.has_camera_permission);
  EXPECT_TRUE(state.is_capturing_camera);

  // Accessing microphone should start a tracking of the kAppId2.
  SetAppCapabilityAccess(kAppId2, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/true);

  state = GetMediaStateInVideoConferenceManagerAsh();
  EXPECT_TRUE(state.has_media_app);
  EXPECT_TRUE(state.has_microphone_permission);
  EXPECT_TRUE(state.is_capturing_microphone);

  // This should stop the accessing, but not the permission.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/false);

  state = GetMediaStateInVideoConferenceManagerAsh();
  EXPECT_TRUE(state.has_camera_permission);
  EXPECT_FALSE(state.is_capturing_camera);

  // Closing instance1 should remove tracking of kAppId1.
  instance1.Close();
  // Wait for the VideoConferenceAppServiceClient::MaybeRemoveApp to be called
  // in the PostTask.
  base::RunLoop().RunUntilIdle();

  state = GetMediaStateInVideoConferenceManagerAsh();
  EXPECT_FALSE(state.has_camera_permission);
  EXPECT_FALSE(state.is_capturing_camera);

  SetAppCapabilityAccess(kAppId2, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/false);

  state = GetMediaStateInVideoConferenceManagerAsh();
  EXPECT_TRUE(state.has_microphone_permission);
  EXPECT_FALSE(state.is_capturing_microphone);

  // Closing instance2 should remove trackingg of kAppId2.
  instance2.Close();
  // Wait for the VideoConferenceAppServiceClient::MaybeRemoveApp to be called
  // in the PostTask.
  base::RunLoop().RunUntilIdle();

  state = GetMediaStateInVideoConferenceManagerAsh();
  EXPECT_FALSE(state.has_media_app);
  EXPECT_FALSE(state.has_camera_permission);
  EXPECT_FALSE(state.has_microphone_permission);
  EXPECT_FALSE(state.is_capturing_camera);
  EXPECT_FALSE(state.is_capturing_microphone);
  EXPECT_FALSE(state.is_capturing_screen);
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest,
                       OnlyCertainAppsAreTracked) {
  for (const auto type :
       {apps::AppType::kUnknown, apps::AppType::kBuiltIn,
        apps::AppType::kCrostini, apps::AppType::kChromeApp,
        apps::AppType::kWeb, apps::AppType::kMacOs, apps::AppType::kPluginVm,
        apps::AppType::kStandaloneBrowser, apps::AppType::kRemote,
        apps::AppType::kBorealis, apps::AppType::kSystemWeb,
        apps::AppType::kStandaloneBrowserChromeApp, apps::AppType::kExtension,
        apps::AppType::kStandaloneBrowserExtension,
        apps::AppType::kBruschetta}) {
    // Create a fake id.
    const std::string app_id = base::NumberToString(static_cast<int>(type));
    // Install the app with given type.
    InstallApp(app_id, type);
    // Start the app.
    FakeAppInstance instance(instance_registry_, app_id);
    instance.Start();

    // has-camera, has-mic should not start tracking of the app only because
    // that we are not tracking the AppType listed above.
    SetAppCapabilityAccess(app_id, /*is_capturing_camera=*/true,
                           /*is_capturing_microphone=*/true);

    EXPECT_TRUE(GetMediaApps().empty());
  }
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest,
                       HandleDeviceUsedWhileDisabled) {
  // Notify disabling state of camera and microphone from
  // video_conference_manager_ash.
  crosapi::CrosapiManager::Get()
      ->crosapi_ash()
      ->video_conference_manager_ash()
      ->SetSystemMediaDeviceStatus(
          crosapi::mojom::VideoConferenceMediaDevice::kCamera,
          /*disabled=*/true);
  crosapi::CrosapiManager::Get()
      ->crosapi_ash()
      ->video_conference_manager_ash()
      ->SetSystemMediaDeviceStatus(
          crosapi::mojom::VideoConferenceMediaDevice::kMicrophone,
          /*disabled=*/true);

  FakeVideoConferenceTrayController* fake_try_controller =
      static_cast<FakeVideoConferenceTrayController*>(
          VideoConferenceTrayController::Get());

  InstallApp(kAppId1);

  // Accessing camera will trigger NotifyDeviceUsedWhileDisabled.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/false);
  ASSERT_EQ(fake_try_controller->device_used_while_disabled_records().size(),
            1u);
  EXPECT_THAT(fake_try_controller->device_used_while_disabled_records().back(),
              testing::Pair(crosapi::mojom::VideoConferenceMediaDevice::kCamera,
                            base::UTF8ToUTF16(std::string(kAppName1))));

  // Accessing microphone will trigger NotifyDeviceUsedWhileDisabled.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/true);
  ASSERT_EQ(fake_try_controller->device_used_while_disabled_records().size(),
            2u);
  EXPECT_THAT(
      fake_try_controller->device_used_while_disabled_records().back(),
      testing::Pair(crosapi::mojom::VideoConferenceMediaDevice::kMicrophone,
                    base::UTF8ToUTF16(std::string(kAppName1))));

  // Stopping microphone access should not trigger
  // NotifyDeviceUsedWhileDisabled.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/false);
  ASSERT_EQ(fake_try_controller->device_used_while_disabled_records().size(),
            2u);

  // Stopping camera access should not trigger NotifyDeviceUsedWhileDisabled.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/false,
                         /*is_capturing_microphone=*/false);
  ASSERT_EQ(fake_try_controller->device_used_while_disabled_records().size(),
            2u);

  // Notify enabling state of camera and microphone from
  // video_conference_manager_ash.
  crosapi::CrosapiManager::Get()
      ->crosapi_ash()
      ->video_conference_manager_ash()
      ->SetSystemMediaDeviceStatus(
          crosapi::mojom::VideoConferenceMediaDevice::kCamera,
          /*disabled=*/false);
  crosapi::CrosapiManager::Get()
      ->crosapi_ash()
      ->video_conference_manager_ash()
      ->SetSystemMediaDeviceStatus(
          crosapi::mojom::VideoConferenceMediaDevice::kMicrophone,
          /*disabled=*/false);

  // Accessing camera should not trigger NotifyDeviceUsedWhileDisabled because
  // camera is not disabled.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/false);
  ASSERT_EQ(fake_try_controller->device_used_while_disabled_records().size(),
            2u);

  // Accessing microphone should not trigger NotifyDeviceUsedWhileDisabled
  // because microphone is not disabled.
  SetAppCapabilityAccess(kAppId1, /*is_capturing_camera=*/true,
                         /*is_capturing_microphone=*/true);
  ASSERT_EQ(fake_try_controller->device_used_while_disabled_records().size(),
            2u);
}

IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest,
                       SomeAppsAreNotTracked) {
  // Install all apps that should be skipped.
  for (const std::string& app_id : ::video_conference::kSkipAppIds) {
    InstallApp(app_id);
    // Accessing mic and camera should trigger tracking except the app_id is
    // skipped.
    SetAppCapabilityAccess(app_id, /*is_capturing_camera=*/true,
                           /*is_capturing_microphone=*/true);
  }

  EXPECT_TRUE(GetMediaApps().empty());
}

}  // namespace ash
