Merge "Compose singleLine & textAllCaps transforms" into klp-dev
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 69b593a..5538dca 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -104,18 +104,6 @@
         Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
 
         /*
-         * In case the runtime switched since last boot (such as when
-         * the old runtime was removed in an OTA), set the system
-         * property so that it is in sync. We can't do this in
-         * libnativehelper's JniInvocation::Init code where we already
-         * had to fallback to a different runtime because it is
-         * running as root and we need to be the system user to set
-         * the property. http://b/11463182
-         */
-        SystemProperties.set("persist.sys.dalvik.vm.lib",
-                             VMRuntime.getRuntime().vmLibrary());
-
-        /*
          * Install a TimezoneGetter subclass for ZoneInfo.db
          */
         TimezoneGetter.setInstance(new TimezoneGetter() {
diff --git a/data/keyboards/AVRCP.kl b/data/keyboards/AVRCP.kl
index 736b43c..4c91ece 100644
--- a/data/keyboards/AVRCP.kl
+++ b/data/keyboards/AVRCP.kl
@@ -14,8 +14,8 @@
 
 # Key layout used for Bluetooth AVRCP support.
 
-key 200   MEDIA_PLAY          WAKE
-key 201   MEDIA_PAUSE         WAKE
+key 200   MEDIA_PLAY_PAUSE    WAKE
+key 201   MEDIA_PLAY_PAUSE    WAKE
 key 166   MEDIA_STOP          WAKE
 key 163   MEDIA_NEXT          WAKE
 key 165   MEDIA_PREVIOUS      WAKE
diff --git a/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java
index 677f1f1..2ee21acd 100644
--- a/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java
+++ b/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java
@@ -39,7 +39,7 @@
      *
      * @param b true to show, false to hide
      */
-    void showChallenge(boolean b);
+    void showChallenge(boolean show);
 
     /**
      * Show the bouncer challenge. This may block access to other child views.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
index c648177..f0413d6 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
@@ -120,21 +120,19 @@
 
     public void fadeOutSecurity(int duration) {
         ((View) mKeyguardSecurityContainer).animate().alpha(0f).setDuration(duration)
-                .setListener(mPauseListener).start();
+                .setListener(mPauseListener);
     }
 
     public void fadeInSecurity(int duration) {
         ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration)
-                .setListener(mResumeListener).start();
+                .setListener(mResumeListener);
     }
 
     public void onPageBeginMoving() {
         if (mChallengeLayout.isChallengeOverlapping() &&
                 mChallengeLayout instanceof SlidingChallengeLayout) {
             SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
-            if (!mKeyguardWidgetPager.isWarping()) {
-                scl.fadeOutChallenge();
-            }
+            scl.fadeOutChallenge();
             mPageIndexOnPageBeginMoving = mKeyguardWidgetPager.getCurrentPage();
         }
         // We use mAppWidgetToShow to show a particular widget after you add it--
@@ -158,9 +156,6 @@
             boolean isCameraPage = newPage instanceof CameraWidgetFrame;
             SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
             scl.setChallengeInteractive(!isCameraPage);
-            if (isCameraPage) {
-                scl.fadeOutChallenge();
-            }
             final int currentFlags = mKeyguardWidgetPager.getSystemUiVisibility();
             final int newFlags = isCameraPage ? (currentFlags | View.STATUS_BAR_DISABLE_SEARCH)
                     : (currentFlags & ~View.STATUS_BAR_DISABLE_SEARCH);
@@ -197,7 +192,7 @@
             boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
             if (challengeOverlapping && !newCurPage.isSmall()
                     && mPageListeningToSlider != newPageIndex) {
-                newCurPage.shrinkWidget();
+                newCurPage.shrinkWidget(true);
             }
         }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
index ab8a759..8ee9b61 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
@@ -375,10 +375,6 @@
         return mSmallFrameHeight;
     }
 
-    public void shrinkWidget() {
-        shrinkWidget(true);
-    }
-
     public void setWidgetLockedSmall(boolean locked) {
         if (locked) {
             setWidgetHeight(mSmallWidgetHeight);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
index 704af6e..99f7757 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
@@ -194,7 +194,9 @@
 
     @Override
     public void onPageEndWarp() {
-        hideOutlinesAndSidePages();
+        // if we're moving to the warp page, then immediately hide the other widgets.
+        int duration = getPageWarpIndex() == getNextPage() ? 0 : -1;
+        animateOutlinesAndSidePages(false, duration);
         mViewStateManager.onPageEndWarp();
     }
 
@@ -669,7 +671,7 @@
                 // On the very first measure pass, if the challenge is showing, we need to make sure
                 // that the widget on the current page is small.
                 if (challengeShowing && i == mCurrentPage && !mHasMeasure) {
-                    frame.shrinkWidget();
+                    frame.shrinkWidget(true);
                 }
             }
         }
diff --git a/packages/Keyguard/src/com/android/keyguard/PagedView.java b/packages/Keyguard/src/com/android/keyguard/PagedView.java
index 5df5d07..b9404d4 100644
--- a/packages/Keyguard/src/com/android/keyguard/PagedView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PagedView.java
@@ -2725,7 +2725,7 @@
     };
 
     private void cancelWarpAnimation(String msg, boolean abortAnimation) {
-        if (DEBUG_WARP) Log.v(TAG, "cancelWarpAnimation(" + msg + ")");
+        if (DEBUG_WARP) Log.v(TAG, "cancelWarpAnimation(" + msg + ",abort=" + abortAnimation + ")");
         if (abortAnimation) {
             // We're done with the animation and moving to a new page.  Let the scroller
             // take over the animation.
diff --git a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
index e14f89a..8511de2 100644
--- a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
+++ b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
@@ -24,6 +24,9 @@
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
 import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
@@ -53,7 +56,8 @@
     private SimpleBitmapRegionDecoderWrapper(BitmapRegionDecoder decoder) {
         mDecoder = decoder;
     }
-    public static SimpleBitmapRegionDecoderWrapper newInstance(String pathName, boolean isShareable) {
+    public static SimpleBitmapRegionDecoderWrapper newInstance(
+            String pathName, boolean isShareable) {
         try {
             BitmapRegionDecoder d = BitmapRegionDecoder.newInstance(pathName, isShareable);
             if (d != null) {
@@ -65,7 +69,8 @@
         }
         return null;
     }
-    public static SimpleBitmapRegionDecoderWrapper newInstance(InputStream is, boolean isShareable) {
+    public static SimpleBitmapRegionDecoderWrapper newInstance(
+            InputStream is, boolean isShareable) {
         try {
             BitmapRegionDecoder d = BitmapRegionDecoder.newInstance(is, isShareable);
             if (d != null) {
@@ -89,8 +94,9 @@
 }
 
 class DumbBitmapRegionDecoder implements SimpleBitmapRegionDecoder {
-    //byte[] streamCopy;
     Bitmap mBuffer;
+    Canvas mTempCanvas;
+    Paint mTempPaint;
     private DumbBitmapRegionDecoder(Bitmap b) {
         mBuffer = b;
     }
@@ -115,9 +121,23 @@
         return mBuffer.getHeight();
     }
     public Bitmap decodeRegion(Rect wantRegion, BitmapFactory.Options options) {
-        System.out.println("DECODING WITH SAMPLE LEVEL OF " + options.inSampleSize);
-        return Bitmap.createBitmap(
-                mBuffer, wantRegion.left, wantRegion.top, wantRegion.width(), wantRegion.height());
+        if (mTempCanvas == null) {
+            mTempCanvas = new Canvas();
+            mTempPaint = new Paint();
+            mTempPaint.setFilterBitmap(true);
+        }
+        int sampleSize = Math.max(options.inSampleSize, 1);
+        Bitmap newBitmap = Bitmap.createBitmap(
+                wantRegion.width() / sampleSize,
+                wantRegion.height() / sampleSize,
+                Bitmap.Config.ARGB_8888);
+        mTempCanvas.setBitmap(newBitmap);
+        mTempCanvas.save();
+        mTempCanvas.scale(1f / sampleSize, 1f / sampleSize);
+        mTempCanvas.drawBitmap(mBuffer, -wantRegion.left, -wantRegion.top, mTempPaint);
+        mTempCanvas.restore();
+        mTempCanvas.setBitmap(null);
+        return newBitmap;
     }
 }
 
@@ -256,6 +276,7 @@
                 if (regionDecoder == null) {
                     is = regenerateInputStream();
                     regionDecoder = DumbBitmapRegionDecoder.newInstance(is);
+                    Utils.closeSilently(is);
                 }
                 return regionDecoder;
             } catch (FileNotFoundException e) {
@@ -280,8 +301,9 @@
         }
         @Override
         public boolean readExif(ExifInterface ei) {
+            InputStream is = null;
             try {
-                InputStream is = regenerateInputStream();
+                is = regenerateInputStream();
                 ei.readExif(is);
                 Utils.closeSilently(is);
                 return true;
@@ -291,6 +313,8 @@
             } catch (IOException e) {
                 Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
                 return false;
+            } finally {
+                Utils.closeSilently(is);
             }
         }
     }
@@ -316,6 +340,7 @@
             if (regionDecoder == null) {
                 is = regenerateInputStream();
                 regionDecoder = DumbBitmapRegionDecoder.newInstance(is);
+                Utils.closeSilently(is);
             }
             return regionDecoder;
         }
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index d12140d..9201b71 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -247,19 +247,19 @@
     private static int getRotationFromExifHelper(
             String path, Resources res, int resId, Context context, Uri uri) {
         ExifInterface ei = new ExifInterface();
+        InputStream is = null;
+        BufferedInputStream bis = null;
         try {
             if (path != null) {
                 ei.readExif(path);
             } else if (uri != null) {
-                InputStream is = context.getContentResolver().openInputStream(uri);
-                BufferedInputStream bis = new BufferedInputStream(is);
+                is = context.getContentResolver().openInputStream(uri);
+                bis = new BufferedInputStream(is);
                 ei.readExif(bis);
-                bis.close();
             } else {
-                InputStream is = res.openRawResource(resId);
-                BufferedInputStream bis = new BufferedInputStream(is);
+                is = res.openRawResource(resId);
+                bis = new BufferedInputStream(is);
                 ei.readExif(bis);
-                bis.close();
             }
             Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
             if (ori != null) {
@@ -267,6 +267,9 @@
             }
         } catch (IOException e) {
             Log.w(LOGTAG, "Getting exif data failed", e);
+        } finally {
+            Utils.closeSilently(bis);
+            Utils.closeSilently(is);
         }
         return 0;
     }
@@ -606,13 +609,13 @@
                 }
 
                 // See how much we're reducing the size of the image
-                int scaleDownSampleSize = Math.min(roundedTrueCrop.width() / mOutWidth,
-                        roundedTrueCrop.height() / mOutHeight);
-
+                int scaleDownSampleSize = Math.max(1, Math.min(roundedTrueCrop.width() / mOutWidth,
+                        roundedTrueCrop.height() / mOutHeight));
                 // Attempt to open a region decoder
                 BitmapRegionDecoder decoder = null;
+                InputStream is = null;
                 try {
-                    InputStream is = regenerateInputStream();
+                    is = regenerateInputStream();
                     if (is == null) {
                         Log.w(LOGTAG, "cannot get input stream for uri=" + mInUri.toString());
                         failure = true;
@@ -622,6 +625,9 @@
                     Utils.closeSilently(is);
                 } catch (IOException e) {
                     Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e);
+                } finally {
+                   Utils.closeSilently(is);
+                   is = null;
                 }
 
                 Bitmap crop = null;
@@ -637,7 +643,7 @@
 
                 if (crop == null) {
                     // BitmapRegionDecoder has failed, try to crop in-memory
-                    InputStream is = regenerateInputStream();
+                    is = regenerateInputStream();
                     Bitmap fullSize = null;
                     if (is != null) {
                         BitmapFactory.Options options = new BitmapFactory.Options();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0e0f156..bb14259 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1104,6 +1104,19 @@
     private static native void nativeInit();
 
     public static void main(String[] args) {
+
+        /*
+         * In case the runtime switched since last boot (such as when
+         * the old runtime was removed in an OTA), set the system
+         * property so that it is in sync. We can't do this in
+         * libnativehelper's JniInvocation::Init code where we already
+         * had to fallback to a different runtime because it is
+         * running as root and we need to be the system user to set
+         * the property. http://b/11463182
+         */
+        SystemProperties.set("persist.sys.dalvik.vm.lib",
+                             VMRuntime.getRuntime().vmLibrary());
+
         if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
             // If a device's clock is before 1970 (before 0), a lot of
             // APIs crash dealing with negative numbers, notably
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 6186b9e..d6360a8 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -76,7 +76,7 @@
 
     // How long a service needs to be running until restarting its process
     // is no longer considered to be a relaunch of the service.
-    static final int SERVICE_RESTART_DURATION = 5*1000;
+    static final int SERVICE_RESTART_DURATION = 1*1000;
 
     // How long a service needs to be running until it will start back at
     // SERVICE_RESTART_DURATION after being killed.
@@ -301,7 +301,7 @@
         ServiceRecord r = res.record;
         NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
                 callingUid, r.packageName, service, service.getFlags(), null);
-        if (unscheduleServiceRestartLocked(r)) {
+        if (unscheduleServiceRestartLocked(r, callingUid)) {
             if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
         }
         r.lastActivity = SystemClock.uptimeMillis();
@@ -695,7 +695,7 @@
         final long origId = Binder.clearCallingIdentity();
 
         try {
-            if (unscheduleServiceRestartLocked(s)) {
+            if (unscheduleServiceRestartLocked(s, callerApp.info.uid)) {
                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
                         + s);
             }
@@ -1141,16 +1141,9 @@
                     r.restartCount = 1;
                     r.restartDelay = minDuration;
                 } else {
-                    if ((r.serviceInfo.applicationInfo.flags
-                            &ApplicationInfo.FLAG_PERSISTENT) != 0) {
-                        // Services in peristent processes will restart much more
-                        // quickly, since they are pretty important.  (Think SystemUI).
-                        r.restartDelay += minDuration/2;
-                    } else {
-                        r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
-                        if (r.restartDelay < minDuration) {
-                            r.restartDelay = minDuration;
-                        }
+                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
+                    if (r.restartDelay < minDuration) {
+                        r.restartDelay = minDuration;
                     }
                 }
             }
@@ -1177,7 +1170,7 @@
             } while (repeat);
 
         } else {
-            // Persistent processes are immediately restrted, so there is no
+            // Persistent processes are immediately restarted, so there is no
             // reason to hold of on restarting their services.
             r.totalRestartCount++;
             r.restartCount = 0;
@@ -1210,12 +1203,17 @@
         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
     }
 
-    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
+    private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid) {
         if (r.restartDelay == 0) {
             return false;
         }
-        r.resetRestartCounter();
-        mRestartingServices.remove(r);
+        // Remove from the restarting list; if the service is currently on the
+        // restarting list, or the call is coming from another app, then this
+        // service has become of much more interest so we reset the restart interval.
+        boolean removed = mRestartingServices.remove(r);
+        if (removed || callingUid != r.appInfo.uid) {
+            r.resetRestartCounter();
+        }
         mAm.mHandler.removeCallbacks(r.restarter);
         return true;
     }
@@ -1549,7 +1547,7 @@
         smap.mServicesByName.remove(r.name);
         smap.mServicesByIntent.remove(r.intent);
         r.totalRestartCount = 0;
-        unscheduleServiceRestartLocked(r);
+        unscheduleServiceRestartLocked(r, 0);
 
         // Also make sure it is not on the pending list.
         int N = mPendingServices.size();