// Copyright 2014 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.

#ifndef COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
#define COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_

#include "base/atomicops.h"
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "components/scheduler/base/pollable_thread_safe_flag.h"
#include "components/scheduler/child/idle_helper.h"
#include "components/scheduler/child/scheduler_helper.h"
#include "components/scheduler/renderer/deadline_task_runner.h"
#include "components/scheduler/renderer/idle_time_estimator.h"
#include "components/scheduler/renderer/render_widget_signals.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
#include "components/scheduler/renderer/task_cost_estimator.h"
#include "components/scheduler/renderer/throttling_helper.h"
#include "components/scheduler/renderer/user_model.h"
#include "components/scheduler/renderer/web_view_scheduler_impl.h"
#include "components/scheduler/scheduler_export.h"

namespace base {
namespace trace_event {
class ConvertableToTraceFormat;
}
}

namespace scheduler {
class RenderWidgetSchedulingState;
class WebViewSchedulerImpl;
class ThrottlingHelper;

class SCHEDULER_EXPORT RendererSchedulerImpl
    : public RendererScheduler,
      public IdleHelper::Delegate,
      public SchedulerHelper::Observer,
      public RenderWidgetSignals::Observer {
 public:
  RendererSchedulerImpl(scoped_refptr<SchedulerTqmDelegate> main_task_runner);
  ~RendererSchedulerImpl() override;

  // RendererScheduler implementation:
  scoped_ptr<blink::WebThread> CreateMainThread() override;
  scoped_refptr<TaskQueue> DefaultTaskRunner() override;
  scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override;
  scoped_refptr<TaskQueue> CompositorTaskRunner() override;
  scoped_refptr<TaskQueue> LoadingTaskRunner() override;
  scoped_refptr<TaskQueue> TimerTaskRunner() override;
  scoped_refptr<TaskQueue> NewLoadingTaskRunner(const char* name) override;
  scoped_refptr<TaskQueue> NewTimerTaskRunner(const char* name) override;
  scoped_ptr<RenderWidgetSchedulingState> NewRenderWidgetSchedulingState()
      override;
  void WillBeginFrame(const cc::BeginFrameArgs& args) override;
  void BeginFrameNotExpectedSoon() override;
  void DidCommitFrameToCompositor() override;
  void DidHandleInputEventOnCompositorThread(
      const blink::WebInputEvent& web_input_event,
      InputEventState event_state) override;
  void DidHandleInputEventOnMainThread(
      const blink::WebInputEvent& web_input_event) override;
  void DidAnimateForInputOnCompositorThread() override;
  void OnRendererBackgrounded() override;
  void OnRendererForegrounded() override;
  void AddPendingNavigation() override;
  void RemovePendingNavigation() override;
  void OnNavigationStarted() override;
  bool IsHighPriorityWorkAnticipated() override;
  bool ShouldYieldForHighPriorityWork() override;
  bool CanExceedIdleDeadlineIfRequired() const override;
  void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
  void RemoveTaskObserver(
      base::MessageLoop::TaskObserver* task_observer) override;
  void Shutdown() override;
  void SuspendTimerQueue() override;
  void ResumeTimerQueue() override;
  void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) override;

  // RenderWidgetSignals::Observer implementation:
  void SetAllRenderWidgetsHidden(bool hidden) override;
  void SetHasVisibleRenderWidgetWithTouchHandler(
      bool has_visible_render_widget_with_touch_handler) override;

  // SchedulerHelper::Observer implementation:
  void OnUnregisterTaskQueue(const scoped_refptr<TaskQueue>& queue) override;
  void OnTriedToExecuteBlockedTask(const TaskQueue& queue,
                                   const base::PendingTask& task) override;

  // Returns a task runner where tasks run at the highest possible priority.
  scoped_refptr<TaskQueue> ControlTaskRunner();

  void RegisterTimeDomain(TimeDomain* time_domain);
  void UnregisterTimeDomain(TimeDomain* time_domain);

  void SetExpensiveTaskBlockingAllowed(bool allowed);

  void AddWebViewScheduler(WebViewSchedulerImpl* web_view_scheduler);
  void RemoveWebViewScheduler(WebViewSchedulerImpl* web_view_scheduler);

  // Test helpers.
  SchedulerHelper* GetSchedulerHelperForTesting();
  TaskCostEstimator* GetLoadingTaskCostEstimatorForTesting();
  TaskCostEstimator* GetTimerTaskCostEstimatorForTesting();
  IdleTimeEstimator* GetIdleTimeEstimatorForTesting();
  base::TimeTicks CurrentIdleTaskDeadlineForTesting() const;

  base::TickClock* tick_clock() const;

  RealTimeDomain* real_time_domain() const {
    return helper_.real_time_domain();
  }

  ThrottlingHelper* throttling_helper() { return throttling_helper_.get(); }

 private:
  friend class RendererSchedulerImplTest;
  friend class RendererSchedulerImplForTest;
  friend class RenderWidgetSchedulingState;

  enum class TimeDomainType {
    REAL,
    THROTTLED,
  };

  struct TaskQueuePolicy {
    TaskQueuePolicy()
        : is_enabled(true),
          priority(TaskQueue::NORMAL_PRIORITY),
          time_domain_type(TimeDomainType::REAL) {}

    bool is_enabled;
    TaskQueue::QueuePriority priority;
    TimeDomainType time_domain_type;

    bool operator==(const TaskQueuePolicy& other) const {
      return is_enabled == other.is_enabled && priority == other.priority &&
             time_domain_type == other.time_domain_type;
    }
  };

  struct Policy {
    TaskQueuePolicy compositor_queue_policy;
    TaskQueuePolicy loading_queue_policy;
    TaskQueuePolicy timer_queue_policy;
    TaskQueuePolicy default_queue_policy;

    bool operator==(const Policy& other) const {
      return compositor_queue_policy == other.compositor_queue_policy &&
             loading_queue_policy == other.loading_queue_policy &&
             timer_queue_policy == other.timer_queue_policy &&
             default_queue_policy == other.default_queue_policy;
    }
  };

  class PollableNeedsUpdateFlag {
   public:
    PollableNeedsUpdateFlag(base::Lock* write_lock);
    ~PollableNeedsUpdateFlag();

    // Set the flag. May only be called if |write_lock| is held.
    void SetWhileLocked(bool value);

    // Returns true iff the flag is set to true.
    bool IsSet() const;

   private:
    base::subtle::Atomic32 flag_;
    base::Lock* write_lock_;  // Not owned.

    DISALLOW_COPY_AND_ASSIGN(PollableNeedsUpdateFlag);
  };

  // IdleHelper::Delegate implementation:
  bool CanEnterLongIdlePeriod(
      base::TimeTicks now,
      base::TimeDelta* next_long_idle_period_delay_out) override;
  void IsNotQuiescent() override {}
  void OnIdlePeriodStarted() override;
  void OnIdlePeriodEnded() override;

  void EndIdlePeriod();

  // Returns the serialized scheduler state for tracing.
  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue(
      base::TimeTicks optional_now) const;
  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked(
      base::TimeTicks optional_now) const;

  static bool ShouldPrioritizeInputEvent(
      const blink::WebInputEvent& web_input_event);

  // The amount of time which idle periods can continue being scheduled when the
  // renderer has been hidden, before going to sleep for good.
  static const int kEndIdleWhenHiddenDelayMillis = 10000;

  // The amount of time for which loading tasks will be prioritized over
  // other tasks during the initial page load.
  static const int kRailsInitialLoadingPrioritizationMillis = 1000;

  // The amount of time in milliseconds we have to respond to user input as
  // defined by RAILS.
  static const int kRailsResponseTimeMillis = 50;

  // For the purposes of deciding whether or not it's safe to turn timers and
  // loading tasks on only in idle periods, we regard the system as being as
  // being "idle period" starved if there hasn't been an idle period in the last
  // 10 seconds. This was chosen to be long enough to cover most anticipated
  // user gestures.
  static const int kIdlePeriodStarvationThresholdMillis = 10000;

  // The amount of time to wait before suspending shared timers after the
  // renderer has been backgrounded. This is used only if background suspension
  // of shared timers is enabled.
  static const int kSuspendTimersWhenBackgroundedDelayMillis = 5 * 60 * 1000;

  // The time we should stay in a priority-escalated mode after a call to
  // DidAnimateForInputOnCompositorThread().
  static const int kFlingEscalationLimitMillis = 100;

  // Schedules an immediate PolicyUpdate, if there isn't one already pending and
  // sets |policy_may_need_update_|. Note |any_thread_lock_| must be
  // locked.
  void EnsureUrgentPolicyUpdatePostedOnMainThread(
      const tracked_objects::Location& from_here);

  // Update the policy if a new signal has arrived. Must be called from the main
  // thread.
  void MaybeUpdatePolicy();

  // Locks |any_thread_lock_| and updates the scheduler policy.  May early
  // out if the policy is unchanged. Must be called from the main thread.
  void UpdatePolicy();

  // Like UpdatePolicy, except it doesn't early out.
  void ForceUpdatePolicy();

  enum class UpdateType {
    MAY_EARLY_OUT_IF_POLICY_UNCHANGED,
    FORCE_UPDATE,
  };

  // The implelemtation of UpdatePolicy & ForceUpdatePolicy.  It is allowed to
  // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED.
  virtual void UpdatePolicyLocked(UpdateType update_type);

  // Helper for computing the use case. |expected_usecase_duration| will be
  // filled with the amount of time after which the use case should be updated
  // again. If the duration is zero, a new use case update should not be
  // scheduled. Must be called with |any_thread_lock_| held. Can be called from
  // any thread.
  UseCase ComputeCurrentUseCase(
      base::TimeTicks now,
      base::TimeDelta* expected_use_case_duration) const;

  // Works out if a gesture appears to be in progress based on the current
  // input signals. Can be called from any thread.
  bool InputSignalsSuggestGestureInProgress(base::TimeTicks now) const;

  // An input event of some sort happened, the policy may need updating.
  void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type,
                                             InputEventState input_event_state);

  // Returns true if there has been at least one idle period in the last
  // |kIdlePeriodStarvationThresholdMillis|.
  bool HadAnIdlePeriodRecently(base::TimeTicks now) const;

  // Helpers for safely suspending/resuming the timer queue after a
  // background/foreground signal.
  void SuspendTimerQueueWhenBackgrounded();
  void ResumeTimerQueueWhenForegrounded();

  // The task cost estimators and the UserModel need to be reset upon page
  // nagigation. This function does that. Must be called from the main thread.
  void ResetForNavigationLocked();

  // Estimates the maximum task length that won't cause a jank based on the
  // current system state. Must be called from the main thread.
  base::TimeDelta EstimateLongestJankFreeTaskDuration() const;

  // Log a console warning message to all WebViews in this process.
  void BroadcastConsoleWarning(const std::string& message);

  void ApplyTaskQueuePolicy(TaskQueue* task_queue,
                            const TaskQueuePolicy& old_task_queue_policy,
                            const TaskQueuePolicy& new_task_queue_policy) const;

  SchedulerHelper helper_;
  IdleHelper idle_helper_;
  scoped_ptr<ThrottlingHelper> throttling_helper_;
  RenderWidgetSignals render_widget_scheduler_signals_;

  const scoped_refptr<TaskQueue> control_task_runner_;
  const scoped_refptr<TaskQueue> compositor_task_runner_;
  std::set<scoped_refptr<TaskQueue>> loading_task_runners_;
  std::set<scoped_refptr<TaskQueue>> timer_task_runners_;
  scoped_refptr<TaskQueue> default_loading_task_runner_;
  scoped_refptr<TaskQueue> default_timer_task_runner_;

  base::Closure update_policy_closure_;
  DeadlineTaskRunner delayed_update_policy_runner_;
  CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
  CancelableClosureHolder suspend_timers_when_backgrounded_closure_;

  // We have decided to improve thread safety at the cost of some boilerplate
  // (the accessors) for the following data members.

  struct MainThreadOnly {
    MainThreadOnly(const scoped_refptr<TaskQueue>& compositor_task_runner,
                   base::TickClock* time_source);
    ~MainThreadOnly();

    TaskCostEstimator loading_task_cost_estimator;
    TaskCostEstimator timer_task_cost_estimator;
    IdleTimeEstimator idle_time_estimator;
    UseCase current_use_case;
    Policy current_policy;
    base::TimeTicks current_policy_expiration_time;
    base::TimeTicks estimated_next_frame_begin;
    base::TimeDelta compositor_frame_interval;
    base::TimeDelta longest_jank_free_task_duration;
    int timer_queue_suspend_count;  // TIMER_TASK_QUEUE suspended if non-zero.
    int navigation_task_expected_count;
    bool renderer_hidden;
    bool renderer_backgrounded;
    bool timer_queue_suspension_when_backgrounded_enabled;
    bool timer_queue_suspended_when_backgrounded;
    bool was_shutdown;
    bool loading_tasks_seem_expensive;
    bool timer_tasks_seem_expensive;
    bool touchstart_expected_soon;
    bool have_seen_a_begin_main_frame;
    bool have_reported_blocking_intervention_in_current_policy;
    bool have_reported_blocking_intervention_since_navigation;
    bool has_visible_render_widget_with_touch_handler;
    bool begin_frame_not_expected_soon;
    bool expensive_task_blocking_allowed;
    std::set<WebViewSchedulerImpl*> web_view_schedulers_;  // Not owned.
  };

  struct AnyThread {
    AnyThread();
    ~AnyThread();

    base::TimeTicks last_idle_period_end_time;
    base::TimeTicks rails_loading_priority_deadline;
    base::TimeTicks fling_compositor_escalation_deadline;
    UserModel user_model;
    bool awaiting_touch_start_response;
    bool in_idle_period;
    bool begin_main_frame_on_critical_path;
    bool last_gesture_was_compositor_driven;
    bool have_seen_touchstart;
  };

  struct CompositorThreadOnly {
    CompositorThreadOnly();
    ~CompositorThreadOnly();

    blink::WebInputEvent::Type last_input_type;
    scoped_ptr<base::ThreadChecker> compositor_thread_checker;

    void CheckOnValidThread() {
#if DCHECK_IS_ON()
      // We don't actually care which thread this called from, just so long as
      // its consistent.
      if (!compositor_thread_checker)
        compositor_thread_checker.reset(new base::ThreadChecker());
      DCHECK(compositor_thread_checker->CalledOnValidThread());
#endif
    }
  };

  // Don't access main_thread_only_, instead use MainThreadOnly().
  MainThreadOnly main_thread_only_;
  MainThreadOnly& MainThreadOnly() {
    helper_.CheckOnValidThread();
    return main_thread_only_;
  }
  const struct MainThreadOnly& MainThreadOnly() const {
    helper_.CheckOnValidThread();
    return main_thread_only_;
  }

  mutable base::Lock any_thread_lock_;
  // Don't access any_thread_, instead use AnyThread().
  AnyThread any_thread_;
  AnyThread& AnyThread() {
    any_thread_lock_.AssertAcquired();
    return any_thread_;
  }
  const struct AnyThread& AnyThread() const {
    any_thread_lock_.AssertAcquired();
    return any_thread_;
  }

  // Don't access compositor_thread_only_, instead use CompositorThreadOnly().
  CompositorThreadOnly compositor_thread_only_;
  CompositorThreadOnly& CompositorThreadOnly() {
    compositor_thread_only_.CheckOnValidThread();
    return compositor_thread_only_;
  }

  PollableThreadSafeFlag policy_may_need_update_;
  base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl);
};

}  // namespace scheduler

#endif  // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
