blob: ae6276cf77a273a3fce244c8651f3a7e231e18d8 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_CAPTURE_DRIVER_H_
#define CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_CAPTURE_DRIVER_H_
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/thumbnails/thumbnail_readiness_tracker.h"
#include "chrome/browser/ui/thumbnails/thumbnail_scheduler.h"
class ThumbnailCaptureDriver : public ThumbnailScheduler::TabCapturer {
public:
class Client {
public:
// Asks the client to prepare for capture. The client should reply
// by calling SetCanCapture(true) when ready.
virtual void RequestCapture() = 0;
// Begin capturing and updating the thumbnail immediately. This will
// not be called unless SetCanCapture(true) was called. The client
// should call GotFrame() whenever it gets a new frame from capture.
virtual void StartCapture() = 0;
// Stop capturing and cancel previous RequestCapture() call.
virtual void StopCapture() = 0;
protected:
// Not deleted through interface pointer.
~Client() = default;
};
using PageReadiness = ThumbnailReadinessTracker::Readiness;
explicit ThumbnailCaptureDriver(Client* client,
ThumbnailScheduler* scheduler);
~ThumbnailCaptureDriver() override;
// Update the capture state machine with new data.
void UpdatePageReadiness(PageReadiness page_readiness);
void UpdatePageVisibility(bool page_visible);
void UpdateThumbnailVisibility(bool thumbnail_visible);
// Can be called whenever. Will not issue a Client::StartCapture()
// call if this is false. If set to false during capture, assumes the
// capture stopped but the request is still outstanding. On the next
// call with true, may immediately issue a Client::StartCapture()
// call.
void SetCanCapture(bool can_capture);
// Notify scheduler a frame was received during capture.
void GotFrame();
// ThumbnailScheduler:
void SetCapturePermittedByScheduler(bool scheduled) override;
// Determines how long to wait for final capture, and how many times
// to retry if one is not received. Exposed for testing.
static constexpr base::TimeDelta kCooldownDelay = base::Milliseconds(500);
static constexpr size_t kMaxCooldownRetries = 3;
private:
// How far along we are in the capture lifecycle for a given page.
enum class CaptureState : int {
// We have not started capturing the current page.
kNoCapture = 0,
// We have asked to capture but haven't started yet.
kCaptureRequested,
// We are currently capturing.
kCapturing,
// We are attempting to capture our last frame.
kCooldown,
// We have a good capture of the final page.
kHaveFinalCapture,
};
void UpdateSchedulingPriority();
void UpdateCaptureState();
void StartCooldown();
void OnCooldownEnded();
const raw_ptr<Client> client_;
const raw_ptr<ThumbnailScheduler> scheduler_;
PageReadiness page_readiness_ = PageReadiness::kNotReady;
bool page_visible_ = false;
bool thumbnail_visible_ = false;
bool can_capture_ = false;
bool scheduled_ = false;
CaptureState capture_state_ = CaptureState::kNoCapture;
// Has a frame been captured during cooldown?
bool captured_cooldown_frame_ = false;
size_t cooldown_retry_count_ = 0U;
base::RetainingOneShotTimer cooldown_timer_;
base::WeakPtrFactory<ThumbnailCaptureDriver> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_UI_THUMBNAILS_THUMBNAIL_CAPTURE_DRIVER_H_