xref: /aosp_15_r20/external/cronet/base/android/input_hint_checker.cc (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 #include "base/android/input_hint_checker.h"
6 
7 #include "base/base_jni/InputHintChecker_jni.h"
8 #include "base/feature_list.h"
9 #include "base/metrics/field_trial_params.h"
10 #include "base/no_destructor.h"
11 #include "base/time/time.h"
12 
13 namespace base::android {
14 
15 namespace {
16 
17 bool g_input_hint_enabled;
18 base::TimeDelta g_poll_interval;
19 InputHintChecker* g_test_instance;
20 
21 }  // namespace
22 
23 // Whether to fetch the input hint from the system. When disabled, pretends
24 // that no input is ever queued.
25 BASE_EXPORT
26 BASE_FEATURE(kYieldWithInputHint,
27              "YieldWithInputHint",
28              base::FEATURE_DISABLED_BY_DEFAULT);
29 
30 // Min time delta between checks for the input hint. Must be a smaller than
31 // time to produce a frame, but a bit longer than the time it takes to retrieve
32 // the hint.
33 const base::FeatureParam<int> kPollIntervalMillisParam{&kYieldWithInputHint,
34                                                        "poll_interval_ms", 3};
35 
36 // static
InitializeFeatures()37 void InputHintChecker::InitializeFeatures() {
38   bool is_enabled = base::FeatureList::IsEnabled(kYieldWithInputHint);
39   g_input_hint_enabled = is_enabled;
40   if (is_enabled) {
41     g_poll_interval = Milliseconds(kPollIntervalMillisParam.Get());
42   }
43 }
44 
HasInputImplWithThrottling()45 bool InputHintChecker::HasInputImplWithThrottling() {
46   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
47   auto now = base::TimeTicks::Now();
48   if (last_checked_.is_null() || (now - last_checked_) >= g_poll_interval) {
49     last_checked_ = now;
50     // TODO(pasko): Implement fetching the hint from the system.
51     return false;
52   }
53   return false;
54 }
55 
SetView(JNIEnv * env,jobject root_view)56 void InputHintChecker::SetView(JNIEnv* env, jobject root_view) {
57   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
58   view_ = JavaObjectWeakGlobalRef(env, root_view);
59 }
60 
61 // static
HasInput()62 bool InputHintChecker::HasInput() {
63   if (!g_input_hint_enabled) {
64     return false;
65   }
66   return GetInstance().HasInputImplWithThrottling();
67 }
68 
GetInstance()69 InputHintChecker& InputHintChecker::GetInstance() {
70   static NoDestructor<InputHintChecker> checker;
71   if (g_test_instance) {
72     return *g_test_instance;
73   }
74   return *checker.get();
75 }
76 
ScopedOverrideInstance(InputHintChecker * checker)77 InputHintChecker::ScopedOverrideInstance::ScopedOverrideInstance(
78     InputHintChecker* checker) {
79   g_test_instance = checker;
80 }
81 
~ScopedOverrideInstance()82 InputHintChecker::ScopedOverrideInstance::~ScopedOverrideInstance() {
83   g_test_instance = nullptr;
84 }
85 
JNI_InputHintChecker_SetView(_JNIEnv * env,const JavaParamRef<jobject> & v)86 void JNI_InputHintChecker_SetView(_JNIEnv* env,
87                                   const JavaParamRef<jobject>& v) {
88   InputHintChecker::GetInstance().SetView(env, v.obj());
89 }
90 
91 }  // namespace base::android
92