Merge "Support non-PorterDuff xfermodes with Xfermode."
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index ff34f4a..0999598 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -312,7 +312,7 @@
      * MotionEvent has no getRawX(int) method; simulate it pending future API approval. 
      */
     private static float getRawX(MotionEvent event, int pointerIndex) {
-        float offset = event.getX() - event.getRawX();
+        float offset = event.getRawX() - event.getX();
         return event.getX(pointerIndex) + offset;
     }
     
@@ -320,7 +320,7 @@
      * MotionEvent has no getRawY(int) method; simulate it pending future API approval. 
      */
     private static float getRawY(MotionEvent event, int pointerIndex) {
-        float offset = event.getY() - event.getRawY();
+        float offset = event.getRawY() - event.getY();
         return event.getY(pointerIndex) + offset;
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1b3975f..570793b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5602,7 +5602,7 @@
      * of ViewGroup that are responsible for arranging their children.
      * @return The LayoutParams associated with this view
      */
-    @ViewDebug.ExportedProperty(deepExport = true, category = "layout")
+    @ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_")
     public ViewGroup.LayoutParams getLayoutParams() {
         return mLayoutParams;
     }
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 7908f36..2ca08ea 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1377,9 +1377,8 @@
                 Object methodValue = method.invoke(view, (Object[]) null);
                 final Class<?> returnType = method.getReturnType();
                 final ExportedProperty property = sAnnotations.get(method);
-                String fullName = (property.category().length() == 0) ?
-                        method.getName() :
-                        (property.category() + ":" + method.getName());
+                String categoryPrefix =
+                        property.category().length() != 0 ? property.category() + ":" : "";
 
                 if (returnType == int.class) {
 
@@ -1390,7 +1389,8 @@
                         final FlagToString[] flagsMapping = property.flagMapping();
                         if (flagsMapping.length > 0) {
                             final int intValue = (Integer) methodValue;
-                            final String valuePrefix = prefix + fullName + '_';
+                            final String valuePrefix =
+                                    categoryPrefix + prefix + method.getName() + '_';
                             exportUnrolledFlags(out, flagsMapping, intValue, valuePrefix);
                         }
 
@@ -1415,7 +1415,7 @@
                     }
                 } else if (returnType == int[].class) {
                     final int[] array = (int[]) methodValue;
-                    final String valuePrefix = prefix + fullName + '_';
+                    final String valuePrefix = categoryPrefix + prefix + method.getName() + '_';
                     final String suffix = "()";
 
                     exportUnrolledArray(context, out, property, array, valuePrefix, suffix);
@@ -1429,7 +1429,7 @@
                     }
                 }
 
-                writeEntry(out, prefix, fullName, "()", methodValue);
+                writeEntry(out, categoryPrefix + prefix, method.getName(), "()", methodValue);
             } catch (IllegalAccessException e) {
             } catch (InvocationTargetException e) {
             }
@@ -1450,9 +1450,8 @@
                 Object fieldValue = null;
                 final Class<?> type = field.getType();
                 final ExportedProperty property = sAnnotations.get(field);
-                String fullName = (property.category().length() == 0) ?
-                        field.getName() :
-                        (property.category() + ":" + field.getName());
+                String categoryPrefix =
+                        property.category().length() != 0 ? property.category() + ":" : "";
 
                 if (type == int.class) {
 
@@ -1463,7 +1462,8 @@
                         final FlagToString[] flagsMapping = property.flagMapping();
                         if (flagsMapping.length > 0) {
                             final int intValue = field.getInt(view);
-                            final String valuePrefix = prefix + fullName + '_';
+                            final String valuePrefix =
+                                    categoryPrefix + prefix + field.getName() + '_';
                             exportUnrolledFlags(out, flagsMapping, intValue, valuePrefix);
                         }
 
@@ -1486,7 +1486,7 @@
                     }
                 } else if (type == int[].class) {
                     final int[] array = (int[]) field.get(view);
-                    final String valuePrefix = prefix + fullName + '_';
+                    final String valuePrefix = categoryPrefix + prefix + field.getName() + '_';
                     final String suffix = "";
 
                     exportUnrolledArray(context, out, property, array, valuePrefix, suffix);
@@ -1495,8 +1495,8 @@
                     return;
                 } else if (!type.isPrimitive()) {
                     if (property.deepExport()) {
-                        dumpViewProperties(context, field.get(view), out,
-                                prefix + property.prefix());
+                        dumpViewProperties(context, field.get(view), out, prefix
+                                + property.prefix());
                         continue;
                     }
                 }
@@ -1505,7 +1505,7 @@
                     fieldValue = field.get(view);
                 }
 
-                writeEntry(out, prefix, fullName, "", fieldValue);
+                writeEntry(out, categoryPrefix + prefix, field.getName(), "", fieldValue);
             } catch (IllegalAccessException e) {
             }
         }
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index 246f9fc..f70a145 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -51,4 +51,9 @@
          android:label="MediaRecorder stress tests InstrumentationRunner">
      </instrumentation>
 
+      <instrumentation android:name=".MediaFrameworkPowerTestRunner"
+         android:targetPackage="com.android.mediaframeworktest"
+         android:label="Media Power tests InstrumentationRunner">
+     </instrumentation>
+
 </manifest>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPowerTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPowerTestRunner.java
new file mode 100755
index 0000000..34db4db
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPowerTestRunner.java
@@ -0,0 +1,50 @@
+/*
+ * 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.mediaframeworktest;
+
+import com.android.mediaframeworktest.power.MediaPlayerPowerTest;
+
+import junit.framework.TestSuite;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+
+
+/**
+ * Instrumentation Test Runner for all MediaPlayer tests.
+ *
+ * Running all tests:
+ *
+ * adb shell am instrument \
+ *   -w com.android.mediaframeworktest/.MediaFrameworkPowerTestRunner
+ */
+
+public class MediaFrameworkPowerTestRunner extends InstrumentationTestRunner {
+
+  @Override
+  public TestSuite getAllTests() {
+      TestSuite suite = new InstrumentationTestSuite(this);
+      suite.addTestSuite(MediaPlayerPowerTest.class);
+      return suite;
+  }
+
+  @Override
+  public ClassLoader getLoader() {
+      return MediaFrameworkPowerTestRunner.class.getClassLoader();
+  }
+}
+
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/power/MediaPlayerPowerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/power/MediaPlayerPowerTest.java
new file mode 100644
index 0000000..9e91740
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/power/MediaPlayerPowerTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.mediaframeworktest.power;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+import android.media.MediaPlayer;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * Junit / Instrumentation test case for the power measurment the media player
+ */
+public class MediaPlayerPowerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+    private String TAG = "MediaPlayerPowerTest";
+    private String MP3_POWERTEST =
+            Environment.getExternalStorageDirectory().toString() + "/power_sample_mp3.mp3";
+    private String MP3_STREAM = "http://75.17.48.204:10088/power_media/power_sample_mp3.mp3";
+    private String OGG_STREAM = "http://75.17.48.204:10088/power_media/power_sample_ogg.mp3";
+    private String AAC_STREAM = "http://75.17.48.204:10088/power_media/power_sample_aac.mp3";
+
+    public MediaPlayerPowerTest() {
+        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+    }
+
+    protected void setUp() throws Exception {
+        getActivity();
+        super.setUp();
+
+    }
+
+    public void audioPlayback(String filePath) {
+        try {
+            MediaPlayer mp = new MediaPlayer();
+            mp.setDataSource(filePath);
+            mp.prepare();
+            mp.start();
+            Thread.sleep(200000);
+            mp.stop();
+            mp.release();
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+            assertTrue("MP3 Playback", false);
+        }
+    }
+
+    // A very simple test case which start the audio player.
+    // Power measurment will be done in other application.
+    public void testPowerLocalMP3Playback() throws Exception {
+        audioPlayback(MP3_POWERTEST);
+    }
+
+    public void testPowerStreamMP3Playback() throws Exception {
+        audioPlayback(MP3_STREAM);
+    }
+
+    public void testPowerStreamOGGPlayback() throws Exception {
+        audioPlayback(OGG_STREAM);
+    }
+
+    public void testPowerStreamAACPlayback() throws Exception {
+        audioPlayback(AAC_STREAM);
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 9d63c82..b35814c 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -109,6 +109,10 @@
         return mProfile.getProfileName();
     }
 
+    public String getSipUri() {
+        return mProfile.getUriString();
+    }
+
     public boolean canTake(Object incomingCall) {
         synchronized (SipPhone.class) {
             if (!(incomingCall instanceof SipAudioCall)) return false;
diff --git a/voip/java/android/net/sip/SipAudioCallImpl.java b/voip/java/android/net/sip/SipAudioCallImpl.java
index 57e0bd2..474bc4b 100644
--- a/voip/java/android/net/sip/SipAudioCallImpl.java
+++ b/voip/java/android/net/sip/SipAudioCallImpl.java
@@ -343,8 +343,11 @@
     public synchronized void endCall() throws SipException {
         try {
             stopRinging();
-            if (mSipSession != null) mSipSession.endCall();
             stopCall(true);
+            mInCall = false;
+
+            // perform the above local ops first and then network op
+            if (mSipSession != null) mSipSession.endCall();
         } catch (Throwable e) {
             throwSipException(e);
         }