Avi Drissman | 3e1a26c | 2022-09-15 20:26:03 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
jaekyun | e4f9eed | 2015-02-24 02:06:58 | [diff] [blame] | 5 | #ifndef UI_ANDROID_WINDOW_ANDROID_H_ |
| 6 | #define UI_ANDROID_WINDOW_ANDROID_H_ |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 7 | |
| 8 | #include <jni.h> |
Khushal Sagar | 931bd7de | 2024-07-18 21:25:23 | [diff] [blame] | 9 | |
eseckler | 8c15fc3 | 2016-12-20 20:22:20 | [diff] [blame] | 10 | #include <memory> |
tedchoc | c1718be | 2015-07-10 00:37:11 | [diff] [blame] | 11 | #include <string> |
tfarina | 93bfa91 | 2014-12-05 14:23:15 | [diff] [blame] | 12 | |
newt@chromium.org | 6a718ab | 2014-04-23 20:01:20 | [diff] [blame] | 13 | #include "base/android/jni_weak_ref.h" |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 14 | #include "base/android/scoped_java_ref.h" |
Avi Drissman | c149c16 | 2023-01-12 02:16:59 | [diff] [blame] | 15 | #include "base/functional/callback.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 16 | #include "base/memory/raw_ptr.h" |
powei@chromium.org | aca40ac | 2013-11-21 21:35:28 | [diff] [blame] | 17 | #include "base/observer_list.h" |
sievers@chromium.org | f22e4584 | 2014-04-29 23:40:32 | [diff] [blame] | 18 | #include "base/time/time.h" |
Aman Verma | f16361d | 2023-07-10 18:04:04 | [diff] [blame] | 19 | #include "third_party/blink/public/common/page/content_to_visible_time_reporter.h" |
Khushal Sagar | 931bd7de | 2024-07-18 21:25:23 | [diff] [blame] | 20 | #include "ui/android/progress_bar_config.h" |
jaekyun | e4f9eed | 2015-02-24 02:06:58 | [diff] [blame] | 21 | #include "ui/android/ui_android_export.h" |
sievers | 481b7fe | 2016-07-21 17:03:59 | [diff] [blame] | 22 | #include "ui/android/view_android.h" |
tfarina | 93bfa91 | 2014-12-05 14:23:15 | [diff] [blame] | 23 | #include "ui/gfx/geometry/vector2d_f.h" |
sangheon77.kim | dd441f9 | 2022-08-31 01:15:08 | [diff] [blame] | 24 | #include "ui/gfx/overlay_transform.h" |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 25 | |
timav | fe53c2c6 | 2016-11-23 02:35:46 | [diff] [blame] | 26 | namespace display { |
Bo Liu | 71ca79cb | 2019-02-26 18:01:24 | [diff] [blame] | 27 | class Display; |
timav | fe53c2c6 | 2016-11-23 02:35:46 | [diff] [blame] | 28 | class DisplayAndroidManager; |
eseckler | 8c15fc3 | 2016-12-20 20:22:20 | [diff] [blame] | 29 | } // namespace display |
timav | fe53c2c6 | 2016-11-23 02:35:46 | [diff] [blame] | 30 | |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 31 | namespace ui { |
| 32 | |
Jinsuk Kim | 7ba8f240 | 2018-05-04 20:44:36 | [diff] [blame] | 33 | extern UI_ANDROID_EXPORT const float kDefaultMouseWheelTickMultiplier; |
Jinsuk Kim | 00e4698 | 2018-03-07 07:54:36 | [diff] [blame] | 34 | |
William Liu | 7e940dd | 2024-09-12 13:16:44 | [diff] [blame] | 35 | class ModalDialogManagerBridge; |
powei@chromium.org | 0809f7e2 | 2014-03-20 00:05:45 | [diff] [blame] | 36 | class WindowAndroidCompositor; |
powei@chromium.org | aca40ac | 2013-11-21 21:35:28 | [diff] [blame] | 37 | class WindowAndroidObserver; |
| 38 | |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 39 | // Android implementation of the activity window. |
sievers | 481b7fe | 2016-07-21 17:03:59 | [diff] [blame] | 40 | // WindowAndroid is also the root of a ViewAndroid tree. |
| 41 | class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid { |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 42 | public: |
William Liu | 196e5aa | 2024-10-01 18:27:09 | [diff] [blame] | 43 | // Intended for unittests only. |
Michael Thiessen | f42f9f3 | 2022-02-03 22:23:06 | [diff] [blame] | 44 | class ScopedWindowAndroidForTesting { |
| 45 | public: |
| 46 | ScopedWindowAndroidForTesting(WindowAndroid* window); |
| 47 | ~ScopedWindowAndroidForTesting(); |
| 48 | |
| 49 | WindowAndroid* get() { return window_; } |
| 50 | |
Joel Hockey | 18f767a | 2024-08-20 03:23:44 | [diff] [blame] | 51 | void SetModalDialogManager( |
| 52 | base::android::ScopedJavaLocalRef<jobject> modal_dialog_manager); |
| 53 | |
Michael Thiessen | f42f9f3 | 2022-02-03 22:23:06 | [diff] [blame] | 54 | private: |
| 55 | raw_ptr<WindowAndroid> window_; |
| 56 | }; |
| 57 | |
Bo Liu | 15828fe4 | 2025-03-13 01:34:44 | [diff] [blame] | 58 | struct AdaptiveRefreshRateInfo { |
| 59 | bool supports_adaptive_refresh_rate = false; |
| 60 | // Fields below are valid only if `supports_adaptive_refresh_rate` is true. |
Bo Liu | 15828fe4 | 2025-03-13 01:34:44 | [diff] [blame] | 61 | float suggested_frame_rate_high = 0.f; |
Bo Liu | 15828fe4 | 2025-03-13 01:34:44 | [diff] [blame] | 62 | |
| 63 | AdaptiveRefreshRateInfo(); |
| 64 | AdaptiveRefreshRateInfo(const AdaptiveRefreshRateInfo& other); |
| 65 | ~AdaptiveRefreshRateInfo(); |
| 66 | AdaptiveRefreshRateInfo& operator=(const AdaptiveRefreshRateInfo& other); |
| 67 | }; |
| 68 | |
Michael Thiessen | 4c05f2a9 | 2018-01-11 00:37:26 | [diff] [blame] | 69 | static WindowAndroid* FromJavaWindowAndroid( |
| 70 | const base::android::JavaParamRef<jobject>& jwindow_android); |
| 71 | |
Khushal | 5187432 | 2019-04-18 23:55:40 | [diff] [blame] | 72 | WindowAndroid(JNIEnv* env, |
Andrew Grieve | 88b4c5fb | 2025-07-17 17:06:47 | [diff] [blame] | 73 | const base::android::JavaRef<jobject>& obj, |
Khushal | 5187432 | 2019-04-18 23:55:40 | [diff] [blame] | 74 | int display_id, |
| 75 | float scroll_factor, |
| 76 | bool window_is_wide_color_gamut); |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 77 | |
Peter BostrÃļm | c8c12353 | 2021-09-21 23:37:15 | [diff] [blame] | 78 | WindowAndroid(const WindowAndroid&) = delete; |
| 79 | WindowAndroid& operator=(const WindowAndroid&) = delete; |
| 80 | |
Jinsuk Kim | d5d29a2 | 2017-08-29 01:39:44 | [diff] [blame] | 81 | ~WindowAndroid() override; |
| 82 | |
Andrew Grieve | 474183fd | 2025-07-02 15:47:10 | [diff] [blame] | 83 | void Destroy(JNIEnv* env); |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 84 | |
| 85 | base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); |
| 86 | |
powei@chromium.org | 0809f7e2 | 2014-03-20 00:05:45 | [diff] [blame] | 87 | void AttachCompositor(WindowAndroidCompositor* compositor); |
powei@chromium.org | aca40ac | 2013-11-21 21:35:28 | [diff] [blame] | 88 | void DetachCompositor(); |
| 89 | |
| 90 | void AddObserver(WindowAndroidObserver* observer); |
| 91 | void RemoveObserver(WindowAndroidObserver* observer); |
| 92 | |
powei@chromium.org | 0809f7e2 | 2014-03-20 00:05:45 | [diff] [blame] | 93 | WindowAndroidCompositor* GetCompositor() { return compositor_; } |
Khushal | a042481 | 2019-03-13 10:05:43 | [diff] [blame] | 94 | float GetRefreshRate(); |
sangheon77.kim | dd441f9 | 2022-08-31 01:15:08 | [diff] [blame] | 95 | gfx::OverlayTransform GetOverlayTransform(); |
Khushal | 5187432 | 2019-04-18 23:55:40 | [diff] [blame] | 96 | std::vector<float> GetSupportedRefreshRates(); |
Bo Liu | 15828fe4 | 2025-03-13 01:34:44 | [diff] [blame] | 97 | AdaptiveRefreshRateInfo adaptive_refresh_rate_info() const { |
| 98 | return adaptive_refresh_rate_info_; |
| 99 | } |
Khushal | 5187432 | 2019-04-18 23:55:40 | [diff] [blame] | 100 | void SetPreferredRefreshRate(float refresh_rate); |
powei@chromium.org | 0809f7e2 | 2014-03-20 00:05:45 | [diff] [blame] | 101 | |
sievers@chromium.org | 41256cd | 2014-05-27 22:45:34 | [diff] [blame] | 102 | void SetNeedsAnimate(); |
jdduke | 566c0f3 | 2015-07-23 00:39:51 | [diff] [blame] | 103 | void Animate(base::TimeTicks begin_frame_time); |
torne | bb13c833 | 2015-12-07 12:49:14 | [diff] [blame] | 104 | void OnVisibilityChanged(JNIEnv* env, |
torne | bb13c833 | 2015-12-07 12:49:14 | [diff] [blame] | 105 | bool visible); |
Andrew Grieve | 474183fd | 2025-07-02 15:47:10 | [diff] [blame] | 106 | void OnActivityStopped(JNIEnv* env); |
| 107 | void OnActivityStarted(JNIEnv* env); |
Khushal | a042481 | 2019-03-13 10:05:43 | [diff] [blame] | 108 | void OnUpdateRefreshRate(JNIEnv* env, |
Khushal | a042481 | 2019-03-13 10:05:43 | [diff] [blame] | 109 | float refresh_rate); |
Khushal | 019a87ec | 2019-03-21 03:41:47 | [diff] [blame] | 110 | void OnSupportedRefreshRatesUpdated( |
| 111 | JNIEnv* env, |
Khushal | 019a87ec | 2019-03-21 03:41:47 | [diff] [blame] | 112 | const base::android::JavaParamRef<jfloatArray>& supported_refresh_rates); |
Bo Liu | efb3dcf | 2025-04-26 04:35:27 | [diff] [blame] | 113 | void OnAdaptiveRefreshRateInfoChanged(JNIEnv* env, |
| 114 | jboolean supports_adaptive_refresh_rate, |
| 115 | jfloat suggested_frame_rate_high); |
Andrew Grieve | 474183fd | 2025-07-02 15:47:10 | [diff] [blame] | 116 | void OnOverlayTransformUpdated(JNIEnv* env); |
Aman Verma | f16361d | 2023-07-10 18:04:04 | [diff] [blame] | 117 | void SendUnfoldLatencyBeginTimestamp(JNIEnv* env, jlong begin_time); |
sievers@chromium.org | f22e4584 | 2014-04-29 23:40:32 | [diff] [blame] | 118 | |
Abdelrahman Eed | 0c78621 | 2025-03-12 10:22:32 | [diff] [blame] | 119 | void OnWindowPointerLockRelease(JNIEnv* env); |
| 120 | |
Daniil Hrybchuk | 5f32662 | 2025-09-12 07:42:09 | [diff] [blame] | 121 | void OnWindowPositionChanged(JNIEnv* env); |
| 122 | |
Charles Hager | d3c47be | 2025-01-29 06:15:59 | [diff] [blame] | 123 | void ShowToast(const std::string text); |
| 124 | |
tedchoc | c1718be | 2015-07-10 00:37:11 | [diff] [blame] | 125 | // Return whether the specified Android permission is granted. |
| 126 | bool HasPermission(const std::string& permission); |
| 127 | // Return whether the specified Android permission can be requested by Chrome. |
| 128 | bool CanRequestPermission(const std::string& permission); |
| 129 | |
Khushal Sagar | 931bd7de | 2024-07-18 21:25:23 | [diff] [blame] | 130 | void set_progress_bar_config_for_testing(ProgressBarConfig config) { |
| 131 | progress_bar_config_for_testing_ = config; |
| 132 | } |
| 133 | ProgressBarConfig GetProgressBarConfig(); |
| 134 | |
William Liu | 7e940dd | 2024-09-12 13:16:44 | [diff] [blame] | 135 | ModalDialogManagerBridge* GetModalDialogManagerBridge(); |
| 136 | |
William Liu | 196e5aa | 2024-10-01 18:27:09 | [diff] [blame] | 137 | // Intended for native browser tests. |
| 138 | void SetModalDialogManagerForTesting( |
| 139 | base::android::ScopedJavaLocalRef<jobject> java_modal_dialog_manager); |
| 140 | |
Jinsuk Kim | 4583ba5 | 2018-03-14 04:58:56 | [diff] [blame] | 141 | float mouse_wheel_scroll_factor() const { return mouse_wheel_scroll_factor_; } |
Jinsuk Kim | 00e4698 | 2018-03-07 07:54:36 | [diff] [blame] | 142 | |
Michael Thiessen | f42f9f3 | 2022-02-03 22:23:06 | [diff] [blame] | 143 | static std::unique_ptr<ScopedWindowAndroidForTesting> CreateForTesting(); |
gsennton | 44b7044 | 2015-11-17 12:44:12 | [diff] [blame] | 144 | |
Bo Liu | 71ca79cb | 2019-02-26 18:01:24 | [diff] [blame] | 145 | // This should return the same Display as Screen::GetDisplayNearestWindow |
| 146 | // except the color space depends on the status of this particular window |
| 147 | // rather than the display itself. |
| 148 | // See comment on WindowAndroid.getWindowIsWideColorGamut for details. |
| 149 | display::Display GetDisplayWithWindowColorSpace(); |
| 150 | |
Chris Blume | a584614 | 2020-04-22 07:38:12 | [diff] [blame] | 151 | void SetWideColorEnabled(bool enabled); |
| 152 | |
Abdelrahman Eed | e154433 | 2025-03-06 11:59:08 | [diff] [blame] | 153 | bool RequestPointerLock(ViewAndroid& view_android); |
| 154 | |
| 155 | bool HasPointerLock(ViewAndroid& view_android); |
| 156 | |
| 157 | void ReleasePointerLock(ViewAndroid& view_android); |
| 158 | |
Nate Chapin | 789fc8c | 2025-08-01 17:31:32 | [diff] [blame] | 159 | bool SetHasKeyboardCapture(bool keyboard_capture); |
| 160 | |
Bartosz Chominski | af491556 | 2025-08-25 18:31:43 | [diff] [blame] | 161 | std::optional<gfx::Rect> GetBoundsInScreenCoordinates(); |
| 162 | |
Khushal | c98fcadd9 | 2019-04-22 18:47:29 | [diff] [blame] | 163 | class TestHooks { |
| 164 | public: |
| 165 | virtual ~TestHooks() = default; |
| 166 | virtual std::vector<float> GetSupportedRates() = 0; |
| 167 | virtual void SetPreferredRate(float refresh_rate) = 0; |
| 168 | }; |
| 169 | void SetTestHooks(TestHooks* hooks); |
| 170 | |
Khushal | 942ed34 | 2019-05-24 19:33:49 | [diff] [blame] | 171 | class ScopedSelectionHandles { |
| 172 | public: |
| 173 | ScopedSelectionHandles(WindowAndroid* window); |
| 174 | ~ScopedSelectionHandles(); |
| 175 | |
| 176 | private: |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 177 | raw_ptr<WindowAndroid> window_; |
Khushal | 942ed34 | 2019-05-24 19:33:49 | [diff] [blame] | 178 | }; |
| 179 | |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 180 | private: |
eseckler | 8c15fc3 | 2016-12-20 20:22:20 | [diff] [blame] | 181 | class WindowBeginFrameSource; |
Bo Liu | ca28fc1c | 2018-11-02 23:03:50 | [diff] [blame] | 182 | class ScopedOnBeginFrame; |
timav | fe53c2c6 | 2016-11-23 02:35:46 | [diff] [blame] | 183 | friend class DisplayAndroidManager; |
eseckler | 8c15fc3 | 2016-12-20 20:22:20 | [diff] [blame] | 184 | friend class WindowBeginFrameSource; |
timav | fe53c2c6 | 2016-11-23 02:35:46 | [diff] [blame] | 185 | |
Khushal | 019a87ec | 2019-03-21 03:41:47 | [diff] [blame] | 186 | void Force60HzRefreshRateIfNeeded(); |
eseckler | 8c15fc3 | 2016-12-20 20:22:20 | [diff] [blame] | 187 | |
sievers | 481b7fe | 2016-07-21 17:03:59 | [diff] [blame] | 188 | // ViewAndroid overrides. |
| 189 | WindowAndroid* GetWindowAndroid() const override; |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 190 | |
timav | fe53c2c6 | 2016-11-23 02:35:46 | [diff] [blame] | 191 | // The ID of the display that this window belongs to. |
| 192 | int display_id() const { return display_id_; } |
| 193 | |
boliu | f1c913e | 2015-03-25 14:49:10 | [diff] [blame] | 194 | base::android::ScopedJavaGlobalRef<jobject> java_window_; |
timav | fe53c2c6 | 2016-11-23 02:35:46 | [diff] [blame] | 195 | const int display_id_; |
Bo Liu | 71ca79cb | 2019-02-26 18:01:24 | [diff] [blame] | 196 | const bool window_is_wide_color_gamut_; |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 197 | raw_ptr<WindowAndroidCompositor> compositor_; |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 198 | |
Khushal Sagar | 931bd7de | 2024-07-18 21:25:23 | [diff] [blame] | 199 | std::optional<ProgressBarConfig> progress_bar_config_for_testing_; |
| 200 | |
Trent Apted | a250ec3ab | 2018-08-19 08:52:19 | [diff] [blame] | 201 | base::ObserverList<WindowAndroidObserver>::Unchecked observer_list_; |
Aman Verma | f16361d | 2023-07-10 18:04:04 | [diff] [blame] | 202 | blink::ContentToVisibleTimeReporter content_to_visible_time_recorder_; |
powei@chromium.org | aca40ac | 2013-11-21 21:35:28 | [diff] [blame] | 203 | |
Jinsuk Kim | 4583ba5 | 2018-03-14 04:58:56 | [diff] [blame] | 204 | float mouse_wheel_scroll_factor_; |
eseckler | 8c15fc3 | 2016-12-20 20:22:20 | [diff] [blame] | 205 | |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 206 | raw_ptr<TestHooks> test_hooks_ = nullptr; |
Khushal | 019a87ec | 2019-03-21 03:41:47 | [diff] [blame] | 207 | |
Khushal | 942ed34 | 2019-05-24 19:33:49 | [diff] [blame] | 208 | int selection_handles_active_count_ = 0; |
Abdelrahman Eed | e154433 | 2025-03-06 11:59:08 | [diff] [blame] | 209 | |
| 210 | raw_ptr<ViewAndroid> pointer_locking_view_ = nullptr; |
Bo Liu | 15828fe4 | 2025-03-13 01:34:44 | [diff] [blame] | 211 | |
| 212 | AdaptiveRefreshRateInfo adaptive_refresh_rate_info_; |
aurimas@chromium.org | 2d02a200 | 2012-09-18 21:47:56 | [diff] [blame] | 213 | }; |
| 214 | |
| 215 | } // namespace ui |
| 216 | |
jaekyun | e4f9eed | 2015-02-24 02:06:58 | [diff] [blame] | 217 | #endif // UI_ANDROID_WINDOW_ANDROID_H_ |