Merge "Count failed install as finished" into nyc-mr1-dev
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9f02050..3d3dc9c 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -714,7 +714,7 @@
         public static final int N = 24;
 
         /**
-         * N MR1: Still ¯\_(シ)_/¯.
+         * N MR1: Nougat++.
          */
         public static final int N_MR1 = 25;
     }
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index 0c8cc9b..f0c4e59 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -42,7 +42,6 @@
             android:singleLine="true"
             android:ellipsize="start"
             android:inputType="textShortMessage|textAutoCorrect|textCapSentences"
-            android:textIsSelectable="true"
             android:imeOptions="actionNone|flagNoExtractUi" />
 
     <FrameLayout
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 65d6805..15ae4ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -126,8 +126,8 @@
                 ? R.drawable.ic_qs_branded_vpn
                 : R.drawable.ic_qs_vpn);
             if (mFooterIconId != footerIconId) {
-                mFooterIcon.setImageResource(footerIconId);
                 mFooterIconId = footerIconId;
+                mMainHandler.post(mUpdateIcon);
             }
             mIsVisible = mIsIconVisible;
         }
@@ -207,6 +207,13 @@
         }
     }
 
+    private final Runnable mUpdateIcon = new Runnable() {
+        @Override
+        public void run() {
+            mFooterIcon.setImageResource(mFooterIconId);
+        }
+    };
+
     private final Runnable mUpdateDisplayState = new Runnable() {
         @Override
         public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index c575417..a1854fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -2517,8 +2517,7 @@
 
         boolean inUse = mPowerManager.isScreenOn()
                 && (!mStatusBarKeyguardViewManager.isShowing()
-                || mStatusBarKeyguardViewManager.isOccluded())
-                && !mStatusBarKeyguardViewManager.isInputRestricted();
+                || mStatusBarKeyguardViewManager.isOccluded());
         try {
             inUse = inUse && !mDreamManager.isDreaming();
         } catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index f72e50b..119d855 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -412,7 +412,10 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, mBackgroundPaint);
+        if (mCurrentBounds.top < mCurrentBounds.bottom) {
+            canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom,
+                    mBackgroundPaint);
+        }
         if (DEBUG) {
             int y = mTopPadding;
             canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
@@ -2013,11 +2016,12 @@
             bottom = top;
         }
         if (mPhoneStatusBar.getBarState() != StatusBarState.KEYGUARD) {
-            mBackgroundBounds.top = (int) Math.max(mTopPadding + mStackTranslation, top);
+            top = (int) Math.max(mTopPadding + mStackTranslation, top);
         } else {
             // otherwise the animation from the shade to the keyguard will jump as it's maxed
-            mBackgroundBounds.top = Math.max(0, top);
+            top = Math.max(0, top);
         }
+        mBackgroundBounds.top = top;
         mBackgroundBounds.bottom = Math.min(getHeight(), Math.max(bottom, top));
     }
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a9624cf..b065392 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -17,7 +17,9 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.StackId;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
@@ -338,6 +340,7 @@
     }
 
     void clearAnimatingFlags() {
+        boolean wallpaperMightChange = false;
         for (int i = allAppWindows.size() - 1; i >= 0; i--) {
             final WindowState win = allAppWindows.get(i);
             // We don't want to clear it out for windows that get replaced, because the
@@ -348,7 +351,6 @@
             // by the client. We should let animation proceed and not clear this flag or
             // they won't eventually be removed by WindowStateAnimator#finishExit.
             if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
-                win.mAnimatingExit = false;
                 // Clear mAnimating flag together with mAnimatingExit. When animation
                 // changes from exiting to entering, we need to clear this flag until the
                 // new animation gets applied, so that isAnimationStarting() becomes true
@@ -356,9 +358,24 @@
                 // Otherwise applySurfaceChangesTransaction will faill to skip surface
                 // placement for this window during this period, one or more frame will
                 // show up with wrong position or scale.
-                win.mWinAnimator.mAnimating = false;
+                if (win.mAnimatingExit) {
+                    win.mAnimatingExit = false;
+                    wallpaperMightChange = true;
+                }
+                if (win.mWinAnimator.mAnimating) {
+                    win.mWinAnimator.mAnimating = false;
+                    wallpaperMightChange = true;
+                }
+                if (win.mDestroying) {
+                    win.mDestroying = false;
+                    service.mDestroySurface.remove(win);
+                    wallpaperMightChange = true;
+                }
             }
         }
+        if (wallpaperMightChange) {
+            requestUpdateWallpaperIfNeeded();
+        }
     }
 
     void destroySurfaces() {
@@ -406,6 +423,9 @@
             if (displayContent != null && !displayList.contains(displayContent)) {
                 displayList.add(displayContent);
             }
+            if (cleanupOnResume) {
+                win.requestUpdateWallpaperIfNeeded();
+            }
             win.mDestroying = false;
         }
         for (int i = 0; i < displayList.size(); i++) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index a976b36..2b66c3a 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -586,27 +586,24 @@
                     if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
                             "New i: " + wallpaperTargetIndex + " old i: " + oldI);
                     if (oldI >= 0) {
-                        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                                "Animating wallpapers: old#" + oldI + "=" + oldW + "; new#"
-                                + wallpaperTargetIndex + "=" + wallpaperTarget);
+                        final boolean newTargetHidden =
+                                wallpaperTarget.mAppToken != null && wallpaperTarget.mAppToken.hiddenRequested;
+                        final boolean oldTargetHidden =
+                                oldW.mAppToken != null && oldW.mAppToken.hiddenRequested;
+                        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:"
+                                + " old#" + oldI + "=" + oldW + " hidden=" + oldTargetHidden
+                                + " new#" + wallpaperTargetIndex + "=" + wallpaperTarget
+                                + " hidden=" + newTargetHidden);
 
-                        // Set the new target correctly.
-                        if (wallpaperTarget.mAppToken != null
-                                && wallpaperTarget.mAppToken.hiddenRequested) {
-                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                                    "Old wallpaper still the target.");
-                            mWallpaperTarget = oldW;
-                            wallpaperTarget = oldW;
-                            wallpaperTargetIndex = oldI;
-                        }
-                        // Now set the upper and lower wallpaper targets correctly,
+                        // Set the upper and lower wallpaper targets correctly,
                         // and make sure that we are positioning the wallpaper below the lower.
-                        else if (wallpaperTargetIndex > oldI) {
+                        if (wallpaperTargetIndex > oldI) {
                             // The new target is on top of the old one.
                             if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
                                     "Found target above old target.");
                             mUpperWallpaperTarget = wallpaperTarget;
                             mLowerWallpaperTarget = oldW;
+
                             wallpaperTarget = oldW;
                             wallpaperTargetIndex = oldI;
                         } else {
@@ -616,6 +613,22 @@
                             mUpperWallpaperTarget = oldW;
                             mLowerWallpaperTarget = wallpaperTarget;
                         }
+                        if (newTargetHidden && !oldTargetHidden) {
+                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                                    "Old wallpaper still the target.");
+                            // Use the old target if new target is hidden but old target
+                            // is not. If they're both hidden, still use the new target.
+                            mWallpaperTarget = oldW;
+                        } else if (newTargetHidden == oldTargetHidden
+                                && !mService.mOpeningApps.contains(wallpaperTarget.mAppToken)
+                                    && (mService.mOpeningApps.contains(oldW.mAppToken)
+                                    || mService.mClosingApps.contains(oldW.mAppToken))) {
+                            // If they're both hidden (or both not hidden), prefer the one that's
+                            // currently in opening or closing app list, this allows transition
+                            // selection logic to better determine the wallpaper status of
+                            // opening/closing apps.
+                            mWallpaperTarget = oldW;
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a00ac5d..81545b6 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1334,7 +1334,8 @@
                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
                         || mWinAnimator.mAnimation != null
                         || ((atoken != null) && (atoken.mAppAnimator.animation != null)
-                                && !mWinAnimator.isDummyAnimation()));
+                                && !mWinAnimator.isDummyAnimation())
+                        || isAnimatingWithSavedSurface());
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index eacf44e..fa5e3ca 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1097,6 +1097,26 @@
         boolean fullscreenAnim = false;
         boolean voiceInteraction = false;
 
+        int i;
+        for (i = 0; i < appsCount; i++) {
+            final AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
+            // Clearing the mAnimatingExit flag before entering animation. It's set to
+            // true if app window is removed, or window relayout to invisible.
+            // This also affects window visibility. We need to clear it *before*
+            // maybeUpdateTransitToWallpaper() as the transition selection depends on
+            // wallpaper target visibility.
+            wtoken.clearAnimatingFlags();
+
+        }
+        // Adjust wallpaper before we pull the lower/upper target, since pending changes
+        // (like the clearAnimatingFlags() above) might affect wallpaper target result.
+        final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
+        if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
+                mWallpaperControllerLocked.adjustWallpaperWindows()) {
+            mService.mLayersController.assignLayersLocked(windows);
+            displayContent.layoutNeeded = true;
+        }
+
         final WindowState lowerWallpaperTarget =
                 mWallpaperControllerLocked.getLowerWallpaperTarget();
         final WindowState upperWallpaperTarget =
@@ -1113,7 +1133,6 @@
             upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
         }
 
-        int i;
         // Do a first pass through the tokens for two
         // things:
         // (1) Determine if both the closing and opening
@@ -1138,12 +1157,6 @@
                 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
                     openingAppHasWallpaper = true;
                 }
-                // Clearing the mAnimatingExit flag before entering animation. It's set to
-                // true if app window is removed, or window relayout to invisible.
-                // This also affects window visibility. We need to clear it *before*
-                // maybeUpdateTransitToWallpaper() as the transition selection depends on
-                // wallpaper target visibility.
-                wtoken.clearAnimatingFlags();
             }
 
             voiceInteraction |= wtoken.voiceInteraction;
@@ -1206,7 +1219,7 @@
 
         // This has changed the visibility of windows, so perform
         // a new layout to get them all up-to-date.
-        mService.getDefaultDisplayContentLocked().layoutNeeded = true;
+        displayContent.layoutNeeded = true;
 
         // TODO(multidisplay): IMEs are only supported on the default display.
         if (windows == mService.getDefaultWindowListLocked()
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 306b3c1..c4739ff 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -224,6 +224,7 @@
 
             conference.setState(parcel.getState());
             conference.setConnectionCapabilities(parcel.getConnectionCapabilities());
+            conference.setConnectionProperties(parcel.getConnectionProperties());
             mConferenceById.put(callId, conference);
             conference.registerCallback(new RemoteConference.Callback() {
                 @Override
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index a7878d1..5f91f17 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1033,7 +1033,6 @@
         return NO_ERROR;
     }
 
-    ResXMLTree tree;
     Asset* asset = assets.openNonAsset(cookie, "AndroidManifest.xml", Asset::ACCESS_STREAMING);
     if (asset == NULL) {
         fprintf(stderr, "ERROR: Platform AndroidManifest.xml not found\n");
@@ -1041,11 +1040,17 @@
     }
 
     ssize_t result = NO_ERROR;
-    if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) {
-        fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n");
-        result = UNKNOWN_ERROR;
-    } else {
-        result = extractPlatformBuildVersion(tree, bundle);
+
+    // Create a new scope so that ResXMLTree is destroyed before we delete the memory over
+    // which it iterates (asset).
+    {
+        ResXMLTree tree;
+        if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) {
+            fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n");
+            result = UNKNOWN_ERROR;
+        } else {
+            result = extractPlatformBuildVersion(tree, bundle);
+        }
     }
 
     delete asset;