blob: cbf0844a7b5b7461bebb0b7ba9b950f965cef41e [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/input_hint_checker.h"
#include "base/base_jni/InputHintChecker_jni.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/no_destructor.h"
#include "base/time/time.h"
namespace base::android {
namespace {
bool g_input_hint_enabled;
base::TimeDelta g_poll_interval;
InputHintChecker* g_test_instance;
} // namespace
// Whether to fetch the input hint from the system. When disabled, pretends
// that no input is ever queued.
BASE_EXPORT
BASE_FEATURE(kYieldWithInputHint,
"YieldWithInputHint",
base::FEATURE_DISABLED_BY_DEFAULT);
// Min time delta between checks for the input hint. Must be a smaller than
// time to produce a frame, but a bit longer than the time it takes to retrieve
// the hint.
const base::FeatureParam<int> kPollIntervalMillisParam{&kYieldWithInputHint,
"poll_interval_ms", 3};
// static
void InputHintChecker::InitializeFeatures() {
bool is_enabled = base::FeatureList::IsEnabled(kYieldWithInputHint);
g_input_hint_enabled = is_enabled;
if (is_enabled) {
g_poll_interval = Milliseconds(kPollIntervalMillisParam.Get());
}
}
bool InputHintChecker::HasInputImplWithThrottling() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto now = base::TimeTicks::Now();
if (last_checked_.is_null() || (now - last_checked_) >= g_poll_interval) {
last_checked_ = now;
// TODO(pasko): Implement fetching the hint from the system.
return false;
}
return false;
}
void InputHintChecker::SetView(JNIEnv* env, jobject root_view) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
view_ = JavaObjectWeakGlobalRef(env, root_view);
}
// static
bool InputHintChecker::HasInput() {
if (!g_input_hint_enabled) {
return false;
}
return GetInstance().HasInputImplWithThrottling();
}
InputHintChecker& InputHintChecker::GetInstance() {
static NoDestructor<InputHintChecker> checker;
if (g_test_instance) {
return *g_test_instance;
}
return *checker.get();
}
InputHintChecker::ScopedOverrideInstance::ScopedOverrideInstance(
InputHintChecker* checker) {
g_test_instance = checker;
}
InputHintChecker::ScopedOverrideInstance::~ScopedOverrideInstance() {
g_test_instance = nullptr;
}
void JNI_InputHintChecker_SetView(_JNIEnv* env,
const JavaParamRef<jobject>& v) {
InputHintChecker::GetInstance().SetView(env, v.obj());
}
} // namespace base::android