Merge change 7833 into donut

* changes:
  Fixing the random audio mangling problem (TTS becomes incomprehensibly fast)
diff --git a/api/current.xml b/api/current.xml
index bb932e6..779d122 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -49036,6 +49036,21 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="canvas" type="android.graphics.Canvas">
+</parameter>
+</method>
+<method name="getScaledHeight"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="metrics" type="android.util.DisplayMetrics">
+</parameter>
 </method>
 <method name="getScaledWidth"
  return="int"
@@ -49047,6 +49062,21 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="canvas" type="android.graphics.Canvas">
+</parameter>
+</method>
+<method name="getScaledWidth"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="metrics" type="android.util.DisplayMetrics">
+</parameter>
 </method>
 <method name="getWidth"
  return="int"
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 903f482..cebb696 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -979,12 +979,12 @@
         /**
          * TODO: enable this before code freeze. b/1967935
          * *
-         */
         if ((densities == null || densities.length == 0)
                 && (pkg.applicationInfo.targetSdkVersion
                         >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
             pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY;
         }
+         */
 
         return pkg;
     }
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index d4e2507..6e34cc8 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -85,6 +85,11 @@
     private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE;
 
     /**
+     * The effective screen density we have selected for this application.
+     */
+    public final int applicationDensity;
+    
+    /**
      * Application's scale.
      */
     public final float applicationScale;
@@ -107,28 +112,34 @@
         }
         
         float packageDensityScale = -1.0f;
+        int packageDensity = 0;
         if (appInfo.supportsDensities != null) {
             int minDiff = Integer.MAX_VALUE;
             for (int density : appInfo.supportsDensities) {
-                if (density == ApplicationInfo.ANY_DENSITY) { 
+                if (density == ApplicationInfo.ANY_DENSITY) {
+                    packageDensity = DisplayMetrics.DENSITY_DEVICE;
                     packageDensityScale = 1.0f;
                     break;
                 }
                 int tmpDiff = Math.abs(DisplayMetrics.DENSITY_DEVICE - density);
                 if (tmpDiff == 0) {
+                    packageDensity = DisplayMetrics.DENSITY_DEVICE;
                     packageDensityScale = 1.0f;
                     break;
                 }
                 // prefer higher density (appScale>1.0), unless that's only option.
                 if (tmpDiff < minDiff && packageDensityScale < 1.0f) {
+                    packageDensity = density;
                     packageDensityScale = DisplayMetrics.DENSITY_DEVICE / (float) density;
                     minDiff = tmpDiff;
                 }
             }
         }
         if (packageDensityScale > 0.0f) {
+            applicationDensity = packageDensity;
             applicationScale = packageDensityScale;
         } else {
+            applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
             applicationScale =
                     DisplayMetrics.DENSITY_DEVICE / (float) DisplayMetrics.DENSITY_DEFAULT;
         }
@@ -139,9 +150,11 @@
         }
     }
 
-    private CompatibilityInfo(int appFlags, int compFlags, float scale, float invertedScale) {
+    private CompatibilityInfo(int appFlags, int compFlags,
+            int dens, float scale, float invertedScale) {
         this.appFlags = appFlags;
         mCompatibilityFlags = compFlags;
+        applicationDensity = dens;
         applicationScale = scale;
         applicationInvertedScale = invertedScale;
     }
@@ -151,6 +164,7 @@
                 | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
                 | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS,
                 EXPANDABLE | CONFIGURED_EXPANDABLE,
+                DisplayMetrics.DENSITY_DEVICE,
                 1.0f,
                 1.0f);
     }
@@ -160,7 +174,7 @@
      */
     public CompatibilityInfo copy() {
         CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags,
-                applicationScale, applicationInvertedScale);
+                applicationDensity, applicationScale, applicationInvertedScale);
         return info;
     }
  
@@ -210,8 +224,7 @@
             if (DBG) Log.d(TAG, "no translation required");
             return null;
         }
-        if (!isScalingRequired() ||
-            (params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
+        if (!isScalingRequired()) {
             return null;
         }
         return new Translator();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 28c1fe1fe..aa701af6 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -257,7 +257,7 @@
         // scales the event back to the pre-scaled coordinates for such surface.
         if (mScaled) {
             MotionEvent scaledBack = MotionEvent.obtain(event);
-            scaledBack.scale(mTranslator.applicationScale);
+            mTranslator.translateEventInScreenToAppWindow(event);
             try {
                 return super.dispatchTouchEvent(scaledBack);
             } finally {
@@ -296,7 +296,8 @@
         if (!mHaveFrame) {
             return;
         }
-        mTranslator = ((ViewRoot)getRootView().getParent()).mTranslator;
+        ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
+        mTranslator = viewRoot.mTranslator;
 
         float appScale = mTranslator == null ? 1.0f : mTranslator.applicationScale;
         
@@ -356,8 +357,10 @@
                               | WindowManager.LayoutParams.FLAG_SCALED
                               | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                               | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                              | WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING
                               ;
+                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
+                    mLayout.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+                }
 
                 mLayout.memoryType = mRequestedType;
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index ba3bfa7..6a26a31 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -483,19 +483,12 @@
          * {@hide} */
         public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
 
-        /** Window flag: special flag to let a window ignore the compatibility scaling.
-         * This is used by SurfaceView to pass this info into ViewRoot, and not used
-         * by WindowManager.
-         *
-         * {@hide} */
-        public static final int FLAG_NO_COMPATIBILITY_SCALING = 0x00100000;
-
         /** Window flag: special flag to limit the size of the window to be
          * original size ([320x480] x density). Used to create window for applications
          * running under compatibility mode.
          *
          * {@hide} */
-        public static final int FLAG_COMPATIBLE_WINDOW = 0x00200000;
+        public static final int FLAG_COMPATIBLE_WINDOW = 0x00100000;
 
         /** Window flag: a special option intended for system dialogs.  When
          * this flag is set, the window will demand focus unconditionally when
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index e62dda5..24c0e2a 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1295,11 +1295,8 @@
                     if (rule > 0) {
                         // The node this node depends on
                         final Node dependency = keyNodes.get(rule);
-                        if (dependency == node) {
-                            throw new IllegalStateException("A view cannot have a dependency" +
-                                    " on itself");
-                        }
-                        if (dependency == null) {
+                        // Skip unknowns and self dependencies
+                        if (dependency == null || dependency == node) {
                             continue;
                         }
                         // Add the current node as a dependent
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 141553e..df659ef 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.DisplayMetrics;
 
 import java.io.OutputStream;
 import java.nio.Buffer;
@@ -605,22 +606,60 @@
      * Convenience method that returns the width of this bitmap divided
      * by the density scale factor.
      *
+     * @param canvas The Canvas the bitmap will be drawn to.
      * @return The scaled width of this bitmap, according to the density scale factor.
      */
-    public int getScaledWidth() {
+    public int getScaledWidth(Canvas canvas) {
         final float scale = mDensityScale;
-        return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getWidth() / scale);
+        if (!mAutoScaling || scale < 0) {
+            return getWidth();
+        }
+        return (int)(getWidth() * canvas.getDensityScale() / scale);
     }
 
     /**
      * Convenience method that returns the height of this bitmap divided
      * by the density scale factor.
      *
+     * @param canvas The Canvas the bitmap will be drawn to.
      * @return The scaled height of this bitmap, according to the density scale factor.
      */
-    public int getScaledHeight() {
+    public int getScaledHeight(Canvas canvas) {
         final float scale = mDensityScale;
-        return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getHeight() / scale);
+        if (!mAutoScaling || scale < 0) {
+            return getHeight();
+        }
+        return (int)(getHeight() * canvas.getDensityScale() / scale);
+    }
+
+    /**
+     * Convenience method that returns the width of this bitmap divided
+     * by the density scale factor.
+     *
+     * @param metrics The target display metrics.
+     * @return The scaled width of this bitmap, according to the density scale factor.
+     */
+    public int getScaledWidth(DisplayMetrics metrics) {
+        final float scale = mDensityScale;
+        if (!mAutoScaling || scale < 0) {
+            return getWidth();
+        }
+        return (int)(getWidth() * metrics.density / scale);
+    }
+
+    /**
+     * Convenience method that returns the height of this bitmap divided
+     * by the density scale factor.
+     *
+     * @param metrics The target display metrics.
+     * @return The scaled height of this bitmap, according to the density scale factor.
+     */
+    public int getScaledHeight(DisplayMetrics metrics) {
+        final float scale = mDensityScale;
+        if (!mAutoScaling || scale < 0) {
+            return getHeight();
+        }
+        return (int)(getHeight() * metrics.density / scale);
     }
 
     /**
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index ee41021..58c04f3 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1327,10 +1327,12 @@
         }
 
         private void persistVolume(VolumeStreamState streamState) {
-            System.putInt(mContentResolver, streamState.mVolumeIndexSettingName,
-                    streamState.mIndex);
-            System.putInt(mContentResolver, streamState.mLastAudibleVolumeIndexSettingName,
-                    streamState.mLastAudibleIndex);
+            if (streamState.mStreamType != AudioManager.STREAM_BLUETOOTH_SCO) {
+                System.putInt(mContentResolver, streamState.mVolumeIndexSettingName,
+                        streamState.mIndex);
+                System.putInt(mContentResolver, streamState.mLastAudibleVolumeIndexSettingName,
+                        streamState.mLastAudibleIndex);
+            }
         }
 
         private void persistRingerMode() {
diff --git a/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
index c6c9452..e4c070f 100644
--- a/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
+++ b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
@@ -106,6 +106,13 @@
     @Override
     protected void performTask() throws IOException {
         String svc = mServiceName;
+        Log.d(mTag, "-----  Stop the daemon just in case: " + mServiceName);
+        SystemProperties.set(SVC_STOP_CMD, mServiceName);
+        if (!blockUntil(SVC_STATE_STOPPED, 5)) {
+            throw new IOException("cannot start service anew: " + svc
+                    + ", it is still running");
+        }
+
         Log.d(mTag, "+++++  Start: " + svc);
         SystemProperties.set(SVC_START_CMD, svc);
 
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
index 7eb3287..32b8e51 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
@@ -57,6 +57,7 @@
     public void onStart (Intent intent, int startId) {
         super.onStart(intent, startId);
         setForeground(true);
+        android.util.Log.d("VpnServiceBinder", "becomes a foreground service");
     }
 
     public IBinder onBind(Intent intent) {
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index b85cf2c..d8dafb6 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4905,6 +4905,22 @@
                     pw.print("    resourcePath="); pw.println(ps.resourcePathString);
                     if (ps.pkg != null) {
                         pw.print("    dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
+                        pw.print("    targetSdk="); pw.println(ps.pkg.applicationInfo.targetSdkVersion);
+                        pw.print("    densities="); pw.println(ps.pkg.supportsDensityList);
+                        ArrayList<String> screens = new ArrayList<String>();
+                        if ((ps.pkg.applicationInfo.flags & 
+                                ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
+                            screens.add("medium");
+                        }
+                        if ((ps.pkg.applicationInfo.flags & 
+                                ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
+                            screens.add("large");
+                        }
+                        if ((ps.pkg.applicationInfo.flags & 
+                                ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
+                            screens.add("small,");
+                        }
+                        pw.print("    supportsScreens="); pw.println(screens);
                     }
                     pw.print("    timeStamp="); pw.println(ps.getTimeStampStr());
                     pw.print("    signatures="); pw.println(ps.signatures);
diff --git a/tests/DpiTest/AndroidManifest.xml b/tests/DpiTest/AndroidManifest.xml
index ea355a4..68ecc6e 100644
--- a/tests/DpiTest/AndroidManifest.xml
+++ b/tests/DpiTest/AndroidManifest.xml
@@ -25,7 +25,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity android:name="DpiTestActivityNoCompat" android:label="DpiTestCompat">
+        <activity android:name="DpiTestNoCompatActivity" android:label="DpiTestNoCompat">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
index 9169025..8c69305 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -17,6 +17,8 @@
 package com.google.android.test.dpi;
 
 import android.app.Activity;
+import android.app.ActivityThread;
+import android.app.Application;
 import android.os.Bundle;
 import android.graphics.BitmapFactory;
 import android.graphics.Bitmap;
@@ -31,6 +33,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.CompatibilityInfo;
+import android.util.DisplayMetrics;
 
 public class DpiTestActivity extends Activity {
     public DpiTestActivity() {
@@ -45,7 +48,10 @@
     
     public void init(boolean noCompat) {
         try {
-            ApplicationInfo ai = getPackageManager().getApplicationInfo(
+            // This is all a dirty hack.  Don't think a real application should
+            // be doing it.
+            Application app = ActivityThread.currentActivityThread().getApplication();
+            ApplicationInfo ai = app.getPackageManager().getApplicationInfo(
                     "com.google.android.test.dpi",
                     PackageManager.GET_SUPPORTS_DENSITIES);
             if (noCompat) {
@@ -53,8 +59,8 @@
                     | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
                     | ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
                 ai.supportsDensities = new int[] { ApplicationInfo.ANY_DENSITY };
+                app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai));
             }
-            getResources().setCompatibilityInfo(new CompatibilityInfo(ai));
         } catch (PackageManager.NameNotFoundException e) {
             throw new RuntimeException("ouch", e);
         }
@@ -192,7 +198,10 @@
         @Override
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-            setMeasuredDimension(mBitmap.getScaledWidth(), mBitmap.getScaledHeight());
+            final DisplayMetrics metrics = getResources().getDisplayMetrics();
+            setMeasuredDimension(
+                    mBitmap.getScaledWidth(metrics),
+                    mBitmap.getScaledHeight(metrics));
         }
 
         @Override