xref: /aosp_15_r20/external/cronet/base/message_loop/message_pump.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/message_loop/message_pump_type.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
18*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker namespace base {
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker class TimeTicks;
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT MessagePump {
25*6777b538SAndroid Build Coastguard Worker  public:
26*6777b538SAndroid Build Coastguard Worker   using MessagePumpFactory = std::unique_ptr<MessagePump>();
27*6777b538SAndroid Build Coastguard Worker   // Uses the given base::MessagePumpFactory to override the default MessagePump
28*6777b538SAndroid Build Coastguard Worker   // implementation for 'MessagePumpType::UI'. May only be called once.
29*6777b538SAndroid Build Coastguard Worker   static void OverrideMessagePumpForUIFactory(MessagePumpFactory* factory);
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker   // Returns true if the MessagePumpForUI has been overidden.
32*6777b538SAndroid Build Coastguard Worker   static bool IsMessagePumpForUIFactoryOveridden();
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker   static void InitializeFeatures();
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker   // Manage the state of |kAlignWakeUps| and the leeway of the process.
37*6777b538SAndroid Build Coastguard Worker   static void OverrideAlignWakeUpsState(bool enabled, TimeDelta leeway);
38*6777b538SAndroid Build Coastguard Worker   static void ResetAlignWakeUpsState();
39*6777b538SAndroid Build Coastguard Worker   static bool GetAlignWakeUpsEnabled();
40*6777b538SAndroid Build Coastguard Worker   static TimeDelta GetLeewayIgnoringThreadOverride();
41*6777b538SAndroid Build Coastguard Worker   static TimeDelta GetLeewayForCurrentThread();
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker   // Creates the default MessagePump based on |type|. Caller owns return value.
44*6777b538SAndroid Build Coastguard Worker   static std::unique_ptr<MessagePump> Create(MessagePumpType type);
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker   // Please see the comments above the Run method for an illustration of how
47*6777b538SAndroid Build Coastguard Worker   // these delegate methods are used.
48*6777b538SAndroid Build Coastguard Worker   class BASE_EXPORT Delegate {
49*6777b538SAndroid Build Coastguard Worker    public:
50*6777b538SAndroid Build Coastguard Worker     virtual ~Delegate() = default;
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker     struct NextWorkInfo {
53*6777b538SAndroid Build Coastguard Worker       // Helper to extract a TimeDelta for pumps that need a
54*6777b538SAndroid Build Coastguard Worker       // timeout-till-next-task.
remaining_delayNextWorkInfo55*6777b538SAndroid Build Coastguard Worker       TimeDelta remaining_delay() const {
56*6777b538SAndroid Build Coastguard Worker         DCHECK(!delayed_run_time.is_null() && !delayed_run_time.is_max());
57*6777b538SAndroid Build Coastguard Worker         DCHECK_GE(TimeTicks::Now(), recent_now);
58*6777b538SAndroid Build Coastguard Worker         return delayed_run_time - recent_now;
59*6777b538SAndroid Build Coastguard Worker       }
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker       // Helper to verify if the next task is ready right away.
is_immediateNextWorkInfo62*6777b538SAndroid Build Coastguard Worker       bool is_immediate() const { return delayed_run_time.is_null(); }
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker       // The next PendingTask's |delayed_run_time|. is_null() if there's extra
65*6777b538SAndroid Build Coastguard Worker       // work to run immediately. is_max() if there are no more immediate nor
66*6777b538SAndroid Build Coastguard Worker       // delayed tasks.
67*6777b538SAndroid Build Coastguard Worker       TimeTicks delayed_run_time;
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker       // |leeway| determines the preferred time range for scheduling
70*6777b538SAndroid Build Coastguard Worker       // work. A larger leeway provides more freedom to schedule work at
71*6777b538SAndroid Build Coastguard Worker       // an optimal time for power consumption. This field is ignored
72*6777b538SAndroid Build Coastguard Worker       // for immediate work.
73*6777b538SAndroid Build Coastguard Worker       TimeDelta leeway;
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker       // A recent view of TimeTicks::Now(). Only valid if |delayed_run_time|
76*6777b538SAndroid Build Coastguard Worker       // isn't null nor max. MessagePump impls should use remaining_delay()
77*6777b538SAndroid Build Coastguard Worker       // instead of resampling Now() if they wish to sleep for a TimeDelta.
78*6777b538SAndroid Build Coastguard Worker       TimeTicks recent_now;
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker       // If true, native messages should be processed before executing more work
81*6777b538SAndroid Build Coastguard Worker       // from the Delegate. This is an optional hint; not all message pumps
82*6777b538SAndroid Build Coastguard Worker       // implement this.
83*6777b538SAndroid Build Coastguard Worker       bool yield_to_native = false;
84*6777b538SAndroid Build Coastguard Worker     };
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker     // Executes an immediate task or a ripe delayed task. Returns information
87*6777b538SAndroid Build Coastguard Worker     // about when DoWork() should be called again. If the returned NextWorkInfo
88*6777b538SAndroid Build Coastguard Worker     // is_immediate(), DoWork() must be invoked again shortly. Else, DoWork()
89*6777b538SAndroid Build Coastguard Worker     // must be invoked at |NextWorkInfo::delayed_run_time| or when
90*6777b538SAndroid Build Coastguard Worker     // ScheduleWork() is invoked, whichever comes first. Redundant/spurious
91*6777b538SAndroid Build Coastguard Worker     // invocations of DoWork() outside of those requirements are tolerated.
92*6777b538SAndroid Build Coastguard Worker     // DoIdleWork() will not be called so long as this returns a NextWorkInfo
93*6777b538SAndroid Build Coastguard Worker     // which is_immediate().
94*6777b538SAndroid Build Coastguard Worker     virtual NextWorkInfo DoWork() = 0;
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker     // Called from within Run just before the message pump goes to sleep.
97*6777b538SAndroid Build Coastguard Worker     // Returns true to indicate that idle work was done; in which case Run()
98*6777b538SAndroid Build Coastguard Worker     // should resume with calling DoWork(). Returning false means the pump
99*6777b538SAndroid Build Coastguard Worker     // should now wait.
100*6777b538SAndroid Build Coastguard Worker     virtual bool DoIdleWork() = 0;
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker     class ScopedDoWorkItem {
103*6777b538SAndroid Build Coastguard Worker      public:
ScopedDoWorkItem()104*6777b538SAndroid Build Coastguard Worker       ScopedDoWorkItem() : outer_(nullptr), work_item_depth_(0) {}
105*6777b538SAndroid Build Coastguard Worker 
~ScopedDoWorkItem()106*6777b538SAndroid Build Coastguard Worker       ~ScopedDoWorkItem() {
107*6777b538SAndroid Build Coastguard Worker         if (outer_) {
108*6777b538SAndroid Build Coastguard Worker           outer_->OnEndWorkItem(work_item_depth_);
109*6777b538SAndroid Build Coastguard Worker         }
110*6777b538SAndroid Build Coastguard Worker       }
111*6777b538SAndroid Build Coastguard Worker 
ScopedDoWorkItem(ScopedDoWorkItem && rhs)112*6777b538SAndroid Build Coastguard Worker       ScopedDoWorkItem(ScopedDoWorkItem&& rhs)
113*6777b538SAndroid Build Coastguard Worker           : outer_(std::exchange(rhs.outer_, nullptr)),
114*6777b538SAndroid Build Coastguard Worker             work_item_depth_(rhs.work_item_depth_) {}
115*6777b538SAndroid Build Coastguard Worker       ScopedDoWorkItem& operator=(ScopedDoWorkItem&& rhs) {
116*6777b538SAndroid Build Coastguard Worker         // We should only ever go from an empty ScopedDoWorkItem to an
117*6777b538SAndroid Build Coastguard Worker         // initialized one, or from an initialized one to an empty one.
118*6777b538SAndroid Build Coastguard Worker         CHECK_NE(IsNull(), rhs.IsNull());
119*6777b538SAndroid Build Coastguard Worker         // Since we're overwriting this ScopedDoWorkItem, we need to record its
120*6777b538SAndroid Build Coastguard Worker         // destruction.
121*6777b538SAndroid Build Coastguard Worker         if (outer_) {
122*6777b538SAndroid Build Coastguard Worker           outer_->OnEndWorkItem(work_item_depth_);
123*6777b538SAndroid Build Coastguard Worker         }
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker         work_item_depth_ = rhs.work_item_depth_;
126*6777b538SAndroid Build Coastguard Worker         outer_ = std::exchange(rhs.outer_, nullptr);
127*6777b538SAndroid Build Coastguard Worker         return *this;
128*6777b538SAndroid Build Coastguard Worker       }
129*6777b538SAndroid Build Coastguard Worker 
IsNull()130*6777b538SAndroid Build Coastguard Worker       bool IsNull() { return !outer_; }
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker      private:
133*6777b538SAndroid Build Coastguard Worker       friend Delegate;
134*6777b538SAndroid Build Coastguard Worker 
ScopedDoWorkItem(Delegate * outer)135*6777b538SAndroid Build Coastguard Worker       explicit ScopedDoWorkItem(Delegate* outer) : outer_(outer) {
136*6777b538SAndroid Build Coastguard Worker         outer_->OnBeginWorkItem();
137*6777b538SAndroid Build Coastguard Worker         work_item_depth_ = outer_->RunDepth();
138*6777b538SAndroid Build Coastguard Worker       }
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker       // `outer_` is not a raw_ptr<...> for performance reasons (based on
141*6777b538SAndroid Build Coastguard Worker       // analysis of sampling profiler data and tab_search:top100:2020).
142*6777b538SAndroid Build Coastguard Worker       RAW_PTR_EXCLUSION Delegate* outer_;
143*6777b538SAndroid Build Coastguard Worker 
144*6777b538SAndroid Build Coastguard Worker       // Records the run level at which this DoWorkItem was created to allow
145*6777b538SAndroid Build Coastguard Worker       // detection of exits of nested loops.
146*6777b538SAndroid Build Coastguard Worker       int work_item_depth_;
147*6777b538SAndroid Build Coastguard Worker     };
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker     // Called before a unit of work is executed. This allows reports
150*6777b538SAndroid Build Coastguard Worker     // about individual units of work to be produced. The unit of work ends when
151*6777b538SAndroid Build Coastguard Worker     // the returned ScopedDoWorkItem goes out of scope.
152*6777b538SAndroid Build Coastguard Worker     // TODO(crbug.com/851163): Place calls for all platforms. Without this, some
153*6777b538SAndroid Build Coastguard Worker     // state like the top-level "ThreadController active" trace event will not
154*6777b538SAndroid Build Coastguard Worker     // be correct when work is performed.
BeginWorkItem()155*6777b538SAndroid Build Coastguard Worker     [[nodiscard]] ScopedDoWorkItem BeginWorkItem() {
156*6777b538SAndroid Build Coastguard Worker       return ScopedDoWorkItem(this);
157*6777b538SAndroid Build Coastguard Worker     }
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker     // Called before the message pump starts waiting for work. This indicates
160*6777b538SAndroid Build Coastguard Worker     // that the message pump is idle (out of application work and ideally out of
161*6777b538SAndroid Build Coastguard Worker     // native work -- if it can tell).
162*6777b538SAndroid Build Coastguard Worker     virtual void BeforeWait() = 0;
163*6777b538SAndroid Build Coastguard Worker 
164*6777b538SAndroid Build Coastguard Worker     // May be called when starting to process native work and it is guaranteed
165*6777b538SAndroid Build Coastguard Worker     // that DoWork() will be called again before sleeping. Allows the delegate
166*6777b538SAndroid Build Coastguard Worker     // to skip unnecessary ScheduleWork() calls.
167*6777b538SAndroid Build Coastguard Worker     virtual void BeginNativeWorkBeforeDoWork() = 0;
168*6777b538SAndroid Build Coastguard Worker 
169*6777b538SAndroid Build Coastguard Worker     // Returns the nesting level at which the Delegate is currently running.
170*6777b538SAndroid Build Coastguard Worker     virtual int RunDepth() = 0;
171*6777b538SAndroid Build Coastguard Worker 
172*6777b538SAndroid Build Coastguard Worker    private:
173*6777b538SAndroid Build Coastguard Worker     // Called upon entering/exiting a ScopedDoWorkItem.
174*6777b538SAndroid Build Coastguard Worker     virtual void OnBeginWorkItem() = 0;
175*6777b538SAndroid Build Coastguard Worker     virtual void OnEndWorkItem(int work_item_depth) = 0;
176*6777b538SAndroid Build Coastguard Worker   };
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker   MessagePump();
179*6777b538SAndroid Build Coastguard Worker   virtual ~MessagePump();
180*6777b538SAndroid Build Coastguard Worker 
181*6777b538SAndroid Build Coastguard Worker   // The Run method is called to enter the message pump's run loop.
182*6777b538SAndroid Build Coastguard Worker   //
183*6777b538SAndroid Build Coastguard Worker   // Within the method, the message pump is responsible for processing native
184*6777b538SAndroid Build Coastguard Worker   // messages as well as for giving cycles to the delegate periodically. The
185*6777b538SAndroid Build Coastguard Worker   // message pump should take care to mix delegate callbacks with native message
186*6777b538SAndroid Build Coastguard Worker   // processing so neither type of event starves the other of cycles. Each call
187*6777b538SAndroid Build Coastguard Worker   // to a delegate function is considered the beginning of a new "unit of work".
188*6777b538SAndroid Build Coastguard Worker   //
189*6777b538SAndroid Build Coastguard Worker   // The anatomy of a typical run loop:
190*6777b538SAndroid Build Coastguard Worker   //
191*6777b538SAndroid Build Coastguard Worker   //   for (;;) {
192*6777b538SAndroid Build Coastguard Worker   //     bool did_native_work = false;
193*6777b538SAndroid Build Coastguard Worker   //     {
194*6777b538SAndroid Build Coastguard Worker   //       auto scoped_do_work_item = state_->delegate->BeginWorkItem();
195*6777b538SAndroid Build Coastguard Worker   //       did_native_work = DoNativeWork();
196*6777b538SAndroid Build Coastguard Worker   //     }
197*6777b538SAndroid Build Coastguard Worker   //     if (should_quit_)
198*6777b538SAndroid Build Coastguard Worker   //       break;
199*6777b538SAndroid Build Coastguard Worker   //
200*6777b538SAndroid Build Coastguard Worker   //     Delegate::NextWorkInfo next_work_info = delegate->DoWork();
201*6777b538SAndroid Build Coastguard Worker   //     if (should_quit_)
202*6777b538SAndroid Build Coastguard Worker   //       break;
203*6777b538SAndroid Build Coastguard Worker   //
204*6777b538SAndroid Build Coastguard Worker   //     if (did_native_work || next_work_info.is_immediate())
205*6777b538SAndroid Build Coastguard Worker   //       continue;
206*6777b538SAndroid Build Coastguard Worker   //
207*6777b538SAndroid Build Coastguard Worker   //     bool did_idle_work = delegate_->DoIdleWork();
208*6777b538SAndroid Build Coastguard Worker   //     if (should_quit_)
209*6777b538SAndroid Build Coastguard Worker   //       break;
210*6777b538SAndroid Build Coastguard Worker   //
211*6777b538SAndroid Build Coastguard Worker   //     if (did_idle_work)
212*6777b538SAndroid Build Coastguard Worker   //       continue;
213*6777b538SAndroid Build Coastguard Worker   //
214*6777b538SAndroid Build Coastguard Worker   //     WaitForWork();
215*6777b538SAndroid Build Coastguard Worker   //   }
216*6777b538SAndroid Build Coastguard Worker   //
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker   // Here, DoNativeWork is some private method of the message pump that is
219*6777b538SAndroid Build Coastguard Worker   // responsible for dispatching the next UI message or notifying the next IO
220*6777b538SAndroid Build Coastguard Worker   // completion (for example).  WaitForWork is a private method that simply
221*6777b538SAndroid Build Coastguard Worker   // blocks until there is more work of any type to do.
222*6777b538SAndroid Build Coastguard Worker   //
223*6777b538SAndroid Build Coastguard Worker   // Notice that the run loop cycles between calling DoNativeWork and DoWork
224*6777b538SAndroid Build Coastguard Worker   // methods. This helps ensure that none of these work queues starve the
225*6777b538SAndroid Build Coastguard Worker   // others. This is important for message pumps that are used to drive
226*6777b538SAndroid Build Coastguard Worker   // animations, for example.
227*6777b538SAndroid Build Coastguard Worker   //
228*6777b538SAndroid Build Coastguard Worker   // Notice also that after each callout to foreign code, the run loop checks to
229*6777b538SAndroid Build Coastguard Worker   // see if it should quit.  The Quit method is responsible for setting this
230*6777b538SAndroid Build Coastguard Worker   // flag.  No further work is done once the quit flag is set.
231*6777b538SAndroid Build Coastguard Worker   //
232*6777b538SAndroid Build Coastguard Worker   // NOTE 1: Run may be called reentrantly from any of the callouts to foreign
233*6777b538SAndroid Build Coastguard Worker   // code (internal work, DoWork, DoIdleWork). As a result, DoWork and
234*6777b538SAndroid Build Coastguard Worker   // DoIdleWork must be reentrant.
235*6777b538SAndroid Build Coastguard Worker   //
236*6777b538SAndroid Build Coastguard Worker   // NOTE 2: Run implementations must arrange for DoWork to be invoked as
237*6777b538SAndroid Build Coastguard Worker   // expected if a callout to foreign code enters a message pump outside their
238*6777b538SAndroid Build Coastguard Worker   // control. For example, the MessageBox API on Windows pumps UI messages. If
239*6777b538SAndroid Build Coastguard Worker   // the MessageBox API is called (indirectly) from within Run, it is expected
240*6777b538SAndroid Build Coastguard Worker   // that DoWork will be invoked from within that call in response to
241*6777b538SAndroid Build Coastguard Worker   // ScheduleWork or as requested by the last NextWorkInfo returned by DoWork.
242*6777b538SAndroid Build Coastguard Worker   // The MessagePump::Delegate may then elect to do nested work or not depending
243*6777b538SAndroid Build Coastguard Worker   // on its policy in that context. Regardless of that decision (and return
244*6777b538SAndroid Build Coastguard Worker   // value of the nested DoWork() call), DoWork() will be invoked again when the
245*6777b538SAndroid Build Coastguard Worker   // nested loop unwinds.
246*6777b538SAndroid Build Coastguard Worker   virtual void Run(Delegate* delegate) = 0;
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker   // Quit immediately from the most recently entered run loop.  This method may
249*6777b538SAndroid Build Coastguard Worker   // only be used on the thread that called Run.
250*6777b538SAndroid Build Coastguard Worker   virtual void Quit() = 0;
251*6777b538SAndroid Build Coastguard Worker 
252*6777b538SAndroid Build Coastguard Worker   // Schedule a DoWork callback to happen reasonably soon.  Does nothing if a
253*6777b538SAndroid Build Coastguard Worker   // DoWork callback is already scheduled. Once this call is made, DoWork is
254*6777b538SAndroid Build Coastguard Worker   // guaranteed to be called repeatedly at least until it returns a
255*6777b538SAndroid Build Coastguard Worker   // non-immediate NextWorkInfo. This call can be expensive and callers should
256*6777b538SAndroid Build Coastguard Worker   // attempt not to invoke it again before a non-immediate NextWorkInfo was
257*6777b538SAndroid Build Coastguard Worker   // returned from DoWork(). Thread-safe (and callers should avoid holding a
258*6777b538SAndroid Build Coastguard Worker   // Lock at all cost while making this call as some platforms' priority
259*6777b538SAndroid Build Coastguard Worker   // boosting features have been observed to cause the caller to get descheduled
260*6777b538SAndroid Build Coastguard Worker   // : https://crbug.com/890978).
261*6777b538SAndroid Build Coastguard Worker   virtual void ScheduleWork() = 0;
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker   // Schedule a DoWork callback to happen at the specified time, cancelling any
264*6777b538SAndroid Build Coastguard Worker   // pending callback scheduled by this method. This method may only be used on
265*6777b538SAndroid Build Coastguard Worker   // the thread that called Run.
266*6777b538SAndroid Build Coastguard Worker   //
267*6777b538SAndroid Build Coastguard Worker   // It isn't necessary to call this during normal execution, as the pump wakes
268*6777b538SAndroid Build Coastguard Worker   // up as requested by the return value of DoWork().
269*6777b538SAndroid Build Coastguard Worker   // TODO(crbug.com/885371): Determine if this must be called to ensure that
270*6777b538SAndroid Build Coastguard Worker   // delayed tasks run when a message pump outside the control of Run is
271*6777b538SAndroid Build Coastguard Worker   // entered.
272*6777b538SAndroid Build Coastguard Worker   virtual void ScheduleDelayedWork(
273*6777b538SAndroid Build Coastguard Worker       const Delegate::NextWorkInfo& next_work_info) = 0;
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker   // Returns an adjusted |run_time| based on alignment policies of the pump.
276*6777b538SAndroid Build Coastguard Worker   virtual TimeTicks AdjustDelayedRunTime(TimeTicks earliest_time,
277*6777b538SAndroid Build Coastguard Worker                                          TimeTicks run_time,
278*6777b538SAndroid Build Coastguard Worker                                          TimeTicks latest_time);
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker   // Requests the pump to handle either the likely imminent creation (`true`) or
281*6777b538SAndroid Build Coastguard Worker   // destruction (`false`) of a native nested loop in which application tasks
282*6777b538SAndroid Build Coastguard Worker   // are desired to be run. The pump should override and return `true` if it
283*6777b538SAndroid Build Coastguard Worker   // supports this call and has scheduled work in response. The default
284*6777b538SAndroid Build Coastguard Worker   // implementation returns `false` and does nothing.
285*6777b538SAndroid Build Coastguard Worker   virtual bool HandleNestedNativeLoopWithApplicationTasks(
286*6777b538SAndroid Build Coastguard Worker       bool application_tasks_desired);
287*6777b538SAndroid Build Coastguard Worker };
288*6777b538SAndroid Build Coastguard Worker 
289*6777b538SAndroid Build Coastguard Worker }  // namespace base
290*6777b538SAndroid Build Coastguard Worker 
291*6777b538SAndroid Build Coastguard Worker #endif  // BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
292