Merge "Rename android.hardware.Usb to UsbManager and UsbObserver to UsbService"
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 0d6966f..2c8ca8b 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -1,5 +1,4 @@
-/* //device/java/android/android/view/IWindowManager.aidl
-**
+/*
 ** Copyright 2006, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -74,7 +73,7 @@
     void setAppOrientation(IApplicationToken token, int requestedOrientation);
     int getAppOrientation(IApplicationToken token);
     void setFocusedApp(IBinder token, boolean moveFocusNow);
-    void prepareAppTransition(int transit);
+    void prepareAppTransition(int transit, boolean alwaysKeepCurrent);
     int getPendingAppTransition();
     void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim);
     void executeAppTransition();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ad96686..da12d46 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6421,6 +6421,12 @@
             mPrivateFlags &= ~DRAWING_CACHE_VALID;
             final ViewParent p = mParent;
             final AttachInfo ai = mAttachInfo;
+            if (p != null && ai != null && ai.mHardwareAccelerated) {
+                // fast-track for GL-enabled applications; just invalidate the whole hierarchy
+                // with a null dirty rect, which tells the ViewRoot to redraw everything
+                p.invalidateChild(this, null);
+                return;
+            }
             if (p != null && ai != null) {
                 final int scrollX = mScrollX;
                 final int scrollY = mScrollY;
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e655192..af0e866 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -459,6 +459,16 @@
          device is data-only. -->
     <bool name="config_voice_capable">true</bool>
 
+    <!-- Flag indicating whether the current device allows sms service.
+         If true, this means that the device supports both sending and
+         receiving sms via the telephony network.
+         This can be overridden to false for "data only" devices
+         which can't send and receive sms message.
+
+         Note: Disable SMS also disable voicemail waiting sms,
+               cell broadcasting sms, and MMS. -->
+    <bool name="config_sms_capable">true</bool>
+
     <!-- IP address of the dns server to use if nobody else suggests one -->
     <string name="config_default_dns_server">8.8.8.8</string>
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b357973..8bfc8d4 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -268,7 +268,7 @@
     const GLuint previousFbo = mSnapshot->fbo;
     const int count = saveSnapshot(flags);
 
-    if (!mSnapshot->invisible) {
+    if (!mSnapshot->isIgnored()) {
         int alpha = 255;
         SkXfermode::Mode mode;
 
@@ -385,13 +385,17 @@
 
     if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize ||
             bounds.getHeight() > mCaches.maxTextureSize) {
-        snapshot->invisible = true;
+        if (fboLayer) {
+            snapshot->invisible = true;
+        } else {
+            snapshot->empty = true;
+        }
     } else {
         snapshot->invisible = snapshot->invisible || (alpha <= ALPHA_THRESHOLD && fboLayer);
     }
 
     // Bail out if we won't draw in this snapshot
-    if (snapshot->invisible) {
+    if (snapshot->invisible || snapshot->empty) {
         return false;
     }
 
@@ -731,7 +735,7 @@
 }
 
 void OpenGLRenderer::clearLayerRegions() {
-    if (mLayers.size() == 0 || mSnapshot->invisible) return;
+    if (mLayers.size() == 0 || mSnapshot->isIgnored()) return;
 
     Rect clipRect(*mSnapshot->clipRect);
     clipRect.snapToPixelBoundaries();
@@ -809,7 +813,7 @@
 }
 
 bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
-    if (mSnapshot->invisible) {
+    if (mSnapshot->isIgnored()) {
         return true;
     }
 
@@ -988,7 +992,7 @@
 
 void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
     // TODO: Should do quickReject for each line
-    if (mSnapshot->invisible) return;
+    if (mSnapshot->isIgnored()) return;
 
     const bool isAA = paint->isAntiAlias();
     const float strokeWidth = paint->getStrokeWidth() * 0.5f;
@@ -1112,7 +1116,7 @@
 
 void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
     // No need to check against the clip, we fill the clip region
-    if (mSnapshot->invisible) return;
+    if (mSnapshot->isIgnored()) return;
 
     Rect& clip(*mSnapshot->clipRect);
     clip.snapToPixelBoundaries();
@@ -1150,7 +1154,7 @@
     if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
         return;
     }
-    if (mSnapshot->invisible) return;
+    if (mSnapshot->isIgnored()) return;
 
     paint->setAntiAlias(true);
 
@@ -1253,7 +1257,7 @@
 }
 
 void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
-    if (mSnapshot->invisible) return;
+    if (mSnapshot->isIgnored()) return;
 
     GLuint textureUnit = 0;
     glActiveTexture(gTextureUnits[textureUnit]);
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 9f78063..9898df4 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -43,7 +43,7 @@
  */
 class Snapshot: public LightRefBase<Snapshot> {
 public:
-    Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false) {
+    Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false), empty(false) {
         transform = &mTransformRoot;
         clipRect = &mClipRectRoot;
         region = NULL;
@@ -55,7 +55,7 @@
      */
     Snapshot(const sp<Snapshot>& s, int saveFlags):
             flags(0), previous(s), layer(NULL), fbo(s->fbo),
-            invisible(s->invisible), viewport(s->viewport), height(s->height) {
+            invisible(s->invisible), empty(false), viewport(s->viewport), height(s->height) {
         if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
             mTransformRoot.load(*s->transform);
             transform = &mTransformRoot;
@@ -203,6 +203,10 @@
         flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
     }
 
+    bool isIgnored() const {
+        return invisible || empty;
+    }
+
     /**
      * Dirty flags.
      */
@@ -225,11 +229,18 @@
 
     /**
      * Indicates that this snapshot is invisible and nothing should be drawn
-     * inside it.
+     * inside it. This flag is set only when the layer clips drawing to its
+     * bounds and is passed to subsequent snapshots.
      */
     bool invisible;
 
     /**
+     * If set to true, the layer will not be composited. This is similar to
+     * invisible but this flag is not passed to subsequent snapshots.
+     */
+    bool empty;
+
+    /**
      * Current viewport.
      */
     Rect viewport;
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 1f6a920..ed0cb8e 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -908,9 +908,11 @@
             ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
             if (connectionIndex >= 0) {
                 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-                synthesizeCancelationEventsForConnectionLocked(
-                        connection, InputState::CANCEL_ALL_EVENTS,
-                        "application not responding");
+                if (connection->status == Connection::STATUS_NORMAL) {
+                    synthesizeCancelationEventsForConnectionLocked(
+                            connection, InputState::CANCEL_ALL_EVENTS,
+                            "application not responding");
+                }
             }
         }
     }
@@ -3056,7 +3058,7 @@
                     // the original UP in which case we would not generate the fallback UP.
                     synthesizeCancelationEventsForConnectionLocked(connection,
                             InputState::CANCEL_FALLBACK_EVENTS,
-                            "Application handled a non-fallback event.");
+                            "application handled a non-fallback event, canceling all fallback events");
                 } else {
                     // If the application did not handle a non-fallback key, then ask
                     // the policy what to do with it.  We might generate a fallback key
@@ -3071,6 +3073,12 @@
 
                     mLock.lock();
 
+                    if (connection->status != Connection::STATUS_NORMAL) {
+                        return;
+                    }
+
+                    assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
+
                     if (fallback) {
                         // Restart the dispatch cycle using the fallback key.
                         keyEntry->eventTime = event.getEventTime();
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index f72d919..576b009 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1164,7 +1164,7 @@
         // set appropriate level for the software AVCEncoder.
         if ((width * height >= 921600) // 720p
                 || (videoBitRate >= 20000000)) {
-            enc_meta->setInt32(kKeyVideoLevel, 50);
+            enc_meta->setInt32(kKeyVideoLevel, OMX_VIDEO_AVCLevel5);
         }
     }
 
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index ed9e865..371c21f 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -592,6 +592,11 @@
                 mLastFrameTimestampUs - mFirstFrameTimeUs);
     }
 
+    if (mNumGlitches > 0) {
+        LOGW("%d long delays between neighboring video frames during",
+                mNumGlitches);
+    }
+
     CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
     return OK;
 }
@@ -712,7 +717,7 @@
     if (mNumFramesReceived > 0 &&
         timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
         if (mNumGlitches % 10 == 0) {  // Don't spam the log
-            LOGW("Long delay detected in video recording");
+            LOGV("Long delay detected in video recording");
         }
         ++mNumGlitches;
     }
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 6fd1825..0b158be 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -72,7 +72,7 @@
       mLastTimeLapseFrameRealTimestampUs(0),
       mSkipCurrentFrame(false) {
 
-    LOGV("starting time lapse mode");
+    LOGD("starting time lapse mode: %lld us", mTimeBetweenTimeLapseFrameCaptureUs);
     mVideoWidth = videoSize.width;
     mVideoHeight = videoSize.height;
 
@@ -116,9 +116,9 @@
 }
 
 bool CameraSourceTimeLapse::trySettingPreviewSize(int32_t width, int32_t height) {
+    LOGV("trySettingPreviewSize: %dx%d", width, height);
     int64_t token = IPCThreadState::self()->clearCallingIdentity();
     String8 s = mCamera->getParameters();
-    IPCThreadState::self()->restoreCallingIdentity(token);
 
     CameraParameters params(s);
     Vector<Size> supportedSizes;
@@ -134,17 +134,24 @@
         }
     }
 
+    bool isSuccessful = false;
     if (previewSizeSupported) {
         LOGV("Video size (%d, %d) is a supported preview size", width, height);
         params.setPreviewSize(width, height);
-        CHECK(mCamera->setParameters(params.flatten()));
-        return true;
+        if (mCamera->setParameters(params.flatten()) == OK) {
+            isSuccessful = true;
+        } else {
+            LOGE("Failed to set preview size to %dx%d", width, height);
+            isSuccessful = false;
+        }
     }
 
-    return false;
+    IPCThreadState::self()->restoreCallingIdentity(token);
+    return isSuccessful;
 }
 
 bool CameraSourceTimeLapse::setPictureSizeToClosestSupported(int32_t width, int32_t height) {
+    LOGV("setPictureSizeToClosestSupported: %dx%d", width, height);
     int64_t token = IPCThreadState::self()->clearCallingIdentity();
     String8 s = mCamera->getParameters();
     IPCThreadState::self()->restoreCallingIdentity(token);
@@ -277,7 +284,6 @@
 
         int64_t token = IPCThreadState::self()->clearCallingIdentity();
         String8 s = mCamera->getParameters();
-        IPCThreadState::self()->restoreCallingIdentity(token);
 
         CameraParameters params(s);
         params.setPictureSize(mPictureWidth, mPictureHeight);
@@ -288,6 +294,7 @@
         // disable shutter sound and play the recording sound.
         mCamera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, 0, 0);
         mCamera->sendCommand(CAMERA_CMD_PLAY_RECORDING_SOUND, 0, 0);
+        IPCThreadState::self()->restoreCallingIdentity(token);
 
         // create a thread which takes pictures in a loop
         pthread_attr_t attr;
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 8ad39dc..e058a5a 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -49,7 +49,8 @@
         mDeviceInfo(NULL),
         mID(usb_device_get_unique_id(device)),
         mSessionID(0),
-        mTransactionID(0)
+        mTransactionID(0),
+        mReceivedResponse(false)
 {
 }
 
@@ -513,6 +514,7 @@
 
 bool MtpDevice::sendRequest(MtpOperationCode operation) {
     LOGV("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation));
+    mReceivedResponse = false;
     mRequest.setOperationCode(operation);
     if (mTransactionID > 0)
         mRequest.setTransactionID(mTransactionID++);
@@ -535,6 +537,14 @@
     int ret = mData.read(mEndpointIn);
     LOGV("readData returned %d\n", ret);
     if (ret >= MTP_CONTAINER_HEADER_SIZE) {
+        if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
+            LOGD("got response packet instead of data packet");
+            // we got a response packet rather than data
+            // copy it to mResponse
+            mResponse.copyFrom(mData);
+            mReceivedResponse = true;
+            return false;
+        }
         mData.dump();
         return true;
     }
@@ -552,12 +562,15 @@
 
 MtpResponseCode MtpDevice::readResponse() {
     LOGV("readResponse\n");
+    if (mReceivedResponse) {
+        mReceivedResponse = false;
+        return mResponse.getResponseCode();
+    }
     int ret = mResponse.read(mEndpointIn);
     if (ret >= MTP_CONTAINER_HEADER_SIZE) {
         mResponse.dump();
         return mResponse.getResponseCode();
-    }
-    else {
+    } else {
         LOGD("readResponse failed\n");
         return -1;
     }
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 6ffbd24..67bb85f 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -53,6 +53,8 @@
     MtpRequestPacket        mRequest;
     MtpDataPacket           mData;
     MtpResponsePacket       mResponse;
+    // set to true if we received a response packet instead of a data packet
+    bool                    mReceivedResponse;
 
     // to ensure only one MTP transaction at a time
     Mutex                   mMutex;
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index bd6196f..a885249 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -84,6 +84,13 @@
     LOGV("\n");
 }
 
+void MtpPacket::copyFrom(const MtpPacket& src) {
+    int length = src.mPacketSize;
+    allocate(length);
+    mPacketSize = length;
+    memcpy(mBuffer, src.mBuffer, length);
+}
+
 uint16_t MtpPacket::getUInt16(int offset) const {
     return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
 }
@@ -113,6 +120,10 @@
     putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
 }
 
+uint16_t MtpPacket::getContainerType() const {
+    return getUInt16(MTP_CONTAINER_TYPE_OFFSET);
+}
+
 MtpTransactionID MtpPacket::getTransactionID() const {
     return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET);
 }
diff --git a/media/mtp/MtpPacket.h b/media/mtp/MtpPacket.h
index 9c8d6da..73963a3 100644
--- a/media/mtp/MtpPacket.h
+++ b/media/mtp/MtpPacket.h
@@ -43,10 +43,13 @@
 
     void                allocate(int length);
     void                dump();
+    void                copyFrom(const MtpPacket& src);
 
     uint16_t            getContainerCode() const;
     void                setContainerCode(uint16_t code);
 
+    uint16_t            getContainerType() const;
+
     MtpTransactionID    getTransactionID() const;
     void                setTransactionID(MtpTransactionID id);
 
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 78bc263..8e33011 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -327,18 +327,6 @@
     final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
 
     /**
-     * This was the app token that was used to retrieve the last enter
-     * animation.  It will be used for the next exit animation.
-     */
-    AppWindowToken mLastEnterAnimToken;
-
-    /**
-     * These were the layout params used to retrieve the last enter animation.
-     * They will be used for the next exit animation.
-     */
-    LayoutParams mLastEnterAnimParams;
-
-    /**
      * Z-ordered (bottom-most first) list of all Window objects.
      */
     final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
@@ -3663,7 +3651,7 @@
         }
     }
 
-    public void prepareAppTransition(int transit) {
+    public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "prepareAppTransition()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3677,14 +3665,16 @@
                 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
                         || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
                     mNextAppTransition = transit;
-                } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
-                        && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
-                    // Opening a new task always supersedes a close for the anim.
-                    mNextAppTransition = transit;
-                } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
-                        && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
-                    // Opening a new activity always supersedes a close for the anim.
-                    mNextAppTransition = transit;
+                } else if (!alwaysKeepCurrent) {
+                    if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
+                            && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
+                        // Opening a new task always supersedes a close for the anim.
+                        mNextAppTransition = transit;
+                    } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
+                            && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
+                        // Opening a new activity always supersedes a close for the anim.
+                        mNextAppTransition = transit;
+                    }
                 }
                 mAppTransitionReady = false;
                 mAppTransitionTimeout = false;
@@ -4237,10 +4227,6 @@
                     wtoken.animating = false;
                 }
                 mAppTokens.remove(wtoken);
-                if (mLastEnterAnimToken == wtoken) {
-                    mLastEnterAnimToken = null;
-                    mLastEnterAnimParams = null;
-                }
                 wtoken.removed = true;
                 if (wtoken.startingData != null) {
                     startingToken = wtoken;
@@ -6713,6 +6699,7 @@
         int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
 
         // Current transformation being applied.
+        boolean mHaveMatrix;
         float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
         float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
         float mHScale=1, mVScale=1;
@@ -7598,6 +7585,7 @@
                 // since it is already included in the transformation.
                 //Slog.i(TAG, "Transform: " + matrix);
 
+                mHaveMatrix = true;
                 tmpMatrix.getValues(tmpFloats);
                 mDsDx = tmpFloats[Matrix.MSCALE_X];
                 mDtDx = tmpFloats[Matrix.MSKEW_Y];
@@ -7649,6 +7637,7 @@
                 mShownFrame.offset(mXOffset, mYOffset);
             }
             mShownAlpha = mAlpha;
+            mHaveMatrix = false;
             mDsDx = 1;
             mDtDx = 0;
             mDsDy = 0;
@@ -8064,11 +8053,6 @@
                     pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
                     pw.print(" last="); mLastVisibleInsets.printShortString(pw);
                     pw.println();
-            if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
-                pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
-                        pw.print(" mAlpha="); pw.print(mAlpha);
-                        pw.print(" mLastAlpha="); pw.println(mLastAlpha);
-            }
             if (mAnimating || mLocalAnimating || mAnimationIsEntrance
                     || mAnimation != null) {
                 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
@@ -8083,6 +8067,17 @@
                         pw.print(" "); mTransformation.printShortString(pw);
                         pw.println();
             }
+            if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
+                pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
+                        pw.print(" mAlpha="); pw.print(mAlpha);
+                        pw.print(" mLastAlpha="); pw.println(mLastAlpha);
+            }
+            if (mHaveMatrix) {
+                pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
+                        pw.print(" mDtDx="); pw.print(mDtDx);
+                        pw.print(" mDsDy="); pw.print(mDsDy);
+                        pw.print(" mDtDy="); pw.println(mDtDy);
+            }
             pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
                     pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
                     pw.print(" mReadyToShow="); pw.print(mReadyToShow);
@@ -8543,14 +8538,14 @@
                 pw.print(prefix); pw.print("animating="); pw.print(animating);
                         pw.print(" animation="); pw.println(animation);
             }
+            if (hasTransformation) {
+                pw.print(prefix); pw.print("XForm: ");
+                        transformation.printShortString(pw);
+                        pw.println();
+            }
             if (animLayerAdjustment != 0) {
                 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
             }
-            if (hasTransformation) {
-                pw.print(prefix); pw.print("hasTransformation="); pw.print(hasTransformation);
-                        pw.print(" transformation="); transformation.printShortString(pw);
-                        pw.println();
-            }
             if (startingData != null || removed || firstWindowDrawn) {
                 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
                         pw.print(" removed="); pw.print(removed);
@@ -9854,15 +9849,6 @@
                                     "New transit into wallpaper: " + transit);
                         }
 
-                        if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
-                            mLastEnterAnimToken = animToken;
-                            mLastEnterAnimParams = animLp;
-                        } else if (mLastEnterAnimParams != null) {
-                            animLp = mLastEnterAnimParams;
-                            mLastEnterAnimToken = null;
-                            mLastEnterAnimParams = null;
-                        }
-
                         // If all closing windows are obscured, then there is
                         // no need to do an animation.  This is the case, for
                         // example, when this transition is being done behind
@@ -10585,10 +10571,6 @@
                 token.animating = false;
                 mAppTokens.remove(token);
                 mExitingAppTokens.remove(i);
-                if (mLastEnterAnimToken == token) {
-                    mLastEnterAnimToken = null;
-                    mLastEnterAnimParams = null;
-                }
             }
         }
 
@@ -11409,10 +11391,6 @@
             }
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
                     pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
-            if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
-                pw.print("  mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
-                        pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
-            }
             if (mOpeningApps.size() > 0) {
                 pw.print("  mOpeningApps="); pw.println(mOpeningApps);
             }
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index aa4cd66..e77ec20 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1195,11 +1195,12 @@
                 if (DEBUG_TRANSITION) Slog.v(TAG,
                         "Prepare close transition: prev=" + prev);
                 if (mNoAnimActivities.contains(prev)) {
-                    mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+                    mService.mWindowManager.prepareAppTransition(
+                            WindowManagerPolicy.TRANSIT_NONE, false);
                 } else {
                     mService.mWindowManager.prepareAppTransition(prev.task == next.task
                             ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
-                            : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
+                            : WindowManagerPolicy.TRANSIT_TASK_CLOSE, false);
                 }
                 mService.mWindowManager.setAppWillBeHidden(prev);
                 mService.mWindowManager.setAppVisibility(prev, false);
@@ -1207,11 +1208,12 @@
                 if (DEBUG_TRANSITION) Slog.v(TAG,
                         "Prepare open transition: prev=" + prev);
                 if (mNoAnimActivities.contains(next)) {
-                    mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+                    mService.mWindowManager.prepareAppTransition(
+                            WindowManagerPolicy.TRANSIT_NONE, false);
                 } else {
                     mService.mWindowManager.prepareAppTransition(prev.task == next.task
                             ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
-                            : WindowManagerPolicy.TRANSIT_TASK_OPEN);
+                            : WindowManagerPolicy.TRANSIT_TASK_OPEN, false);
                 }
             }
             if (false) {
@@ -1222,9 +1224,11 @@
             if (DEBUG_TRANSITION) Slog.v(TAG,
                     "Prepare open transition: no previous");
             if (mNoAnimActivities.contains(next)) {
-                mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+                mService.mWindowManager.prepareAppTransition(
+                        WindowManagerPolicy.TRANSIT_NONE, false);
             } else {
-                mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+                mService.mWindowManager.prepareAppTransition(
+                        WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, false);
             }
         }
 
@@ -1368,7 +1372,7 @@
     }
 
     private final void startActivityLocked(ActivityRecord r, boolean newTask,
-            boolean doResume) {
+            boolean doResume, boolean keepCurTransition) {
         final int NH = mHistory.size();
 
         int addPos = -1;
@@ -1439,16 +1443,17 @@
             if (DEBUG_TRANSITION) Slog.v(TAG,
                     "Prepare open transition: starting " + r);
             if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-                mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+                mService.mWindowManager.prepareAppTransition(
+                        WindowManagerPolicy.TRANSIT_NONE, keepCurTransition);
                 mNoAnimActivities.add(r);
             } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
                 mService.mWindowManager.prepareAppTransition(
-                        WindowManagerPolicy.TRANSIT_TASK_OPEN);
+                        WindowManagerPolicy.TRANSIT_TASK_OPEN, keepCurTransition);
                 mNoAnimActivities.remove(r);
             } else {
                 mService.mWindowManager.prepareAppTransition(newTask
                         ? WindowManagerPolicy.TRANSIT_TASK_OPEN
-                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
                 mNoAnimActivities.remove(r);
             }
             mService.mWindowManager.addAppToken(
@@ -2250,7 +2255,7 @@
                             (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
                             == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
                         // The caller has requested to completely replace any
-                        // exising task with its new activity.  Well that should
+                        // existing task with its new activity.  Well that should
                         // not be too hard...
                         reuseTask = taskTop.task;
                         performClearTaskLocked(taskTop.task.taskId);
@@ -2383,6 +2388,7 @@
         }
 
         boolean newTask = false;
+        boolean keepCurTransition = false;
 
         // Should this be considered a new task?
         if (r.resultTo == null && !addingToTask
@@ -2413,6 +2419,7 @@
                 // activity is already running.
                 ActivityRecord top = performClearTaskLocked(
                         sourceRecord.task.taskId, r, launchFlags);
+                keepCurTransition = true;
                 if (top != null) {
                     logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                     top.deliverNewIntentLocked(callingUid, r.intent);
@@ -2474,7 +2481,7 @@
             EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
         }
         logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
-        startActivityLocked(r, newTask, doResume);
+        startActivityLocked(r, newTask, doResume, keepCurTransition);
         return START_SUCCESS;
     }
 
@@ -3128,7 +3135,7 @@
                     "Prepare close transition: finishing " + r);
             mService.mWindowManager.prepareAppTransition(endTask
                     ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
-                    : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
+                    : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE, false);
     
             // Tell window manager to prepare for this one to be removed.
             mService.mWindowManager.setAppVisibility(r, false);
@@ -3481,13 +3488,15 @@
                 "Prepare to front transition: task=" + tr);
         if (reason != null &&
                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-            mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+            mService.mWindowManager.prepareAppTransition(
+                    WindowManagerPolicy.TRANSIT_NONE, false);
             ActivityRecord r = topRunningActivityLocked(null);
             if (r != null) {
                 mNoAnimActivities.add(r);
             }
         } else {
-            mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
+            mService.mWindowManager.prepareAppTransition(
+                    WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, false);
         }
         
         mService.mWindowManager.moveAppTokensToTop(moved);
@@ -3566,13 +3575,15 @@
 
         if (reason != null &&
                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-            mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+            mService.mWindowManager.prepareAppTransition(
+                    WindowManagerPolicy.TRANSIT_NONE, false);
             ActivityRecord r = topRunningActivityLocked(null);
             if (r != null) {
                 mNoAnimActivities.add(r);
             }
         } else {
-            mService.mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
+            mService.mWindowManager.prepareAppTransition(
+                    WindowManagerPolicy.TRANSIT_TASK_TO_BACK, false);
         }
         mService.mWindowManager.moveAppTokensToBottom(moved);
         if (VALIDATE_TOKENS) {
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 710ff30..e0f0f05 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -144,7 +144,7 @@
         }
         
         try {
-            mWm.prepareAppTransition(0);
+            mWm.prepareAppTransition(0, false);
             fail("IWindowManager.prepareAppTransition did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {