xref: /aosp_15_r20/external/cronet/base/memory/post_delayed_memory_reduction_task.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_MEMORY_POST_DELAYED_MEMORY_REDUCTION_TASK_H_
6 #define BASE_MEMORY_POST_DELAYED_MEMORY_REDUCTION_TASK_H_
7 
8 #include "base/task/sequenced_task_runner.h"
9 
10 namespace base {
11 
12 // Context in which a memory reduction task is invoked.
13 enum class MemoryReductionTaskContext {
14   // After the expiration of its delay.
15   kDelayExpired,
16   // Before the expiration of its delay, to proactively reduce memory.
17   kProactive,
18 };
19 
20 // This API should be used for posting delayed tasks that reduce memory usage
21 // while Chrome is backgrounded. On Android 14+, tasks posted this way may be
22 // run before the delay is elapsed, in the case where Chrome is about to be
23 // frozen by Android. On other platforms, this is equivalent to directly posting
24 // the delayed task, using the task runner.
25 void BASE_EXPORT
26 PostDelayedMemoryReductionTask(scoped_refptr<SequencedTaskRunner> task_runner,
27                                const Location& from_here,
28                                OnceClosure task,
29                                base::TimeDelta delay);
30 
31 // Same as above, but passes a parameter to the task, depending on how it was
32 // run. On non-Android platforms, will always pass |kDelayExpired|.
33 void BASE_EXPORT PostDelayedMemoryReductionTask(
34     scoped_refptr<SequencedTaskRunner> task_runner,
35     const Location& from_here,
36     OnceCallback<void(MemoryReductionTaskContext)> task,
37     base::TimeDelta delay);
38 
39 // Replacement for |OneShotTimer|, that allows the tasks to be run by
40 // |OnPreFreeze| (see |PreFreezeBackgroundMemoryTrimmer| above).
41 class BASE_EXPORT OneShotDelayedBackgroundTimer final {
42  public:
43   OneShotDelayedBackgroundTimer();
44   ~OneShotDelayedBackgroundTimer();
45 
46   void Stop();
47 
Start(const Location & posted_from,TimeDelta delay,OnceClosure task)48   void Start(const Location& posted_from, TimeDelta delay, OnceClosure task) {
49     Start(posted_from, delay,
50           BindOnce(
51               [](OnceClosure task,
52                  MemoryReductionTaskContext called_from_prefreeze) {
53                 std::move(task).Run();
54               },
55               std::move(task)));
56   }
57   void Start(const Location& posted_from,
58              TimeDelta delay,
59              OnceCallback<void(MemoryReductionTaskContext)> task);
60 
61   bool IsRunning() const;
62 
63   template <class Receiver>
Start(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())64   void Start(const Location& posted_from,
65              TimeDelta delay,
66              Receiver* receiver,
67              void (Receiver::*method)()) {
68     Start(posted_from, delay, BindOnce(method, Unretained(receiver)));
69   }
70 
71   void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner);
72 
73  private:
74   class OneShotDelayedBackgroundTimerImpl {
75    public:
76     virtual ~OneShotDelayedBackgroundTimerImpl() = default;
77     virtual void Stop() = 0;
78     virtual void Start(const Location& posted_from,
79                        TimeDelta delay,
80                        OnceCallback<void(MemoryReductionTaskContext)> task) = 0;
81     virtual bool IsRunning() const = 0;
82     virtual void SetTaskRunner(
83         scoped_refptr<SequencedTaskRunner> task_runner) = 0;
84   };
85 
86 #if BUILDFLAG(IS_ANDROID)
87   friend class android::PreFreezeBackgroundMemoryTrimmer;
88 #endif
89   class TimerImpl;
90   class TaskImpl;
91 
92   std::unique_ptr<OneShotDelayedBackgroundTimerImpl> impl_;
93 };
94 
95 }  // namespace base
96 
97 #endif  // BASE_MEMORY_POST_DELAYED_MEMORY_REDUCTION_TASK_H_
98