am b1110149: merge from open-source master

Merge commit 'b1110149cccc3b99e59ead34ca46e5ac026f6db9' into kraken

* commit 'b1110149cccc3b99e59ead34ca46e5ac026f6db9':
  Use integer for loop counter instead of float
  New test in FrameworkTest for the VelocityTracker class
  Preserve '+' in phone numbers imported from SIM.
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index aab76c4..e69b807 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -206,7 +206,7 @@
             final long oldestTime = pastTime[oldestTouch];
             float accumX = 0;
             float accumY = 0;
-            float N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1;
+            int N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1;
             // Skip the last received event, since it is probably pretty noisy.
             if (N > 3) N--;
 
diff --git a/core/tests/coretests/src/android/view/VelocityTest.java b/core/tests/coretests/src/android/view/VelocityTest.java
new file mode 100644
index 0000000..fb28e1e
--- /dev/null
+++ b/core/tests/coretests/src/android/view/VelocityTest.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.frameworktest.view;
+
+import junit.framework.Assert;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+
+/**
+ * Exercises {@link android.view.VelocityTracker} to compute correct velocity.<br>
+ * To launch this test, use :<br>
+ * <code>./development/testrunner/runtest.py framework -c com.android.frameworktest.view.VelocityTest</code>
+ */
+public class VelocityTest extends InstrumentationTestCase {
+
+    @MediumTest
+    public void testInitialCondiditions() {
+        VelocityTracker vt = VelocityTracker.obtain();
+        assertNotNull(vt);
+        vt.recycle();
+    }
+
+    /**
+     * Test that {@link android.view.VelocityTracker}.clear() clears
+     * the previous values after a call to computeCurrentVelocity()
+     */
+    @MediumTest
+    public void testClear() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 300);
+        vt.computeCurrentVelocity(1);
+        assertFalse("Velocity should not be null", vt.getXVelocity() == 0.0f);
+        assertFalse("Velocity should not be null", vt.getYVelocity() == 0.0f);
+        vt.clear();
+        vt.computeCurrentVelocity(1);
+        assertEquals(0.0f, vt.getXVelocity());
+        assertEquals(0.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragAcceleration () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 15, t, 400, new AccelerateInterpolator());
+        vt.computeCurrentVelocity(1000);
+        assertGreater(250.0f, vt.getXVelocity());
+        assertGreater(250.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragDeceleration () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 15, t, 400, new DecelerateInterpolator());
+        vt.computeCurrentVelocity(1000);
+        assertLower(250.0f, vt.getXVelocity());
+        assertLower(250.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragLinearHorizontal() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        // 100px in 400ms => 250px/s
+        drag(vt, 100, 200, 200, 200, 15, t, 400);
+        vt.computeCurrentVelocity(1000);
+        assertEquals(0.0f, vt.getYVelocity());
+        assertEqualFuzzy(250.0f, vt.getXVelocity(), 4f);
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragLinearVertical() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        // 100px in 400ms => 250px/s
+        drag(vt, 200, 200, 100, 200, 15, t, 400);
+        vt.computeCurrentVelocity(1000);
+        assertEquals(0.0f, vt.getXVelocity());
+        assertEqualFuzzy(250.0f, vt.getYVelocity(), 4f);
+        vt.recycle();
+    }
+
+    /**
+     * Test dragging with two points only
+     * (velocity must be an exact value)
+     */
+    @MediumTest
+    public void testDragWith2Points () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        // 100px, 2 steps, 100ms => 1000px/s
+        drag(vt, 100, 200, 100, 200, 2, t, 100);
+        vt.computeCurrentVelocity(1000);
+        assertEquals(1000.0f, vt.getXVelocity());
+        assertEquals(1000.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    /**
+     * Velocity is independent of the number of points used during
+     * the same interval
+     */
+    @MediumTest
+    public void testStabilityInNbPoints () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 400); // 10 steps over 400ms
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.clear();
+        drag(vt, 100, 200, 100, 200, 20, t, 400); // 20 steps over 400ms
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX, 0.1f);
+        assertEqualFuzzy(firstY, secondY, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Velocity is independent of the time when the events occurs,
+     * it only depends on delays between the events.
+     */
+    @MediumTest
+    public void testStabilityInTime () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 400);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.clear();
+        drag(vt, 100, 200, 100, 200, 10, t + 3600*1000, 400); // on hour later
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX, 0.1f);
+        assertEqualFuzzy(firstY, secondY, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Velocity is independent of the position of the events,
+     * it only depends on their relative distance.
+     */
+    @MediumTest
+    public void testStabilityInSpace () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 400);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.clear();
+        drag(vt, 200, 300, 200, 300, 10, t, 400); // 100px further
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX, 0.1f);
+        assertEqualFuzzy(firstY, secondY, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Test that calls to {@link android.view.VelocityTracker}.computeCurrentVelocity()
+     * will output same values when using the same data.
+     */
+    @MediumTest
+    public void testStabilityOfComputation() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 300);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEquals(firstX, secondX);
+        assertEquals(firstY, secondY);
+        vt.recycle();
+    }
+
+    /**
+     * Test the units parameter of {@link android.view.VelocityTracker}.computeCurrentVelocity()
+     */
+    @MediumTest
+    public void testStabilityOfUnits() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 300);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.computeCurrentVelocity(1000);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX / 1000.0f, 0.1f);
+        assertEqualFuzzy(firstY, secondY / 1000.0f, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Simulate a drag by giving directly MotionEvents to
+     * the VelocityTracker using a linear interpolator
+     */
+    private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
+            long startime, int duration) {
+        drag(vt, startX, endX, startY, endY, steps, startime, duration, new LinearInterpolator());
+    }
+
+    /**
+     * Simulate a drag by giving directly MotionEvents to
+     * the VelocityTracker using a given interpolator
+     */
+    private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
+            long startime, int duration, Interpolator interpolator) {
+        addMotionEvent(vt, startX, startY, startime, MotionEvent.ACTION_DOWN);
+        float dt = duration / (float)steps;
+        int distX = endX - startX;
+        int distY = endY - startY;
+        for (int i=1; i<steps-1; i++) {
+            float ii = interpolator.getInterpolation(i / (float)steps);
+            int x = (int) (startX + distX * ii);
+            int y = (int) (startY + distY * ii);
+            long time = startime + (int) (i * dt);
+            addMotionEvent(vt, x, y, time, MotionEvent.ACTION_MOVE);
+        }
+        addMotionEvent(vt, endX, endY, startime + duration, MotionEvent.ACTION_UP);
+    }
+
+    private void addMotionEvent(VelocityTracker vt, int x, int y, long time, int action) {
+        MotionEvent me = MotionEvent.obtain(time, time, action, x, y, 0);
+        vt.addMovement(me);
+        me.recycle();
+    }
+
+    /**
+     * Float imprecision of the average computations and filtering
+     * (removing last MotionEvent for N > 3) implies that tests
+     *  accepts some approximated values.
+     */
+    private void assertEqualFuzzy(float expected, float actual, float threshold) {
+        boolean fuzzyEqual = actual >= expected - threshold && actual <= expected + threshold;
+        Assert.assertTrue("Expected: <"+expected+"> but was: <"+actual+
+                "> while accepting a variation of: <"+threshold+">", fuzzyEqual);
+    }
+
+    private void assertGreater(float minExpected, float actual) {
+        Assert.assertTrue("Expected: minimum <"+minExpected+"> but was: <"+actual+">",
+                actual > minExpected);
+    }
+
+    private void assertLower(float maxExpected, float actual) {
+        Assert.assertTrue("Expected: maximum <"+maxExpected+"> but was: <"+actual+">",
+                actual < maxExpected);
+    }
+}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 32e7176..a60d2be 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -732,7 +732,8 @@
             return "";
         }
 
-        if ((bytes[offset] & 0xff) == TOA_International) {
+        //Only TON field should be taken in consideration
+        if ((bytes[offset] & 0xf0) == (TOA_International & 0xf0)) {
             prependPlus = true;
         }
 
diff --git a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java
index b456a03..a74c5c2 100644
--- a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java
@@ -85,6 +85,16 @@
         assertEquals("17005550020",
             PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
 
+        b[0] = (byte) 0x80; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
+        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
+        assertEquals("17005550020",
+            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
+
+        b[0] = (byte) 0x90; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
+        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
+        assertEquals("+17005550020",
+            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
+
         b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
         b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
         assertEquals("+17005550020",