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 package org.chromium.ui.gfx; 6 7 import android.content.ComponentCallbacks; 8 import android.content.Context; 9 import android.content.res.Configuration; 10 import android.content.res.Resources; 11 import android.util.TypedValue; 12 import android.view.ViewConfiguration; 13 14 import org.chromium.base.CalledByNative; 15 import org.chromium.base.JNINamespace; 16 import org.chromium.ui.R; 17 18 /** 19 * This class facilitates access to ViewConfiguration-related properties, also 20 * providing native-code notifications when such properties have changed. 21 * 22 */ 23 @JNINamespace("gfx") 24 public class ViewConfigurationHelper { 25 26 // Fallback constants when resource lookup fails, see 27 // ui/android/java/res/values/dimens.xml. 28 private static final float MIN_SCALING_SPAN_MM = 27.0f; 29 private static final float MIN_SCALING_TOUCH_MAJOR_DIP = 48.0f; 30 31 private final Context mAppContext; 32 private ViewConfiguration mViewConfiguration; 33 ViewConfigurationHelper(Context context)34 private ViewConfigurationHelper(Context context) { 35 mAppContext = context.getApplicationContext(); 36 mViewConfiguration = ViewConfiguration.get(mAppContext); 37 } 38 registerListener()39 private void registerListener() { 40 mAppContext.registerComponentCallbacks( 41 new ComponentCallbacks() { 42 @Override 43 public void onConfigurationChanged(Configuration configuration) { 44 updateNativeViewConfigurationIfNecessary(); 45 } 46 47 @Override 48 public void onLowMemory() { 49 } 50 }); 51 } 52 updateNativeViewConfigurationIfNecessary()53 private void updateNativeViewConfigurationIfNecessary() { 54 // The ViewConfiguration will differ only if the density has changed. 55 ViewConfiguration configuration = ViewConfiguration.get(mAppContext); 56 if (mViewConfiguration == configuration) return; 57 58 mViewConfiguration = configuration; 59 nativeUpdateSharedViewConfiguration( 60 getScaledMaximumFlingVelocity(), 61 getScaledMinimumFlingVelocity(), 62 getScaledTouchSlop(), 63 getScaledDoubleTapSlop(), 64 getScaledMinScalingSpan(), 65 getScaledMinScalingTouchMajor()); 66 } 67 68 @CalledByNative getDoubleTapTimeout()69 private static int getDoubleTapTimeout() { 70 return ViewConfiguration.getDoubleTapTimeout(); 71 } 72 73 @CalledByNative getLongPressTimeout()74 private static int getLongPressTimeout() { 75 return ViewConfiguration.getLongPressTimeout(); 76 } 77 78 @CalledByNative getTapTimeout()79 private static int getTapTimeout() { 80 return ViewConfiguration.getTapTimeout(); 81 } 82 83 @CalledByNative getScrollFriction()84 private static float getScrollFriction() { 85 return ViewConfiguration.getScrollFriction(); 86 } 87 88 @CalledByNative getScaledMaximumFlingVelocity()89 private int getScaledMaximumFlingVelocity() { 90 return mViewConfiguration.getScaledMaximumFlingVelocity(); 91 } 92 93 @CalledByNative getScaledMinimumFlingVelocity()94 private int getScaledMinimumFlingVelocity() { 95 return mViewConfiguration.getScaledMinimumFlingVelocity(); 96 } 97 98 @CalledByNative getScaledTouchSlop()99 private int getScaledTouchSlop() { 100 return mViewConfiguration.getScaledTouchSlop(); 101 } 102 103 @CalledByNative getScaledDoubleTapSlop()104 private int getScaledDoubleTapSlop() { 105 return mViewConfiguration.getScaledDoubleTapSlop(); 106 } 107 108 @CalledByNative getScaledMinScalingSpan()109 private int getScaledMinScalingSpan() { 110 final Resources res = mAppContext.getResources(); 111 int id = res.getIdentifier("config_minScalingSpan", "dimen", "android"); 112 // Fall back to a sensible default if the internal identifier does not exist. 113 if (id == 0) id = R.dimen.config_min_scaling_span; 114 try { 115 return res.getDimensionPixelSize(id); 116 } catch (Resources.NotFoundException e) { 117 assert false : "MinScalingSpan resource lookup failed."; 118 return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, MIN_SCALING_SPAN_MM, 119 res.getDisplayMetrics()); 120 } 121 } 122 123 @CalledByNative getScaledMinScalingTouchMajor()124 private int getScaledMinScalingTouchMajor() { 125 final Resources res = mAppContext.getResources(); 126 int id = res.getIdentifier("config_minScalingTouchMajor", "dimen", "android"); 127 // Fall back to a sensible default if the internal identifier does not exist. 128 if (id == 0) id = R.dimen.config_min_scaling_touch_major; 129 try { 130 return res.getDimensionPixelSize(id); 131 } catch (Resources.NotFoundException e) { 132 assert false : "MinScalingTouchMajor resource lookup failed."; 133 return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 134 MIN_SCALING_TOUCH_MAJOR_DIP, res.getDisplayMetrics()); 135 } 136 } 137 138 @CalledByNative createWithListener(Context context)139 private static ViewConfigurationHelper createWithListener(Context context) { 140 ViewConfigurationHelper viewConfigurationHelper = new ViewConfigurationHelper(context); 141 viewConfigurationHelper.registerListener(); 142 return viewConfigurationHelper; 143 } 144 nativeUpdateSharedViewConfiguration( int scaledMaximumFlingVelocity, int scaledMinimumFlingVelocity, int scaledTouchSlop, int scaledDoubleTapSlop, int scaledMinScalingSpan, int scaledMinScalingTouchMajor)145 private native void nativeUpdateSharedViewConfiguration( 146 int scaledMaximumFlingVelocity, int scaledMinimumFlingVelocity, 147 int scaledTouchSlop, int scaledDoubleTapSlop, 148 int scaledMinScalingSpan, int scaledMinScalingTouchMajor); 149 } 150