summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java13
-rw-r--r--core/java/android/hardware/SensorManager.java18
-rw-r--r--core/java/android/inputmethodservice/SoftInputWindow.java3
-rw-r--r--core/java/android/preference/Preference.java7
-rw-r--r--core/java/android/preference/PreferenceScreen.java1
-rw-r--r--core/java/android/provider/Checkin.java5
-rw-r--r--core/java/android/provider/Gmail.java10
-rw-r--r--core/java/android/provider/MediaStore.java6
-rw-r--r--core/java/android/server/BluetoothDeviceService.java21
-rw-r--r--core/java/android/server/BluetoothEventLoop.java3
-rw-r--r--core/java/android/view/KeyEvent.java4
-rwxr-xr-xcore/java/android/view/OrientationEventListener.java20
-rw-r--r--core/java/android/view/SurfaceHolder.java2
-rw-r--r--core/java/android/view/ViewRoot.java11
-rw-r--r--core/java/android/view/WindowManagerPolicy.java17
-rwxr-xr-xcore/java/android/view/WindowOrientationListener.java20
-rw-r--r--core/java/android/webkit/WebSettings.java6
-rw-r--r--core/java/android/webkit/WebView.java116
-rw-r--r--core/java/android/webkit/WebViewCore.java9
-rw-r--r--core/java/android/webkit/gears/GearsPluginSettings.java95
-rw-r--r--core/java/android/webkit/gears/HtmlDialogAndroid.java174
-rw-r--r--core/java/android/webkit/gears/IGearsDialogService.java107
-rw-r--r--core/java/android/widget/Adapter.java2
-rw-r--r--core/java/android/widget/TextView.java16
-rw-r--r--core/java/android/widget/ZoomRing.java113
-rw-r--r--core/java/android/widget/ZoomRingController.java82
26 files changed, 385 insertions, 496 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 8236943..849a37d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -890,9 +890,9 @@ public class Activity extends ContextThemeWrapper
}
/**
- * Called after {@link #onCreate} or {@link #onStop} when the current
- * activity is now being displayed to the user. It will
- * be followed by {@link #onRestart}.
+ * Called after {@link #onCreate} — or after {@link #onRestart} when
+ * the activity had been stopped, but is now again being displayed to the
+ * user. It will be followed by {@link #onResume}.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
@@ -907,9 +907,9 @@ public class Activity extends ContextThemeWrapper
}
/**
- * Called after {@link #onStart} when the current activity is being
+ * Called after {@link #onStop} when the current activity is being
* re-displayed to the user (the user has navigated back to it). It will
- * be followed by {@link #onResume}.
+ * be followed by {@link #onStart} and then {@link #onResume}.
*
* <p>For activities that are using raw {@link Cursor} objects (instead of
* creating them through
@@ -923,6 +923,7 @@ public class Activity extends ContextThemeWrapper
* thrown.</em></p>
*
* @see #onStop
+ * @see #onStart
* @see #onResume
*/
protected void onRestart() {
@@ -1220,7 +1221,7 @@ public class Activity extends ContextThemeWrapper
/**
* Called when you are no longer visible to the user. You will next
- * receive either {@link #onStart}, {@link #onDestroy}, or nothing,
+ * receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
*
* <p>Note that this method may never be called, in low memory situations
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 3981f27..e232c2c 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -620,6 +620,9 @@ public class SensorManager extends IRotationWatcher.Stub
*/
@Deprecated
public boolean registerListener(SensorListener listener, int sensors, int rate) {
+ if (listener == null) {
+ return false;
+ }
boolean result = false;
result = registerLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER,
listener, sensors, rate) || result;
@@ -638,6 +641,9 @@ public class SensorManager extends IRotationWatcher.Stub
private boolean registerLegacyListener(int legacyType, int type,
SensorListener listener, int sensors, int rate)
{
+ if (listener == null) {
+ return false;
+ }
boolean result = false;
// Are we activating this legacy sensor?
if ((sensors & legacyType) != 0) {
@@ -693,6 +699,9 @@ public class SensorManager extends IRotationWatcher.Stub
private void unregisterLegacyListener(int legacyType, int type,
SensorListener listener, int sensors)
{
+ if (listener == null) {
+ return;
+ }
// do we know about this listener?
LegacyListener legacyListener = null;
synchronized (mLegacyListenersMap) {
@@ -800,6 +809,9 @@ public class SensorManager extends IRotationWatcher.Stub
*/
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate,
Handler handler) {
+ if (listener == null || sensor == null) {
+ return false;
+ }
boolean result;
int delay = -1;
switch (rate) {
@@ -856,6 +868,9 @@ public class SensorManager extends IRotationWatcher.Stub
}
private void unregisterListener(Object listener, Sensor sensor) {
+ if (listener == null || sensor == null) {
+ return;
+ }
try {
synchronized (sListeners) {
final int size = sListeners.size();
@@ -881,6 +896,9 @@ public class SensorManager extends IRotationWatcher.Stub
}
private void unregisterListener(Object listener) {
+ if (listener == null) {
+ return;
+ }
try {
synchronized (sListeners) {
final int size = sListeners.size();
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java
index da67c6d..c37845f 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -141,7 +141,8 @@ class SoftInputWindow extends Dialog {
lp.gravity = Gravity.BOTTOM;
lp.width = -1;
// Let the input method window's orientation follow sensor based rotation
- lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
+ // Turn this off for now, it is very problematic.
+ //lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
getWindow().setAttributes(lp);
getWindow().setFlags(
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 3820f28..a255438 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -667,7 +667,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
* {@link SharedPreferences}. This should be unique for the package.
*
* @param key The key for the preference.
- * @see #getId()
*/
public void setKey(String key) {
mKey = key;
@@ -1460,7 +1459,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
* @param container The Bundle in which to save the instance of this Preference.
*
* @see #restoreHierarchyState
- * @see #dispatchSaveInstanceState
* @see #onSaveInstanceState
*/
public void saveHierarchyState(Bundle container) {
@@ -1474,7 +1472,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
*
* @param container The Bundle in which to save the instance of this Preference.
*
- * @see #dispatchRestoreInstanceState
* @see #saveHierarchyState
* @see #onSaveInstanceState
*/
@@ -1503,7 +1500,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
* The default implementation returns null.
* @see #onRestoreInstanceState
* @see #saveHierarchyState
- * @see #dispatchSaveInstanceState
*/
protected Parcelable onSaveInstanceState() {
mBaseMethodCalled = true;
@@ -1516,7 +1512,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
* @param container The Bundle that holds the previously saved state.
*
* @see #saveHierarchyState
- * @see #dispatchRestoreInstanceState
* @see #onRestoreInstanceState
*/
public void restoreHierarchyState(Bundle container) {
@@ -1530,7 +1525,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
* not want to save state for their children.
*
* @param container The Bundle that holds the previously saved state.
- * @see #dispatchSaveInstanceState
* @see #restoreHierarchyState
* @see #onRestoreInstanceState
*/
@@ -1557,7 +1551,6 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
* {@link #onSaveInstanceState}.
* @see #onSaveInstanceState
* @see #restoreHierarchyState
- * @see #dispatchRestoreInstanceState
*/
protected void onRestoreInstanceState(Parcelable state) {
mBaseMethodCalled = true;
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index 9929b96..5353b53 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -100,7 +100,6 @@ public final class PreferenceScreen extends PreferenceGroup implements AdapterVi
*
* @return An adapter that provides the {@link Preference} contained in this
* {@link PreferenceScreen}.
- * @see PreferenceGroupAdapter
*/
public ListAdapter getRootAdapter() {
if (mRootAdapter == null) {
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 688e19a..0cdac53 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -126,6 +126,11 @@ public final class Checkin {
/** Valid tag values. Extend as necessary for your needs. */
public enum Tag {
+ BROWSER_SNAP_CENTER,
+ BROWSER_TEXT_SIZE_CHANGE,
+ BROWSER_ZOOM_OVERVIEW,
+ BROWSER_ZOOM_RING,
+ BROWSER_ZOOM_RING_DRAG,
CRASHES_REPORTED,
CRASHES_TRUNCATED,
ELAPSED_REALTIME_SEC,
diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java
index 253dd4a..5b3c223 100644
--- a/core/java/android/provider/Gmail.java
+++ b/core/java/android/provider/Gmail.java
@@ -1477,10 +1477,20 @@ public final class Gmail {
LABEL_OUTBOX, LABEL_DRAFT, LABEL_ALL,
LABEL_SPAM, LABEL_TRASH);
+
+ private static final Set<String> USER_MEANINGFUL_SYSTEM_LABELS_SET =
+ Sets.newHashSet(
+ SORTED_USER_MEANINGFUL_SYSTEM_LABELS.toArray(
+ new String[]{}));
+
public static List<String> getSortedUserMeaningfulSystemLabels() {
return SORTED_USER_MEANINGFUL_SYSTEM_LABELS;
}
+ public static Set<String> getUserMeaningfulSystemLabelsSet() {
+ return USER_MEANINGFUL_SYSTEM_LABELS_SET;
+ }
+
/**
* If you are ever tempted to remove outbox or draft from this set make sure you have a
* way to stop draft and outbox messages from getting purged before they are sent to the
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 2897b4e..b91bc9d 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -158,6 +158,12 @@ public final class MediaStore
public final static String EXTRA_VIDEO_QUALITY = "android.intent.extra.videoQuality";
/**
+ * Specify the maximum allowed size.
+ * @hide
+ */
+ public final static String EXTRA_SIZE_LIMIT = "android.intent.extra.sizeLimit";
+
+ /**
* The name of the Intent-extra used to indicate a content resolver Uri to be used to
* store the requested image or video.
*/
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 86d5a1e..fa53a60 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -47,8 +47,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
public class BluetoothDeviceService extends IBluetoothDevice.Stub {
@@ -121,7 +121,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
* Bring down bluetooth. Returns true on success.
*
* @param saveSetting If true, disable BT in settings
- *
+ *
*/
public synchronized boolean disable(boolean saveSetting) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -172,7 +172,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
* This turns on/off the underlying hardware.
*
* @param saveSetting If true, enable BT in settings
- *
+ *
* @return True on success (so far), guaranteeing the callback with be
* notified when complete.
*/
@@ -275,6 +275,14 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
private final ArrayList<String> mAutoPairingFailures = new ArrayList<String>();
+ // List of all the vendor_id prefix of Bluetooth addresses for which
+ // auto pairing is not attempted
+ private final ArrayList<String> mAutoPairingBlacklisted =
+ new ArrayList<String>(Arrays.asList(
+ "00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", //ALPS
+ "00:21:4F", "00:23:06", "00:24:33", "00:A0:79", // ALPS
+ "00:0E:6D", "00:13:E0", "00:21:E8", "00:60:57"// Murata for Prius 2007
+ ));
public synchronized void loadBondState() {
if (!mIsEnabled) {
@@ -322,6 +330,13 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
}
+ public boolean isAutoPairingBlacklisted(String address) {
+ for (String blacklistAddress : mAutoPairingBlacklisted) {
+ if (address.startsWith(blacklistAddress)) return true;
+ }
+ return false;
+ }
+
public synchronized int getBondState(String address) {
Integer state = mState.get(address);
if (state == null) {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 187ec2c..8b09583 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -312,7 +312,8 @@ class BluetoothEventLoop {
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
- if (!mBluetoothService.getBondState().hasAutoPairingFailed(address)) {
+ if (!mBluetoothService.getBondState().hasAutoPairingFailed(address) &&
+ !mBluetoothService.getBondState().isAutoPairingBlacklisted(address)) {
mBluetoothService.getBondState().attempt(address);
mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes("0000"));
return;
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index d5434b6..d6ea91c 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -117,7 +117,8 @@ public class KeyEvent implements Parcelable {
public static final int KEYCODE_PREVIOUSSONG = 88;
public static final int KEYCODE_REWIND = 89;
public static final int KEYCODE_FORWARD = 90;
- private static final int LAST_KEYCODE = KEYCODE_FORWARD;
+ public static final int KEYCODE_MUTE = 91;
+ private static final int LAST_KEYCODE = KEYCODE_MUTE;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
@@ -502,6 +503,7 @@ public class KeyEvent implements Parcelable {
case KEYCODE_ENDCALL:
case KEYCODE_VOLUME_UP:
case KEYCODE_VOLUME_DOWN:
+ case KEYCODE_MUTE:
case KEYCODE_POWER:
case KEYCODE_HEADSETHOOK:
case KEYCODE_PLAYPAUSE:
diff --git a/core/java/android/view/OrientationEventListener.java b/core/java/android/view/OrientationEventListener.java
index cddec11..391ba1e 100755
--- a/core/java/android/view/OrientationEventListener.java
+++ b/core/java/android/view/OrientationEventListener.java
@@ -69,8 +69,11 @@ public abstract class OrientationEventListener {
public OrientationEventListener(Context context, int rate) {
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
- mSensorEventListener = new SensorEventListenerImpl();
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ if (mSensor != null) {
+ // Create listener only if sensors do exist
+ mSensorEventListener = new SensorEventListenerImpl();
+ }
}
void registerListener(OrientationListener lis) {
@@ -82,6 +85,10 @@ public abstract class OrientationEventListener {
* {@link #onOrientationChanged} when the device orientation changes.
*/
public void enable() {
+ if (mSensor == null) {
+ Log.w(TAG, "Cannot detect sensors. Not enabled");
+ return;
+ }
if (mEnabled == false) {
if (localLOGV) Log.d(TAG, "OrientationEventListener enabled");
mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
@@ -93,6 +100,10 @@ public abstract class OrientationEventListener {
* Disables the OrientationEventListener.
*/
public void disable() {
+ if (mSensor == null) {
+ Log.w(TAG, "Cannot detect sensors. Invalid disable");
+ return;
+ }
if (mEnabled == true) {
if (localLOGV) Log.d(TAG, "OrientationEventListener disabled");
mSensorManager.unregisterListener(mSensorEventListener);
@@ -138,6 +149,13 @@ public abstract class OrientationEventListener {
}
}
+
+ /*
+ * Returns true if sensor is enabled and false otherwise
+ */
+ public boolean canDetectOrientation() {
+ return mSensor != null;
+ }
/**
* Called when the orientation of the device has changed.
diff --git a/core/java/android/view/SurfaceHolder.java b/core/java/android/view/SurfaceHolder.java
index 21a72e7..3d0dda3 100644
--- a/core/java/android/view/SurfaceHolder.java
+++ b/core/java/android/view/SurfaceHolder.java
@@ -240,7 +240,7 @@ public interface SurfaceHolder {
* in particular there is no guarantee that the content of the Surface
* will remain unchanged when lockCanvas() is called again.
*
- * @see android.view.SurfaceHolder.lockCanvas
+ * @see #lockCanvas()
*
* @param canvas The Canvas previously returned by lockCanvas().
*/
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index db8829f..3cfaf1b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1817,6 +1817,11 @@ public final class ViewRoot extends Handler implements ViewParent,
if (event != null) {
event.recycle();
}
+ // If we reach this, we delivered a trackball event to mView and
+ // mView consumed it. Because we will not translate the trackball
+ // event into a key event, touch mode will not exit, so we exit
+ // touch mode here.
+ ensureTouchMode(false);
//noinspection ReturnInsideFinallyBlock
return;
}
@@ -2140,7 +2145,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
boolean keyHandled = mView.dispatchKeyEvent(event);
- if ((!keyHandled && isDown) || (action == KeyEvent.ACTION_MULTIPLE)) {
+ if (!keyHandled && isDown) {
int direction = 0;
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_LEFT:
@@ -2541,7 +2546,7 @@ public final class ViewRoot extends Handler implements ViewParent,
* for us to consider the user to be doing fast trackball movements,
* and thus apply an acceleration.
*/
- static final long FAST_MOVE_TIME = 100;
+ static final long FAST_MOVE_TIME = 150;
/**
* Scaling factor to the time (in milliseconds) between events to how
@@ -2549,7 +2554,7 @@ public final class ViewRoot extends Handler implements ViewParent,
* is < FAST_MOVE_TIME this multiplies the acceleration; when >
* FAST_MOVE_TIME it divides it.
*/
- static final float ACCEL_MOVE_SCALING_FACTOR = (1.0f/50);
+ static final float ACCEL_MOVE_SCALING_FACTOR = (1.0f/40);
float position;
float absPosition;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 051f823..0f15b17 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -129,14 +129,22 @@ public interface WindowManagerPolicy {
Rect contentFrame, Rect visibleFrame);
/**
- * Retrieve the current frame of the window. Must be called with the
- * window manager lock held.
+ * Retrieve the current frame of the window that has been assigned by
+ * the window manager. Must be called with the window manager lock held.
*
* @return Rect The rectangle holding the window frame.
*/
public Rect getFrameLw();
/**
+ * Retrieve the current frame of the window that is actually shown.
+ * Must be called with the window manager lock held.
+ *
+ * @return Rect The rectangle holding the shown window frame.
+ */
+ public Rect getShownFrameLw();
+
+ /**
* Retrieve the frame of the display that this window was last
* laid out in. Must be called with the
* window manager lock held.
@@ -273,9 +281,12 @@ public interface WindowManagerPolicy {
* false, this is based on the currently requested
* frame, which any current animation will be moving
* towards.
+ * @param onlyOpaque If true, this will only pass if the window is
+ * also opaque.
* @return Returns true if the window is both full screen and opaque
*/
- public boolean fillsScreenLw(int width, int height, boolean shownFrame);
+ public boolean fillsScreenLw(int width, int height, boolean shownFrame,
+ boolean onlyOpaque);
/**
* Returns true if this window has been shown on screen at some time in
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 4aa3f7a..5877932 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -74,8 +74,11 @@ public abstract class WindowOrientationListener {
public WindowOrientationListener(Context context, int rate) {
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
- mSensorEventListener = new SensorEventListenerImpl();
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ if (mSensor != null) {
+ // Create listener only if sensors do exist
+ mSensorEventListener = new SensorEventListenerImpl();
+ }
}
/**
@@ -83,6 +86,10 @@ public abstract class WindowOrientationListener {
* {@link #onOrientationChanged} when the device orientation changes.
*/
public void enable() {
+ if (mSensor == null) {
+ Log.w(TAG, "Cannot detect sensors. Not enabled");
+ return;
+ }
if (mEnabled == false) {
if (localLOGV) Log.d(TAG, "WindowOrientationListener enabled");
mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
@@ -94,6 +101,10 @@ public abstract class WindowOrientationListener {
* Disables the WindowOrientationListener.
*/
public void disable() {
+ if (mSensor == null) {
+ Log.w(TAG, "Cannot detect sensors. Invalid disable");
+ return;
+ }
if (mEnabled == true) {
if (localLOGV) Log.d(TAG, "WindowOrientationListener disabled");
mSensorManager.unregisterListener(mSensorEventListener);
@@ -145,6 +156,13 @@ public abstract class WindowOrientationListener {
}
}
+ /*
+ * Returns true if sensor is enabled and false otherwise
+ */
+ public boolean canDetectOrientation() {
+ return mSensor != null;
+ }
+
/**
* Called when the orientation of the device has changed.
* orientation parameter is in degrees, ranging from 0 to 359.
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 5c470cf..4e2b2ab 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -20,6 +20,8 @@ import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
+import android.provider.Checkin;
+
import java.lang.SecurityException;
import android.content.pm.PackageManager;
@@ -408,6 +410,10 @@ public class WebSettings {
* @see WebSettings.TextSize
*/
public synchronized void setTextSize(TextSize t) {
+ if (WebView.mLogEvent && mTextSize != t ) {
+ Checkin.updateStats(mContext.getContentResolver(),
+ Checkin.Stats.Tag.BROWSER_TEXT_SIZE_CHANGE, 1, 0.0);
+ }
mTextSize = t;
postSync();
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4d9a8fb..c59a5fc 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -38,11 +38,13 @@ import android.os.Handler;
import android.os.Message;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.provider.Checkin;
import android.text.IClipboard;
import android.text.Selection;
import android.text.Spannable;
import android.util.AttributeSet;
import android.util.Config;
+import android.util.EventLog;
import android.util.Log;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
@@ -450,6 +452,13 @@ public class WebView extends AbsoluteLayout
// Used to match key downs and key ups
private boolean mGotKeyDown;
+ /* package */ static boolean mLogEvent = true;
+ private static final int EVENT_LOG_ZOOM_LEVEL_CHANGE = 70101;
+ private static final int EVENT_LOG_DOUBLE_TAP_DURATION = 70102;
+
+ // for event log
+ private long mLastTouchUpTime = 0;
+
/**
* URI scheme for telephone number
*/
@@ -556,7 +565,11 @@ public class WebView extends AbsoluteLayout
private ZoomRingController.OnZoomListener mZoomListener =
new ZoomRingController.OnZoomListener() {
-
+
+ private float mClockwiseBound;
+ private float mCounterClockwiseBound;
+ private float mStartScale;
+
public void onCenter(int x, int y) {
// Don't translate when the control is invoked, hence we do nothing
// in this callback
@@ -564,6 +577,10 @@ public class WebView extends AbsoluteLayout
public void onBeginPan() {
setZoomOverviewVisible(false);
+ if (mLogEvent) {
+ Checkin.updateStats(mContext.getContentResolver(),
+ Checkin.Stats.Tag.BROWSER_ZOOM_RING_DRAG, 1, 0.0);
+ }
}
public boolean onPan(int deltaX, int deltaY) {
@@ -576,12 +593,25 @@ public class WebView extends AbsoluteLayout
public void onVisibilityChanged(boolean visible) {
if (visible) {
switchOutDrawHistory();
+ if (mMaxZoomScale - 1 > ZOOM_RING_STEPS * 0.01f) {
+ mClockwiseBound = (float) (2 * Math.PI - MAX_ZOOM_RING_ANGLE);
+ } else {
+ mClockwiseBound = (float) (2 * Math.PI);
+ }
+ mZoomRingController.setThumbClockwiseBound(mClockwiseBound);
+ if (1 - mMinZoomScale > ZOOM_RING_STEPS * 0.01f) {
+ mCounterClockwiseBound = MAX_ZOOM_RING_ANGLE;
+ } else {
+ mCounterClockwiseBound = 0;
+ }
+ mZoomRingController
+ .setThumbCounterclockwiseBound(mCounterClockwiseBound);
float angle = 0f;
- if (mActualScale > 1) {
+ if (mActualScale > 1 && mClockwiseBound < (float) (2 * Math.PI)) {
angle = -(float) Math.round(ZOOM_RING_STEPS
* (mActualScale - 1) / (mMaxZoomScale - 1))
/ ZOOM_RING_STEPS;
- } else if (mActualScale < 1) {
+ } else if (mActualScale < 1 && mCounterClockwiseBound > 0) {
angle = (float) Math.round(ZOOM_RING_STEPS
* (1 - mActualScale) / (1 - mMinZoomScale))
/ ZOOM_RING_STEPS;
@@ -590,16 +620,26 @@ public class WebView extends AbsoluteLayout
// Show the zoom overview tab on the ring
setZoomOverviewVisible(true);
+ if (mLogEvent) {
+ Checkin.updateStats(mContext.getContentResolver(),
+ Checkin.Stats.Tag.BROWSER_ZOOM_RING, 1, 0.0);
+ }
}
}
public void onBeginDrag() {
mPreviewZoomOnly = true;
+ mStartScale = mActualScale;
setZoomOverviewVisible(false);
}
public void onEndDrag() {
mPreviewZoomOnly = false;
+ if (mLogEvent) {
+ EventLog.writeEvent(EVENT_LOG_ZOOM_LEVEL_CHANGE,
+ (int) mStartScale * 100, (int) mActualScale * 100,
+ System.currentTimeMillis());
+ }
setNewZoomScale(mActualScale, true);
}
@@ -616,21 +656,21 @@ public class WebView extends AbsoluteLayout
mZoomCenterY = (float) centerY;
float scale = 1.0f;
- if (curAngle > (float) Math.PI)
- curAngle -= (float) 2 * Math.PI;
- if (curAngle > 0) {
- if (curAngle >= MAX_ZOOM_RING_ANGLE) {
+ // curAngle is [0, 2 * Math.PI)
+ if (curAngle < (float) Math.PI) {
+ if (curAngle >= mCounterClockwiseBound) {
scale = mMinZoomScale;
} else {
scale = 1 - (float) Math.round(curAngle
/ ZOOM_RING_ANGLE_UNIT) / ZOOM_RING_STEPS
* (1 - mMinZoomScale);
}
- } else if (curAngle < 0) {
- if (curAngle <= -MAX_ZOOM_RING_ANGLE) {
+ } else {
+ if (curAngle <= mClockwiseBound) {
scale = mMaxZoomScale;
} else {
- scale = 1 + (float) Math.round(-curAngle
+ scale = 1 + (float) Math.round(
+ ((float) 2 * Math.PI - curAngle)
/ ZOOM_RING_ANGLE_UNIT) / ZOOM_RING_STEPS
* (mMaxZoomScale - 1);
}
@@ -687,12 +727,11 @@ public class WebView extends AbsoluteLayout
mScroller = new Scroller(context);
mZoomRingController = new ZoomRingController(context, this);
mZoomRingController.setResetThumbAutomatically(false);
- mZoomRingController.setThumbClockwiseBound(
- (float) (2 * Math.PI - MAX_ZOOM_RING_ANGLE));
- mZoomRingController.setThumbCounterclockwiseBound(MAX_ZOOM_RING_ANGLE);
mZoomRingController.setCallback(mZoomListener);
mZoomRingController.setZoomRingTrack(
com.android.internal.R.drawable.zoom_ring_track_absolute);
+ mZoomRingController.setPannerAcceleration(160);
+ mZoomRingController.setPannerStartAcceleratingDuration(700);
createZoomRingOverviewTab();
}
@@ -730,6 +769,10 @@ public class WebView extends AbsoluteLayout
public void onClick(View v) {
// Hide the zoom ring
mZoomRingController.setVisible(false);
+ if (mLogEvent) {
+ Checkin.updateStats(mContext.getContentResolver(),
+ Checkin.Stats.Tag.BROWSER_ZOOM_OVERVIEW, 1, 0.0);
+ }
zoomScrollOut();
}});
@@ -3468,7 +3511,7 @@ public class WebView extends AbsoluteLayout
// update mMinZoomScale
if (mMinContentWidth > MAX_FLOAT_CONTENT_WIDTH) {
boolean atMin = Math.abs(mActualScale - mMinZoomScale) < 0.01f;
- mMinZoomScale = (float) getViewWidth() / mMinContentWidth;
+ mMinZoomScale = (float) getViewWidth() / mContentWidth;
if (atMin) {
// if the WebView was at the minimum zoom scale, keep it. e,g.,
// the WebView was at the minimum zoom scale at the portrait
@@ -3535,7 +3578,8 @@ public class WebView extends AbsoluteLayout
return false;
}
- if (mShowZoomRingTutorial && mMinZoomScale < mMaxZoomScale) {
+ if (mShowZoomRingTutorial && getSettings().supportZoom()
+ && (mMaxZoomScale - mMinZoomScale) > ZOOM_RING_STEPS * 0.01f) {
ZoomRingController.showZoomTutorialOnce(mContext);
mShowZoomRingTutorial = false;
mPrivateHandler.sendMessageDelayed(mPrivateHandler
@@ -3616,10 +3660,18 @@ public class WebView extends AbsoluteLayout
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
mZoomRingController.setVisible(true);
mInZoomTapDragMode = true;
+ if (mLogEvent) {
+ EventLog.writeEvent(EVENT_LOG_DOUBLE_TAP_DURATION,
+ (eventTime - mLastTouchUpTime), eventTime);
+ }
return mZoomRingController.handleDoubleTapEvent(ev);
} else {
mTouchMode = TOUCH_INIT_MODE;
mPreventDrag = mForwardTouchEvents;
+ if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
+ EventLog.writeEvent(EVENT_LOG_DOUBLE_TAP_DURATION,
+ (eventTime - mLastTouchUpTime), eventTime);
+ }
}
// don't trigger the link if zoom ring is visible
if (mTouchMode == TOUCH_INIT_MODE
@@ -3783,17 +3835,23 @@ public class WebView extends AbsoluteLayout
break;
}
case MotionEvent.ACTION_UP: {
+ mLastTouchUpTime = eventTime;
switch (mTouchMode) {
case TOUCH_INIT_MODE: // tap
if (mZoomRingController.isVisible()) {
- // don't trigger the link if zoom ring is visible
+ // don't trigger the link if zoom ring is visible,
+ // but still allow the double tap
+ mPrivateHandler.sendMessageDelayed(mPrivateHandler
+ .obtainMessage(RELEASE_SINGLE_TAP,
+ new Boolean(false)),
+ DOUBLE_TAP_TIMEOUT);
break;
}
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- if (getSettings().supportZoom()
- && (mMinZoomScale < mMaxZoomScale)) {
+ if (getSettings().supportZoom()) {
mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(RELEASE_SINGLE_TAP),
+ .obtainMessage(RELEASE_SINGLE_TAP,
+ new Boolean(true)),
DOUBLE_TAP_TIMEOUT);
} else {
// do short press now
@@ -3841,7 +3899,8 @@ public class WebView extends AbsoluteLayout
// as tap instead of short press.
mTouchMode = TOUCH_INIT_MODE;
mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(RELEASE_SINGLE_TAP),
+ .obtainMessage(RELEASE_SINGLE_TAP,
+ new Boolean(true)),
DOUBLE_TAP_TIMEOUT);
} else {
mTouchMode = TOUCH_DONE_MODE;
@@ -3963,6 +4022,7 @@ public class WebView extends AbsoluteLayout
+ " time=" + time
+ " mLastFocusTime=" + mLastFocusTime);
}
+ if (isInTouchMode()) requestFocusFromTouch();
return false; // let common code in onKeyDown at it
}
if (ev.getAction() == MotionEvent.ACTION_UP) {
@@ -4399,7 +4459,12 @@ public class WebView extends AbsoluteLayout
int contentX = viewToContent((int) mLastTouchX + mScrollX);
int contentY = viewToContent((int) mLastTouchY + mScrollY);
int contentSize = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- nativeMotionUp(contentX, contentY, contentSize, true);
+ if (nativeMotionUp(contentX, contentY, contentSize, true)) {
+ if (mLogEvent) {
+ Checkin.updateStats(mContext.getContentResolver(),
+ Checkin.Stats.Tag.BROWSER_SNAP_CENTER, 1, 0.0);
+ }
+ }
if (nativeUpdateFocusNode() && !mFocusNode.mIsTextField
&& !mFocusNode.mIsTextArea) {
playSoundEffect(SoundEffectConstants.CLICK);
@@ -4619,7 +4684,9 @@ public class WebView extends AbsoluteLayout
}
case RELEASE_SINGLE_TAP: {
mTouchMode = TOUCH_DONE_MODE;
- doShortPress();
+ if ((Boolean)msg.obj) {
+ doShortPress();
+ }
break;
}
case SWITCH_TO_ENTER:
@@ -4671,7 +4738,7 @@ public class WebView extends AbsoluteLayout
mMinContentWidth = msg.arg1;
if (mMinContentWidth > MAX_FLOAT_CONTENT_WIDTH) {
mMinZoomScale = (float) getViewWidth()
- / mMinContentWidth;
+ / draw.mWidthHeight.x;
}
// We update the layout (i.e. request a layout from the
// view system) if the last view size that we sent to
@@ -5236,7 +5303,8 @@ public class WebView extends AbsoluteLayout
private native Rect nativeGetNavBounds();
private native void nativeInstrumentReport();
private native void nativeMarkNodeInvalid(int node);
- private native void nativeMotionUp(int x, int y, int slop, boolean isClick);
+ // return true if the page has been scrolled
+ private native boolean nativeMotionUp(int x, int y, int slop, boolean isClick);
// returns false if it handled the key
private native boolean nativeMoveFocus(int keyCode, int count,
boolean noScroll);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 45113ab..a7261c5 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1197,6 +1197,7 @@ final class WebViewCore {
Log.w(LOGTAG, "skip viewSizeChanged as w is 0");
return;
}
+ // negative scale indicate that WebCore should reuse the current scale
float scale = (float) viewWidth / w;
if (mSettings.getUseWideViewPort()
&& (w < mViewportWidth || mViewportWidth == -1)) {
@@ -1224,7 +1225,7 @@ final class WebViewCore {
// keep the same width and screen width so that there is
// no reflow when zoom-out
width = minContentWidth;
- screenWidth = Math.min(screenWidth, viewWidth);
+ screenWidth = Math.min(screenWidth, Math.abs(viewWidth));
} else {
width = Math.max(w, minContentWidth);
}
@@ -1536,11 +1537,11 @@ final class WebViewCore {
// white space in the GMail which uses WebView for message view.
if (mWebView != null && mWebView.mHeightCanMeasure) {
mWebView.mLastHeightSent = 0;
- // Send a negative scale to indicate that WebCore should reuse the
- // current scale
+ // Send a negative screen width to indicate that WebCore should
+ // reuse the current scale
mEventHub.sendMessage(Message.obtain(null,
EventHub.VIEW_SIZE_CHANGED, mWebView.mLastWidthSent,
- mWebView.mLastHeightSent, new Integer(-1)));
+ mWebView.mLastHeightSent, -mWebView.mLastWidthSent));
}
mBrowserFrame.didFirstLayout();
diff --git a/core/java/android/webkit/gears/GearsPluginSettings.java b/core/java/android/webkit/gears/GearsPluginSettings.java
deleted file mode 100644
index d36d3fb..0000000
--- a/core/java/android/webkit/gears/GearsPluginSettings.java
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2008 The Android Open Source Project
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// 3. Neither the name of Google Inc. nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package android.webkit.gears;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.util.Log;
-import android.webkit.Plugin;
-import android.webkit.Plugin.PreferencesClickHandler;
-
-/**
- * Simple bridge class intercepting the click in the
- * browser plugin list and calling the Gears settings
- * dialog.
- */
-public class GearsPluginSettings {
-
- private static final String TAG = "Gears-J-GearsPluginSettings";
- private Context context;
-
- public GearsPluginSettings(Plugin plugin) {
- plugin.setClickHandler(new ClickHandler());
- }
-
- /**
- * We do not need to call the dialog synchronously here (doing so
- * actually cause a lot of problems as the main message loop is also
- * blocked), which is why we simply call it via a thread.
- */
- private class ClickHandler implements PreferencesClickHandler {
- public void handleClickEvent(Context aContext) {
- context = aContext;
- Thread startService = new Thread(new StartService());
- startService.run();
- }
- }
-
- private static native void runSettingsDialog(Context c);
-
- /**
- * StartService is the runnable we use to open the dialog.
- * We bind the service to serviceConnection; upon
- * onServiceConnected the dialog will be called from the
- * native side using the runSettingsDialog method.
- */
- private class StartService implements Runnable {
- public void run() {
- HtmlDialogAndroid.bindToService(context, serviceConnection);
- }
- }
-
- /**
- * ServiceConnection instance.
- * onServiceConnected is called upon connection with the service;
- * we can then safely open the dialog.
- */
- private ServiceConnection serviceConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- IGearsDialogService gearsDialogService =
- IGearsDialogService.Stub.asInterface(service);
- HtmlDialogAndroid.setGearsDialogService(gearsDialogService);
- runSettingsDialog(context);
- context.unbindService(serviceConnection);
- HtmlDialogAndroid.setGearsDialogService(null);
- }
- public void onServiceDisconnected(ComponentName className) {
- HtmlDialogAndroid.setGearsDialogService(null);
- }
- };
-}
diff --git a/core/java/android/webkit/gears/HtmlDialogAndroid.java b/core/java/android/webkit/gears/HtmlDialogAndroid.java
deleted file mode 100644
index 6209ab9..0000000
--- a/core/java/android/webkit/gears/HtmlDialogAndroid.java
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2008 The Android Open Source Project
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// 3. Neither the name of Google Inc. nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package android.webkit.gears;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.webkit.CacheManager;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * Utility class to call a modal HTML dialog on Android
- */
-public class HtmlDialogAndroid {
-
- private static final String TAG = "Gears-J-HtmlDialog";
- private static final String DIALOG_PACKAGE = "com.android.browser";
- private static final String DIALOG_SERVICE = DIALOG_PACKAGE
- + ".GearsDialogService";
- private static final String DIALOG_INTERFACE = DIALOG_PACKAGE
- + ".IGearsDialogService";
-
- private static IGearsDialogService gearsDialogService;
-
- public static void setGearsDialogService(IGearsDialogService service) {
- gearsDialogService = service;
- }
-
- /**
- * Bind to the GearsDialogService.
- */
- public static boolean bindToService(Context context,
- ServiceConnection serviceConnection) {
- Intent dialogIntent = new Intent();
- dialogIntent.setClassName(DIALOG_PACKAGE, DIALOG_SERVICE);
- dialogIntent.setAction(DIALOG_INTERFACE);
- return context.bindService(dialogIntent, serviceConnection,
- Context.BIND_AUTO_CREATE);
- }
-
- /**
- * Bind to the GearsDialogService synchronously.
- * The service is started using our own defaultServiceConnection
- * handler, and we wait until the handler notifies us.
- */
- public void synchronousBindToService(Context context) {
- try {
- if (bindToService(context, defaultServiceConnection)) {
- if (gearsDialogService == null) {
- synchronized(defaultServiceConnection) {
- defaultServiceConnection.wait(3000); // timeout after 3s
- }
- }
- }
- } catch (InterruptedException e) {
- Log.e(TAG, "exception: " + e);
- }
- }
-
- /**
- * Read the HTML content from the disk
- */
- public String readHTML(String filePath) {
- FileInputStream inputStream = null;
- String content = "";
- try {
- inputStream = new FileInputStream(filePath);
- StringBuffer out = new StringBuffer();
- byte[] buffer = new byte[4096];
- for (int n; (n = inputStream.read(buffer)) != -1;) {
- out.append(new String(buffer, 0, n));
- }
- content = out.toString();
- } catch (IOException e) {
- Log.e(TAG, "exception: " + e);
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException e) {
- Log.e(TAG, "exception: " + e);
- }
- }
- }
- return content;
- }
-
- /**
- * Open an HTML dialog synchronously and waits for its completion.
- * The dialog is accessed through the GearsDialogService provided by
- * the Android Browser.
- * We can be called either directly, and then gearsDialogService will
- * not be set and we will bind to the service synchronously, and unbind
- * after calling the service, or called indirectly via GearsPluginSettings.
- * In the latter case, GearsPluginSettings does the binding/unbinding.
- */
- public String showDialog(Context context, String htmlFilePath,
- String arguments) {
-
- CacheManager.endCacheTransaction();
-
- String ret = null;
- boolean synchronousCall = false;
- if (gearsDialogService == null) {
- synchronousCall = true;
- synchronousBindToService(context);
- }
-
- try {
- if (gearsDialogService != null) {
- String htmlContent = readHTML(htmlFilePath);
- if (htmlContent.length() > 0) {
- ret = gearsDialogService.showDialog(htmlContent, arguments,
- !synchronousCall);
- }
- } else {
- Log.e(TAG, "Could not connect to the GearsDialogService!");
- }
- if (synchronousCall) {
- context.unbindService(defaultServiceConnection);
- gearsDialogService = null;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "remote exception: " + e);
- gearsDialogService = null;
- }
-
- CacheManager.startCacheTransaction();
-
- return ret;
- }
-
- private ServiceConnection defaultServiceConnection =
- new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- synchronized (defaultServiceConnection) {
- gearsDialogService = IGearsDialogService.Stub.asInterface(service);
- defaultServiceConnection.notify();
- }
- }
- public void onServiceDisconnected(ComponentName className) {
- gearsDialogService = null;
- }
- };
-}
diff --git a/core/java/android/webkit/gears/IGearsDialogService.java b/core/java/android/webkit/gears/IGearsDialogService.java
deleted file mode 100644
index 82a3bd9..0000000
--- a/core/java/android/webkit/gears/IGearsDialogService.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: android.webkit.gears/IGearsDialogService.aidl
- */
-package android.webkit.gears;
-import java.lang.String;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Binder;
-import android.os.Parcel;
-public interface IGearsDialogService extends android.os.IInterface
-{
-/** Local-side IPC implementation stub class. */
-public static abstract class Stub extends android.os.Binder implements android.webkit.gears.IGearsDialogService
-{
-private static final java.lang.String DESCRIPTOR = "com.android.browser.IGearsDialogService";
-/** Construct the stub at attach it to the interface. */
-public Stub()
-{
-this.attachInterface(this, DESCRIPTOR);
-}
-/**
- * Cast an IBinder object into an IGearsDialogService interface,
- * generating a proxy if needed.
- */
-public static android.webkit.gears.IGearsDialogService asInterface(android.os.IBinder obj)
-{
-if ((obj==null)) {
-return null;
-}
-android.webkit.gears.IGearsDialogService in = (android.webkit.gears.IGearsDialogService)obj.queryLocalInterface(DESCRIPTOR);
-if ((in!=null)) {
-return in;
-}
-return new android.webkit.gears.IGearsDialogService.Stub.Proxy(obj);
-}
-public android.os.IBinder asBinder()
-{
-return this;
-}
-public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
-{
-switch (code)
-{
-case INTERFACE_TRANSACTION:
-{
-reply.writeString(DESCRIPTOR);
-return true;
-}
-case TRANSACTION_showDialog:
-{
-data.enforceInterface(DESCRIPTOR);
-java.lang.String _arg0;
-_arg0 = data.readString();
-java.lang.String _arg1;
-_arg1 = data.readString();
-boolean _arg2;
-_arg2 = (0!=data.readInt());
-java.lang.String _result = this.showDialog(_arg0, _arg1, _arg2);
-reply.writeNoException();
-reply.writeString(_result);
-return true;
-}
-}
-return super.onTransact(code, data, reply, flags);
-}
-private static class Proxy implements android.webkit.gears.IGearsDialogService
-{
-private android.os.IBinder mRemote;
-Proxy(android.os.IBinder remote)
-{
-mRemote = remote;
-}
-public android.os.IBinder asBinder()
-{
-return mRemote;
-}
-public java.lang.String getInterfaceDescriptor()
-{
-return DESCRIPTOR;
-}
-public java.lang.String showDialog(java.lang.String htmlContent, java.lang.String dialogArguments, boolean inSettings) throws android.os.RemoteException
-{
-android.os.Parcel _data = android.os.Parcel.obtain();
-android.os.Parcel _reply = android.os.Parcel.obtain();
-java.lang.String _result;
-try {
-_data.writeInterfaceToken(DESCRIPTOR);
-_data.writeString(htmlContent);
-_data.writeString(dialogArguments);
-_data.writeInt(((inSettings)?(1):(0)));
-mRemote.transact(Stub.TRANSACTION_showDialog, _data, _reply, 0);
-_reply.readException();
-_result = _reply.readString();
-}
-finally {
-_reply.recycle();
-_data.recycle();
-}
-return _result;
-}
-}
-static final int TRANSACTION_showDialog = (IBinder.FIRST_CALL_TRANSACTION + 0);
-}
-public java.lang.String showDialog(java.lang.String htmlContent, java.lang.String dialogArguments, boolean inSettings) throws android.os.RemoteException;
-}
diff --git a/core/java/android/widget/Adapter.java b/core/java/android/widget/Adapter.java
index e952dd5..f2b3e2a 100644
--- a/core/java/android/widget/Adapter.java
+++ b/core/java/android/widget/Adapter.java
@@ -116,7 +116,7 @@ public interface Adapter {
* can be converted to the other in {@link #getView}. Note: Integers must be in the
* range 0 to {@link #getViewTypeCount} - 1. {@link #IGNORE_ITEM_VIEW_TYPE} can
* also be returned.
- * @see IGNORE_ITEM_VIEW_TYPE
+ * @see #IGNORE_ITEM_VIEW_TYPE
*/
int getItemViewType(int position);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bdc54ff..c852be5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4132,8 +4132,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
removeParcelableSpans(content, start, end);
content.replace(start, end, text.text);
}
- Selection.setSelection((Spannable)getText(),
- text.selectionStart, text.selectionEnd);
+
+ // Now set the selection position... make sure it is in range, to
+ // avoid crashes. If this is a partial update, it is possible that
+ // the underlying text may have changed, causing us problems here.
+ // Also we just don't want to trust clients to do the right thing.
+ Spannable sp = (Spannable)getText();
+ final int N = sp.length();
+ int start = text.selectionStart;
+ if (start < 0) start = 0;
+ else if (start > N) start = N;
+ int end = text.selectionEnd;
+ if (end < 0) end = 0;
+ else if (end > N) end = N;
+ Selection.setSelection(sp, start, end);
}
/**
diff --git a/core/java/android/widget/ZoomRing.java b/core/java/android/widget/ZoomRing.java
index 22881b3..a29e1a0 100644
--- a/core/java/android/widget/ZoomRing.java
+++ b/core/java/android/widget/ZoomRing.java
@@ -84,6 +84,10 @@ public class ZoomRing extends View {
private Drawable mThumbPlusArrowDrawable;
/** Shown beneath the thumb if we can still zoom out. */
private Drawable mThumbMinusArrowDrawable;
+ private static final int THUMB_ARROW_PLUS = 1 << 0;
+ private static final int THUMB_ARROW_MINUS = 1 << 1;
+ /** Bitwise-OR of {@link #THUMB_ARROW_MINUS} and {@link #THUMB_ARROW_PLUS} */
+ private int mThumbArrowsToDraw;
private static final int THUMB_ARROWS_FADE_DURATION = 300;
private long mThumbArrowsFadeStartTime;
private int mThumbArrowsAlpha = 255;
@@ -166,7 +170,7 @@ public class ZoomRing extends View {
// TODO: add padding to drawable
setBackgroundResource(R.drawable.zoom_ring_track);
// TODO get from style
- setRingBounds(30, Integer.MAX_VALUE);
+ setRingBounds(43, Integer.MAX_VALUE);
mThumbHalfHeight = mThumbDrawable.getIntrinsicHeight() / 2;
mThumbHalfWidth = mThumbDrawable.getIntrinsicWidth() / 2;
@@ -276,7 +280,7 @@ public class ZoomRing extends View {
thumbCenterX + mThumbHalfWidth,
thumbCenterY + mThumbHalfHeight);
- if (mThumbArrowsAlpha > 0) {
+ if (mThumbArrowsToDraw > 0) {
setThumbArrowsAngle(angle);
}
@@ -420,12 +424,15 @@ public class ZoomRing extends View {
switch (action) {
case MotionEvent.ACTION_DOWN:
- mCallback.onUserInteractionStarted();
-
if (time - mPreviousUpTime <= DOUBLE_TAP_DISMISS_TIMEOUT) {
mCallback.onZoomRingDismissed(true);
+ onTouchUp(time);
+
+ // Dismissing, so halt here
+ return true;
}
+ mCallback.onUserInteractionStarted();
mPreviousDownX = x;
mPreviousDownY = y;
resetState();
@@ -441,23 +448,7 @@ public class ZoomRing extends View {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
- mCallback.onZoomRingSetMovableHintVisible(false);
- if (mMode == MODE_MOVE_ZOOM_RING) {
- mCallback.onZoomRingMovingStopped();
- }
- } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG ||
- mMode == MODE_WAITING_FOR_DRAG_THUMB) {
- onThumbDragStopped();
-
- if (mMode == MODE_DRAG_THUMB) {
- // Animate back to a tick
- setThumbAngleAnimated(mPreviousCallbackAngle, 0);
- }
- }
-
- mPreviousUpTime = time;
- mCallback.onUserInteractionStopped();
+ onTouchUp(time);
return true;
default:
@@ -524,10 +515,9 @@ public class ZoomRing extends View {
deltaThumbAndTick = getDelta(mThumbAngle, tickAngle, !oldDirectionIsCcw);
boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick);
if (boundAngle != Integer.MIN_VALUE) {
- Log
- .d(
- TAG,
- "Tapped somewhere where the shortest distance goes through a bound, but then the opposite direction also went through a bound!");
+ // Not allowed to be here, it is between two bounds
+ mMode = MODE_IGNORE_UNTIL_UP;
+ return true;
}
}
}
@@ -574,6 +564,26 @@ public class ZoomRing extends View {
return true;
}
+
+ private void onTouchUp(long time) {
+ if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingSetMovableHintVisible(false);
+ if (mMode == MODE_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingMovingStopped();
+ }
+ } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG ||
+ mMode == MODE_WAITING_FOR_DRAG_THUMB) {
+ onThumbDragStopped();
+
+ if (mMode == MODE_DRAG_THUMB) {
+ // Animate back to a tick
+ setThumbAngleAnimated(mPreviousCallbackAngle, 0);
+ }
+ }
+
+ mPreviousUpTime = time;
+ mCallback.onUserInteractionStopped();
+ }
private boolean isDeltaInBounds(int startAngle, int deltaAngle) {
return getBoundIfExceeds(startAngle, deltaAngle) == Integer.MIN_VALUE;
@@ -766,9 +776,11 @@ public class ZoomRing extends View {
}
}
- int deltaAngle = getDelta(mThumbAngle, touchAngle, useDirection, ccw);
- mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
-
+ if (DRAW_TRAIL) {
+ int deltaAngle = getDelta(mThumbAngle, touchAngle, useDirection, ccw);
+ mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
+ }
+
if (animateThumbToNewAngle) {
if (useDirection) {
setThumbAngleAnimated(touchAngle, 0, ccw);
@@ -851,15 +863,10 @@ public class ZoomRing extends View {
if (DRAW_TRAIL) {
mTrail.draw(canvas);
}
-
- // If we aren't near the bounds, draw the corresponding arrows
- int callbackAngle = mPreviousCallbackAngle;
- if (callbackAngle < mThumbCwBound - RADIAN_INT_ERROR ||
- callbackAngle > mThumbCwBound + RADIAN_INT_ERROR) {
+ if ((mThumbArrowsToDraw & THUMB_ARROW_PLUS) != 0) {
mThumbPlusArrowDrawable.draw(canvas);
}
- if (callbackAngle < mThumbCcwBound - RADIAN_INT_ERROR ||
- callbackAngle > mThumbCcwBound + RADIAN_INT_ERROR) {
+ if ((mThumbArrowsToDraw & THUMB_ARROW_MINUS) != 0) {
mThumbMinusArrowDrawable.draw(canvas);
}
mThumbDrawable.draw(canvas);
@@ -875,8 +882,21 @@ public class ZoomRing extends View {
public void setThumbArrowsVisible(boolean visible) {
if (visible) {
mThumbArrowsAlpha = 255;
- mThumbPlusArrowDrawable.setAlpha(255);
- mThumbMinusArrowDrawable.setAlpha(255);
+ int callbackAngle = mPreviousCallbackAngle;
+ if (callbackAngle < mThumbCwBound - RADIAN_INT_ERROR ||
+ callbackAngle > mThumbCwBound + RADIAN_INT_ERROR) {
+ mThumbPlusArrowDrawable.setAlpha(255);
+ mThumbArrowsToDraw |= THUMB_ARROW_PLUS;
+ } else {
+ mThumbArrowsToDraw &= ~THUMB_ARROW_PLUS;
+ }
+ if (callbackAngle < mThumbCcwBound - RADIAN_INT_ERROR ||
+ callbackAngle > mThumbCcwBound + RADIAN_INT_ERROR) {
+ mThumbMinusArrowDrawable.setAlpha(255);
+ mThumbArrowsToDraw |= THUMB_ARROW_MINUS;
+ } else {
+ mThumbArrowsToDraw &= ~THUMB_ARROW_MINUS;
+ }
invalidate();
} else if (mThumbArrowsAlpha == 255) {
// Only start fade if we're fully visible (otherwise another fade is happening already)
@@ -886,17 +906,24 @@ public class ZoomRing extends View {
}
private void onThumbArrowsFadeTick() {
- if (mThumbArrowsAlpha <= 0) return;
+ if (mThumbArrowsAlpha <= 0) {
+ mThumbArrowsToDraw = 0;
+ return;
+ }
mThumbArrowsAlpha = (int)
(255 - (255 * (SystemClock.elapsedRealtime() - mThumbArrowsFadeStartTime)
/ THUMB_ARROWS_FADE_DURATION));
if (mThumbArrowsAlpha < 0) mThumbArrowsAlpha = 0;
- mThumbPlusArrowDrawable.setAlpha(mThumbArrowsAlpha);
- mThumbMinusArrowDrawable.setAlpha(mThumbArrowsAlpha);
- invalidateDrawable(mThumbPlusArrowDrawable);
- invalidateDrawable(mThumbMinusArrowDrawable);
-
+ if ((mThumbArrowsToDraw & THUMB_ARROW_PLUS) != 0) {
+ mThumbPlusArrowDrawable.setAlpha(mThumbArrowsAlpha);
+ invalidateDrawable(mThumbPlusArrowDrawable);
+ }
+ if ((mThumbArrowsToDraw & THUMB_ARROW_MINUS) != 0) {
+ mThumbMinusArrowDrawable.setAlpha(mThumbArrowsAlpha);
+ invalidateDrawable(mThumbMinusArrowDrawable);
+ }
+
if (!mHandler.hasMessages(MSG_THUMB_ARROWS_FADE_TICK)) {
mHandler.sendEmptyMessage(MSG_THUMB_ARROWS_FADE_TICK);
}
diff --git a/core/java/android/widget/ZoomRingController.java b/core/java/android/widget/ZoomRingController.java
index 31074b6..2e97fda 100644
--- a/core/java/android/widget/ZoomRingController.java
+++ b/core/java/android/widget/ZoomRingController.java
@@ -57,7 +57,7 @@ import android.view.animation.DecelerateInterpolator;
public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
View.OnTouchListener, View.OnKeyListener {
- private static final int ZOOM_RING_RADIUS_INSET = 10;
+ private static final int ZOOM_RING_RADIUS_INSET = 24;
private static final int ZOOM_RING_RECENTERING_DURATION = 500;
@@ -79,7 +79,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private static final int MAX_PAN_GAP = 20;
private static final int MAX_INITIATE_PAN_GAP = 10;
// TODO view config
- private static final int INITIATE_PAN_DELAY = 400;
+ private static final int INITIATE_PAN_DELAY = 300;
private static final String SETTING_NAME_SHOWN_TOAST = "shown_zoom_ring_toast";
@@ -146,7 +146,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private int mZoomRingHeight;
/** Invokes panning of owner view if the zoom ring is touching an edge. */
- private Panner mPanner = new Panner();
+ private Panner mPanner;
private long mTouchingEdgeStartTime;
private boolean mPanningEnabledForThisInteraction;
@@ -241,6 +241,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ mPanner = new Panner();
mOwnerView = ownerView;
mZoomRing = new ZoomRing(context);
@@ -389,6 +390,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
};
}
+ mPanningArrows.setAnimation(null);
+
mHandler.post(mPostedVisibleInitializer);
// Handle configuration changes when visible
@@ -409,12 +412,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
} else {
mOwnerView.setOnTouchListener(null);
}
-
+
// No longer care about configuration changes
mContext.unregisterReceiver(mConfigurationChangedReceiver);
mWindowManager.removeView(mContainer);
-
+ mHandler.removeCallbacks(mPostedVisibleInitializer);
+
if (mCallback != null) {
mCallback.onVisibilityChanged(false);
}
@@ -464,6 +468,9 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public boolean handleDoubleTapEvent(MotionEvent event) {
int action = event.getAction();
+ // TODO: make sure this works well with the
+ // ownerView.setOnTouchListener(this) instead of window receiving
+ // touches
if (action == MotionEvent.ACTION_DOWN) {
mTouchMode = TOUCH_MODE_WAITING_FOR_TAP_DRAG_MOVEMENT;
int x = (int) event.getX();
@@ -493,6 +500,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mViewConfig.getScaledTouchSlop()) {
mZoomRing.setTapDragMode(true, x, y);
mTouchMode = TOUCH_MODE_FORWARDING_FOR_TAP_DRAG;
+ setTouchTargetView(mZoomRing);
}
return true;
@@ -587,7 +595,6 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void onZoomRingMovingStarted() {
mScroller.abortAnimation();
- mPanningEnabledForThisInteraction = false;
mTouchingEdgeStartTime = 0;
if (mCallback != null) {
mCallback.onBeginPan();
@@ -658,6 +665,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
if (!horizontalPanning) {
// Neither are panning, reset any timer to start pan mode
mTouchingEdgeStartTime = 0;
+ mPanningEnabledForThisInteraction = false;
+ mPanner.stop();
}
}
}
@@ -752,6 +761,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
// The ring was dismissed but we need to throw away all events until the up
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
mOwnerView.setOnTouchListener(null);
+ setTouchTargetView(null);
mReleaseTouchListenerOnUp = false;
}
@@ -763,16 +773,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
switch (action) {
case MotionEvent.ACTION_DOWN:
- targetView = mTouchTargetView =
- getViewForTouch((int) event.getRawX(), (int) event.getRawY());
- if (targetView != null) {
- targetView.getLocationInWindow(mTouchTargetLocationInWindow);
- }
+ targetView = getViewForTouch((int) event.getRawX(), (int) event.getRawY());
+ setTouchTargetView(targetView);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mTouchTargetView = null;
+ setTouchTargetView(null);
break;
}
@@ -799,6 +806,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
}
+ private void setTouchTargetView(View view) {
+ mTouchTargetView = view;
+ if (view != null) {
+ view.getLocationInWindow(mTouchTargetLocationInWindow);
+ }
+ }
+
/**
* Returns the View that should receive a touch at the given coordinates.
*
@@ -950,6 +964,22 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
}
+ public void setPannerStartVelocity(float startVelocity) {
+ mPanner.mStartVelocity = startVelocity;
+ }
+
+ public void setPannerAcceleration(float acceleration) {
+ mPanner.mAcceleration = acceleration;
+ }
+
+ public void setPannerMaxVelocity(float maxVelocity) {
+ mPanner.mMaxVelocity = maxVelocity;
+ }
+
+ public void setPannerStartAcceleratingDuration(int duration) {
+ mPanner.mStartAcceleratingDuration = duration;
+ }
+
private class Panner implements Runnable {
private static final int RUN_DELAY = 15;
private static final float STOP_SLOWDOWN = 0.8f;
@@ -967,6 +997,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
/** The time of the last callback to pan the map/browser/etc. */
private long mPreviousCallbackTime;
+ // TODO Adjust to be DPI safe
+ private float mStartVelocity = 135;
+ private float mAcceleration = 160;
+ private float mMaxVelocity = 1000;
+ private int mStartAcceleratingDuration = 700;
+ private float mVelocity;
+
/** -100 (full left) to 0 (none) to 100 (full right) */
public void setHorizontalStrength(int horizontalStrength) {
if (mHorizontalStrength == 0 && mVerticalStrength == 0 && horizontalStrength != 0) {
@@ -1013,11 +1050,12 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
boolean firstRun = mPreviousCallbackTime == 0;
long curTime = SystemClock.elapsedRealtime();
- int panAmount = getPanAmount(mStartTime, mPreviousCallbackTime, curTime);
+ int panAmount = getPanAmount(mPreviousCallbackTime, curTime);
mPreviousCallbackTime = curTime;
if (firstRun) {
mStartTime = curTime;
+ mVelocity = mStartVelocity;
} else {
int panX = panAmount * mHorizontalStrength / 100;
int panY = panAmount * mVerticalStrength / 100;
@@ -1030,12 +1068,22 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mUiHandler.postDelayed(this, RUN_DELAY);
}
- // TODO make setter for this value so zoom clients can have different pan rates, if they want
- private static final int PAN_VELOCITY_PX_S = 30;
- private int getPanAmount(long startTime, long previousTime, long currentTime) {
- return (int) ((currentTime - previousTime) * PAN_VELOCITY_PX_S / 100);
+ private int getPanAmount(long previousTime, long currentTime) {
+ if (mVelocity > mMaxVelocity) {
+ mVelocity = mMaxVelocity;
+ } else if (mVelocity < mMaxVelocity) {
+ // See if it's time to add in some acceleration
+ if (currentTime - mStartTime > mStartAcceleratingDuration) {
+ mVelocity += (currentTime - previousTime) * mAcceleration / 1000;
+ }
+ }
+
+ return (int) ((currentTime - previousTime) * mVelocity) / 1000;
}
+
}
+
+
public interface OnZoomListener {
void onBeginDrag();