1// Copyright 2014 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
5#include "ui/gfx/android/view_configuration.h"
6
7#include "base/android/jni_android.h"
8#include "base/lazy_instance.h"
9#include "base/threading/non_thread_safe.h"
10#include "jni/ViewConfigurationHelper_jni.h"
11
12using base::android::AttachCurrentThread;
13using base::android::GetApplicationContext;
14
15namespace gfx {
16
17namespace {
18
19struct ViewConfigurationData {
20  ViewConfigurationData()
21      : double_tap_timeout_in_ms_(0),
22        long_press_timeout_in_ms_(0),
23        tap_timeout_in_ms_(0),
24        scroll_friction_(1.f),
25        max_fling_velocity_in_pixels_s_(0),
26        min_fling_velocity_in_pixels_s_(0),
27        touch_slop_in_pixels_(0),
28        double_tap_slop_in_pixels_(0),
29        min_scaling_span_in_pixels_(0),
30        min_scaling_touch_major_in_pixels_(0) {
31    JNIEnv* env = AttachCurrentThread();
32    j_view_configuration_helper_.Reset(
33        Java_ViewConfigurationHelper_createWithListener(
34            env, base::android::GetApplicationContext()));
35
36    double_tap_timeout_in_ms_ =
37        Java_ViewConfigurationHelper_getDoubleTapTimeout(env);
38    long_press_timeout_in_ms_ =
39        Java_ViewConfigurationHelper_getLongPressTimeout(env);
40    tap_timeout_in_ms_ = Java_ViewConfigurationHelper_getTapTimeout(env);
41    scroll_friction_ = Java_ViewConfigurationHelper_getScrollFriction(env);
42
43    jobject obj = j_view_configuration_helper_.obj();
44    Update(
45        Java_ViewConfigurationHelper_getScaledMaximumFlingVelocity(env, obj),
46        Java_ViewConfigurationHelper_getScaledMinimumFlingVelocity(env, obj),
47        Java_ViewConfigurationHelper_getScaledTouchSlop(env, obj),
48        Java_ViewConfigurationHelper_getScaledDoubleTapSlop(env, obj),
49        Java_ViewConfigurationHelper_getScaledMinScalingSpan(env, obj),
50        Java_ViewConfigurationHelper_getScaledMinScalingTouchMajor(env, obj));
51  }
52
53  ~ViewConfigurationData() {}
54
55  void SynchronizedUpdate(int scaled_maximum_fling_velocity,
56                          int scaled_minimum_fling_velocity,
57                          int scaled_touch_slop,
58                          int scaled_double_tap_slop,
59                          int scaled_min_scaling_span,
60                          int scaled_min_scaling_touch_major) {
61    base::AutoLock autolock(lock_);
62    Update(scaled_maximum_fling_velocity,
63           scaled_minimum_fling_velocity,
64           scaled_touch_slop,
65           scaled_double_tap_slop,
66           scaled_min_scaling_span,
67           scaled_min_scaling_touch_major);
68  }
69
70  int double_tap_timeout_in_ms() const { return double_tap_timeout_in_ms_; }
71  int long_press_timeout_in_ms() const { return long_press_timeout_in_ms_; }
72  int tap_timeout_in_ms() const { return tap_timeout_in_ms_; }
73  float scroll_friction() const { return scroll_friction_; }
74
75  int max_fling_velocity_in_pixels_s() {
76    base::AutoLock autolock(lock_);
77    return max_fling_velocity_in_pixels_s_;
78  }
79
80  int min_fling_velocity_in_pixels_s() {
81    base::AutoLock autolock(lock_);
82    return min_fling_velocity_in_pixels_s_;
83  }
84
85  int touch_slop_in_pixels() {
86    base::AutoLock autolock(lock_);
87    return touch_slop_in_pixels_;
88  }
89
90  int double_tap_slop_in_pixels() {
91    base::AutoLock autolock(lock_);
92    return double_tap_slop_in_pixels_;
93  }
94
95  int min_scaling_span_in_pixels() {
96    base::AutoLock autolock(lock_);
97    return min_scaling_span_in_pixels_;
98  }
99
100  int min_scaling_touch_major_in_pixels() {
101    base::AutoLock autolock(lock_);
102    return min_scaling_touch_major_in_pixels_;
103  }
104
105 private:
106  void Update(int scaled_maximum_fling_velocity,
107              int scaled_minimum_fling_velocity,
108              int scaled_touch_slop,
109              int scaled_double_tap_slop,
110              int scaled_min_scaling_span,
111              int scaled_min_scaling_touch_major) {
112    DCHECK_LE(scaled_minimum_fling_velocity, scaled_maximum_fling_velocity);
113    max_fling_velocity_in_pixels_s_ = scaled_maximum_fling_velocity;
114    min_fling_velocity_in_pixels_s_ = scaled_minimum_fling_velocity;
115    touch_slop_in_pixels_ = scaled_touch_slop;
116    double_tap_slop_in_pixels_ = scaled_double_tap_slop;
117    min_scaling_span_in_pixels_ = scaled_min_scaling_span;
118    min_scaling_touch_major_in_pixels_ = scaled_min_scaling_touch_major;
119  }
120
121  base::Lock lock_;
122  base::android::ScopedJavaGlobalRef<jobject> j_view_configuration_helper_;
123
124  // These values will remain constant throughout the lifetime of the app, so
125  // read-access needn't be synchronized.
126  int double_tap_timeout_in_ms_;
127  int long_press_timeout_in_ms_;
128  int tap_timeout_in_ms_;
129  float scroll_friction_;
130
131  // These values may vary as view-specific parameters (DPI scale) are changed,
132  // so read/write access must be synchronized.
133  int max_fling_velocity_in_pixels_s_;
134  int min_fling_velocity_in_pixels_s_;
135  int touch_slop_in_pixels_;
136  int double_tap_slop_in_pixels_;
137  int min_scaling_span_in_pixels_;
138  int min_scaling_touch_major_in_pixels_;
139
140 private:
141  DISALLOW_COPY_AND_ASSIGN(ViewConfigurationData);
142};
143
144// Leaky to allow access from any thread.
145base::LazyInstance<ViewConfigurationData>::Leaky g_view_configuration =
146    LAZY_INSTANCE_INITIALIZER;
147
148}  // namespace
149
150static void UpdateSharedViewConfiguration(JNIEnv* env,
151                                          jobject obj,
152                                          jint scaled_maximum_fling_velocity,
153                                          jint scaled_minimum_fling_velocity,
154                                          jint scaled_touch_slop,
155                                          jint scaled_double_tap_slop,
156                                          jint scaled_min_scaling_span,
157                                          jint scaled_min_scaling_touch_major) {
158  g_view_configuration.Get().SynchronizedUpdate(scaled_maximum_fling_velocity,
159                                                scaled_minimum_fling_velocity,
160                                                scaled_touch_slop,
161                                                scaled_double_tap_slop,
162                                                scaled_min_scaling_span,
163                                                scaled_min_scaling_touch_major);
164}
165
166int ViewConfiguration::GetDoubleTapTimeoutInMs() {
167  return g_view_configuration.Get().double_tap_timeout_in_ms();
168}
169
170int ViewConfiguration::GetLongPressTimeoutInMs() {
171  return g_view_configuration.Get().long_press_timeout_in_ms();
172}
173
174int ViewConfiguration::GetTapTimeoutInMs() {
175  return g_view_configuration.Get().tap_timeout_in_ms();
176}
177
178float ViewConfiguration::GetScrollFriction() {
179  return g_view_configuration.Get().scroll_friction();
180}
181
182int ViewConfiguration::GetMaximumFlingVelocityInPixelsPerSecond() {
183  return g_view_configuration.Get().max_fling_velocity_in_pixels_s();
184}
185
186int ViewConfiguration::GetMinimumFlingVelocityInPixelsPerSecond() {
187  return g_view_configuration.Get().min_fling_velocity_in_pixels_s();
188}
189
190int ViewConfiguration::GetTouchSlopInPixels() {
191  return g_view_configuration.Get().touch_slop_in_pixels();
192}
193
194int ViewConfiguration::GetDoubleTapSlopInPixels() {
195  return g_view_configuration.Get().double_tap_slop_in_pixels();
196}
197
198int ViewConfiguration::GetMinScalingSpanInPixels() {
199  return g_view_configuration.Get().min_scaling_span_in_pixels();
200}
201
202int ViewConfiguration::GetMinScalingTouchMajorInPixels() {
203  return g_view_configuration.Get().min_scaling_touch_major_in_pixels();
204}
205
206bool ViewConfiguration::RegisterViewConfiguration(JNIEnv* env) {
207  return RegisterNativesImpl(env);
208}
209
210}  // namespace gfx
211