window_android.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/android/window_android.h"
  5. #include <utility>
  6. #include <vector>
  7. #include "base/android/jni_android.h"
  8. #include "base/android/jni_array.h"
  9. #include "base/android/jni_string.h"
  10. #include "base/android/jni_weak_ref.h"
  11. #include "base/android/scoped_java_ref.h"
  12. #include "base/observer_list.h"
  13. #include "ui/android/display_android_manager.h"
  14. #include "ui/android/ui_android_jni_headers/WindowAndroid_jni.h"
  15. #include "ui/android/window_android_compositor.h"
  16. #include "ui/android/window_android_observer.h"
  17. #include "ui/base/ui_base_features.h"
  18. namespace ui {
  19. using base::android::AttachCurrentThread;
  20. using base::android::JavaParamRef;
  21. using base::android::JavaRef;
  22. using base::android::ScopedJavaLocalRef;
  23. const float kDefaultMouseWheelTickMultiplier = 64;
  24. WindowAndroid::ScopedSelectionHandles::ScopedSelectionHandles(
  25. WindowAndroid* window)
  26. : window_(window) {
  27. if (++window_->selection_handles_active_count_ == 1) {
  28. JNIEnv* env = AttachCurrentThread();
  29. Java_WindowAndroid_onSelectionHandlesStateChanged(
  30. env, window_->GetJavaObject(), true /* active */);
  31. }
  32. }
  33. WindowAndroid::ScopedSelectionHandles::~ScopedSelectionHandles() {
  34. DCHECK_GT(window_->selection_handles_active_count_, 0);
  35. if (--window_->selection_handles_active_count_ == 0) {
  36. JNIEnv* env = AttachCurrentThread();
  37. Java_WindowAndroid_onSelectionHandlesStateChanged(
  38. env, window_->GetJavaObject(), false /* active */);
  39. }
  40. }
  41. WindowAndroid::ScopedWindowAndroidForTesting::ScopedWindowAndroidForTesting(
  42. WindowAndroid* window)
  43. : window_(window) {}
  44. WindowAndroid::ScopedWindowAndroidForTesting::~ScopedWindowAndroidForTesting() {
  45. JNIEnv* env = AttachCurrentThread();
  46. Java_WindowAndroid_destroy(env, window_->GetJavaObject());
  47. }
  48. // static
  49. WindowAndroid* WindowAndroid::FromJavaWindowAndroid(
  50. const JavaParamRef<jobject>& jwindow_android) {
  51. if (jwindow_android.is_null())
  52. return nullptr;
  53. return reinterpret_cast<WindowAndroid*>(Java_WindowAndroid_getNativePointer(
  54. AttachCurrentThread(), jwindow_android));
  55. }
  56. WindowAndroid::WindowAndroid(JNIEnv* env,
  57. jobject obj,
  58. int display_id,
  59. float scroll_factor,
  60. bool window_is_wide_color_gamut)
  61. : display_id_(display_id),
  62. window_is_wide_color_gamut_(window_is_wide_color_gamut),
  63. compositor_(nullptr) {
  64. java_window_.Reset(env, obj);
  65. mouse_wheel_scroll_factor_ =
  66. scroll_factor > 0 ? scroll_factor
  67. : kDefaultMouseWheelTickMultiplier * GetDipScale();
  68. }
  69. void WindowAndroid::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
  70. delete this;
  71. }
  72. ScopedJavaLocalRef<jobject> WindowAndroid::GetJavaObject() {
  73. return base::android::ScopedJavaLocalRef<jobject>(java_window_);
  74. }
  75. WindowAndroid::~WindowAndroid() {
  76. DCHECK(parent_ == nullptr) << "WindowAndroid must be a root view.";
  77. DCHECK(!compositor_);
  78. RemoveAllChildren(true);
  79. Java_WindowAndroid_clearNativePointer(AttachCurrentThread(), GetJavaObject());
  80. }
  81. std::unique_ptr<WindowAndroid::ScopedWindowAndroidForTesting>
  82. WindowAndroid::CreateForTesting() {
  83. JNIEnv* env = AttachCurrentThread();
  84. long native_pointer = Java_WindowAndroid_createForTesting(env);
  85. return std::make_unique<ScopedWindowAndroidForTesting>(
  86. reinterpret_cast<WindowAndroid*>(native_pointer));
  87. }
  88. void WindowAndroid::OnCompositingDidCommit() {
  89. for (WindowAndroidObserver& observer : observer_list_)
  90. observer.OnCompositingDidCommit();
  91. }
  92. void WindowAndroid::AddObserver(WindowAndroidObserver* observer) {
  93. if (!observer_list_.HasObserver(observer))
  94. observer_list_.AddObserver(observer);
  95. }
  96. void WindowAndroid::RemoveObserver(WindowAndroidObserver* observer) {
  97. observer_list_.RemoveObserver(observer);
  98. }
  99. void WindowAndroid::AttachCompositor(WindowAndroidCompositor* compositor) {
  100. if (compositor_ && compositor != compositor_)
  101. DetachCompositor();
  102. compositor_ = compositor;
  103. for (WindowAndroidObserver& observer : observer_list_)
  104. observer.OnAttachCompositor();
  105. compositor_->SetVSyncPaused(vsync_paused_);
  106. }
  107. void WindowAndroid::DetachCompositor() {
  108. compositor_ = nullptr;
  109. for (WindowAndroidObserver& observer : observer_list_)
  110. observer.OnDetachCompositor();
  111. observer_list_.Clear();
  112. }
  113. float WindowAndroid::GetRefreshRate() {
  114. JNIEnv* env = AttachCurrentThread();
  115. return Java_WindowAndroid_getRefreshRate(env, GetJavaObject());
  116. }
  117. std::vector<float> WindowAndroid::GetSupportedRefreshRates() {
  118. if (test_hooks_)
  119. return test_hooks_->GetSupportedRates();
  120. JNIEnv* env = AttachCurrentThread();
  121. base::android::ScopedJavaLocalRef<jfloatArray> j_supported_refresh_rates =
  122. Java_WindowAndroid_getSupportedRefreshRates(env, GetJavaObject());
  123. std::vector<float> supported_refresh_rates;
  124. if (j_supported_refresh_rates) {
  125. base::android::JavaFloatArrayToFloatVector(env, j_supported_refresh_rates,
  126. &supported_refresh_rates);
  127. }
  128. return supported_refresh_rates;
  129. }
  130. void WindowAndroid::SetPreferredRefreshRate(float refresh_rate) {
  131. if (test_hooks_) {
  132. test_hooks_->SetPreferredRate(refresh_rate);
  133. return;
  134. }
  135. JNIEnv* env = AttachCurrentThread();
  136. Java_WindowAndroid_setPreferredRefreshRate(env, GetJavaObject(),
  137. refresh_rate);
  138. }
  139. void WindowAndroid::SetNeedsAnimate() {
  140. if (compositor_)
  141. compositor_->SetNeedsAnimate();
  142. }
  143. void WindowAndroid::Animate(base::TimeTicks begin_frame_time) {
  144. for (WindowAndroidObserver& observer : observer_list_)
  145. observer.OnAnimate(begin_frame_time);
  146. }
  147. void WindowAndroid::OnVisibilityChanged(JNIEnv* env,
  148. const JavaParamRef<jobject>& obj,
  149. bool visible) {
  150. for (WindowAndroidObserver& observer : observer_list_)
  151. observer.OnRootWindowVisibilityChanged(visible);
  152. }
  153. void WindowAndroid::OnActivityStopped(JNIEnv* env,
  154. const JavaParamRef<jobject>& obj) {
  155. for (WindowAndroidObserver& observer : observer_list_)
  156. observer.OnActivityStopped();
  157. }
  158. void WindowAndroid::OnActivityStarted(JNIEnv* env,
  159. const JavaParamRef<jobject>& obj) {
  160. for (WindowAndroidObserver& observer : observer_list_)
  161. observer.OnActivityStarted();
  162. }
  163. void WindowAndroid::SetVSyncPaused(JNIEnv* env,
  164. const JavaParamRef<jobject>& obj,
  165. bool paused) {
  166. vsync_paused_ = paused;
  167. if (compositor_)
  168. compositor_->SetVSyncPaused(paused);
  169. }
  170. void WindowAndroid::OnUpdateRefreshRate(
  171. JNIEnv* env,
  172. const base::android::JavaParamRef<jobject>& obj,
  173. float refresh_rate) {
  174. if (compositor_)
  175. compositor_->OnUpdateRefreshRate(refresh_rate);
  176. }
  177. void WindowAndroid::OnSupportedRefreshRatesUpdated(
  178. JNIEnv* env,
  179. const base::android::JavaParamRef<jobject>& obj,
  180. const JavaParamRef<jfloatArray>& j_supported_refresh_rates) {
  181. std::vector<float> supported_refresh_rates;
  182. if (j_supported_refresh_rates) {
  183. base::android::JavaFloatArrayToFloatVector(env, j_supported_refresh_rates,
  184. &supported_refresh_rates);
  185. }
  186. if (compositor_)
  187. compositor_->OnUpdateSupportedRefreshRates(supported_refresh_rates);
  188. }
  189. void WindowAndroid::SetWideColorEnabled(bool enabled) {
  190. JNIEnv* env = AttachCurrentThread();
  191. Java_WindowAndroid_setWideColorEnabled(env, GetJavaObject(), enabled);
  192. }
  193. bool WindowAndroid::HasPermission(const std::string& permission) {
  194. JNIEnv* env = AttachCurrentThread();
  195. return Java_WindowAndroid_hasPermission(
  196. env, GetJavaObject(),
  197. base::android::ConvertUTF8ToJavaString(env, permission));
  198. }
  199. bool WindowAndroid::CanRequestPermission(const std::string& permission) {
  200. JNIEnv* env = AttachCurrentThread();
  201. return Java_WindowAndroid_canRequestPermission(
  202. env, GetJavaObject(),
  203. base::android::ConvertUTF8ToJavaString(env, permission));
  204. }
  205. WindowAndroid* WindowAndroid::GetWindowAndroid() const {
  206. DCHECK(parent_ == nullptr);
  207. return const_cast<WindowAndroid*>(this);
  208. }
  209. display::Display WindowAndroid::GetDisplayWithWindowColorSpace() {
  210. display::Display display =
  211. display::Screen::GetScreen()->GetDisplayNearestWindow(this);
  212. DisplayAndroidManager::DoUpdateDisplay(
  213. &display, display.GetSizeInPixel(), display.device_scale_factor(),
  214. display.RotationAsDegree(), display.color_depth(),
  215. display.depth_per_component(), window_is_wide_color_gamut_);
  216. return display;
  217. }
  218. void WindowAndroid::SetTestHooks(TestHooks* hooks) {
  219. test_hooks_ = hooks;
  220. if (!test_hooks_)
  221. return;
  222. if (compositor_) {
  223. compositor_->OnUpdateSupportedRefreshRates(
  224. test_hooks_->GetSupportedRates());
  225. }
  226. }
  227. // ----------------------------------------------------------------------------
  228. // Native JNI methods
  229. // ----------------------------------------------------------------------------
  230. jlong JNI_WindowAndroid_Init(JNIEnv* env,
  231. const JavaParamRef<jobject>& obj,
  232. jint sdk_display_id,
  233. jfloat scroll_factor,
  234. jboolean window_is_wide_color_gamut) {
  235. WindowAndroid* window = new WindowAndroid(
  236. env, obj, sdk_display_id, scroll_factor, window_is_wide_color_gamut);
  237. return reinterpret_cast<intptr_t>(window);
  238. }
  239. } // namespace ui