#ifndef ASH_PROJECTOR_PROJECTOR_CONTROLLER_IMPL_H_
#define ASH_PROJECTOR_PROJECTOR_CONTROLLER_IMPL_H_
#include <string>
#include <vector>
#include "ash/ash_export.h"
#include "ash/capture_mode/capture_mode_observer.h"
#include "ash/projector/model/projector_session_impl.h"
#include "ash/public/cpp/projector/projector_controller.h"
#include "base/files/safe_base_name.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "chromeos/ash/components/audio/cras_audio_handler.h"
#include "third_party/skia/include/core/SkColor.h"
class PrefRegistrySimple;
namespace aura {
class Window;
}
namespace base {
class FilePath;
}
namespace gfx {
class ImageSkia;
}
namespace ash {
class ProjectorClient;
class ProjectorUiController;
class ProjectorMetadataController;
class ASH_EXPORT ProjectorControllerImpl
: public ProjectorController,
public ProjectorSessionObserver,
public CrasAudioHandler::AudioObserver,
public CaptureModeObserver {
public:
using CreateScreencastContainerFolderCallback = base::OnceCallback<void(
const base::FilePath& screencast_file_path_no_extension)>;
using OnPathDeletedCallback =
base::OnceCallback<void(const base::FilePath& path, bool success)>;
using OnFileSavedCallback =
base::OnceCallback<void(const base::FilePath& path, bool success)>;
ProjectorControllerImpl();
ProjectorControllerImpl(const ProjectorControllerImpl&) = delete;
ProjectorControllerImpl& operator=(const ProjectorControllerImpl&) = delete;
~ProjectorControllerImpl() override;
static ProjectorControllerImpl* Get();
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
void StartProjectorSession(const base::SafeBaseName& storage_dir) override;
void SetClient(ProjectorClient* client) override;
void OnSpeechRecognitionAvailabilityChanged() override;
void OnTranscription(const media::SpeechRecognitionResult& result) override;
void OnTranscriptionError() override;
void OnSpeechRecognitionStopped(bool forced) override;
NewScreencastPrecondition GetNewScreencastPrecondition() const override;
void CreateScreencastContainerFolder(
CreateScreencastContainerFolderCallback callback);
void OnNewScreencastPreconditionChanged();
void SetProjectorMetadataControllerForTest(
std::unique_ptr<ProjectorMetadataController> metadata_controller);
void SetOnPathDeletedCallbackForTest(OnPathDeletedCallback callback);
void SetOnFileSavedCallbackForTest(OnFileSavedCallback callback);
ProjectorUiController* ui_controller() { return ui_controller_.get(); }
ProjectorSessionImpl* projector_session() { return projector_session_.get(); }
void OnAudioNodesChanged() override;
void OnRecordingStarted(aura::Window* current_root) override;
void OnRecordingEnded() override;
void OnVideoFileFinalized(bool user_deleted_video_file,
const gfx::ImageSkia& thumbnail) override;
void OnRecordedWindowChangingRoot(aura::Window* new_root) override;
void OnRecordingStartAborted() override;
base::OneShotTimer* get_timer_for_testing() {
return &force_stop_recognition_timer_;
}
private:
enum class SpeechRecognitionState {
kRecognitionNotStarted = 0,
kRecognitionStarted = 1,
kRecognitionStopping = 2,
kRecognitionError = 3,
};
void OnProjectorSessionActiveStateChanged(bool active) override;
bool IsInputDeviceAvailable() const;
void StartSpeechRecognition();
void MaybeStopSpeechRecognition();
void ForceEndSpeechRecognition();
void OnSessionStartAttempted(const base::SafeBaseName& storage_dir,
bool success);
void OnContainerFolderCreated(
const base::FilePath& path,
CreateScreencastContainerFolderCallback callback,
bool success);
void SaveScreencast();
void SaveThumbnailFile(const gfx::ImageSkia& thumbnail);
void CleanupContainerFolder();
void MaybeWrapUpRecording();
std::vector<base::FilePath> GetScreencastFilePaths() const;
raw_ptr<ProjectorClient, DanglingUntriaged> client_ = nullptr;
std::unique_ptr<ProjectorSessionImpl> projector_session_;
std::unique_ptr<ProjectorUiController> ui_controller_;
std::unique_ptr<ProjectorMetadataController> metadata_controller_;
SpeechRecognitionState speech_recognition_state_ =
SpeechRecognitionState::kRecognitionNotStarted;
bool use_on_device_speech_recognition = false;
bool dlp_restriction_checked_completed_ = false;
bool user_deleted_video_file_ = false;
OnPathDeletedCallback on_path_deleted_callback_;
OnFileSavedCallback on_file_saved_callback_;
base::OneShotTimer force_stop_recognition_timer_;
base::WeakPtrFactory<ProjectorControllerImpl> weak_factory_{this};
};
}
#endif