// Copyright 2023 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_AUTOFILL_ANDROID_TOUCH_TO_FILL_KEYBOARD_SUPPRESSOR_H_ #define COMPONENTS_AUTOFILL_ANDROID_TOUCH_TO_FILL_KEYBOARD_SUPPRESSOR_H_ #include "base/memory/weak_ptr.h" #include "base/scoped_multi_source_observation.h" #include "base/scoped_observation.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" namespace autofill { class ContentAutofillClient; // Suppresses the Android IME. // // If a TTF surface intends to be displayed, it must suppress the keyboard // preemptively before Autofill has parsed the form. Otherwise, the keyboard // could be displayed while Autofill is parsing the form, which would lead to // flickering. // // TouchToFillKeyboardSuppressor takes two callbacks from a TTF controller: // - `is_showing()` returns true iff the TTF is currently shown; // - `intends_to_show()` returns true iff the TTF is intended to be shown // once parsing is completed. // // With TouchToFillKeyboardSuppressor, the controller can implement the // following behavior: // // +--------------------------------------------------------+ // | After parsing: controller wants to show TTF? | // +--------------------------+-----------------------------+ // | No | Yes | // +----------+-----+--------------------------+-----------------------------+ // | Before | No | Don't suppress. | // | parsing: | | Don't show TTF. | // | con- +-----+--------------------------+-----------------------------+ // | troller | Yes | Suppress before parsing. | Suppress before parsing. | // | intends | | Unsuppress after parsing | Unsuppress after timeout if | // | to show | | or after timeout. | parsing is slow. Otherwise, | // | TTF? | | Don't show TTF. | show TTF, then unsuppress. | // +----------+-----+--------------------------+-----------------------------+ // // The timeout mechanism is intended for cases where parsing takes extremely // long. // // The TTF controller must satisfy the following conditions: // - The `is_showing()` callback must be true after parsing only if // `is_showing() || intends_to_show()` has been true before parsing. // - The TTF controller must show the TTF only if `is_suppressing()` is true. // - The TTF controller must call `Unsuppress()` after the TTF was shown. // // The lifecycle of a TouchToFillKeyboardSuppressor must be aligned to the // lifecycle of a tab (represented here by a ContentAutofillClient). // It must be created before any ContentAutofillDrivers of the tab have been // created: it won't suppress the keyboard in frames that were created already. // // TouchToFillKeyboardSuppressor observes all AutofillManagers of a given tab // (represented by the ContentAutofillClient). The event structure is this: // 1. AutofillManager::Observer::OnBeforeAskForValuesToFill(). // 2. Asynchronous parsing. // 3. Controller's shows TTF only if // - `intends_to_show()` had been true in Step 1, and // - `is_suppressing()` is true now. // 4. AutofillManager::Observer::OnAfterAskForValuesToFill(). class TouchToFillKeyboardSuppressor : public ContentAutofillDriverFactory::Observer, public AutofillManager::Observer { … }; } // namespace autofill #endif // COMPONENTS_AUTOFILL_ANDROID_TOUCH_TO_FILL_KEYBOARD_SUPPRESSOR_H_