Fix issues #5233826 and #5209847 -- live wallpapers.

5233826	when a live wallpaper starts, it does so regardless of its visibility

The WallpaperService is now very forceful about telling a wallpaper it is
not visible when it first starts.

5209847	Make launcher turn off the wallpaper in all apps.

Fix a bug in the window manager that would not correctly handle the wallpaper
flag changing.

Change-Id: Ie3314043a84664be72a1304a1705408efd789a15
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 4c563ce..39f9367 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -139,6 +139,7 @@
         boolean mSurfaceCreated;
         boolean mIsCreating;
         boolean mDrawingAllowed;
+        boolean mOffsetsChanged;
         int mWidth;
         int mHeight;
         int mFormat;
@@ -604,12 +605,15 @@
                         if (DEBUG) Log.v(TAG, "Layout: Surface destroyed");
                         return;
                     }
-                    
+
+                    boolean didSurface = false;
+
                     try {
                         mSurfaceHolder.ungetCallbacks();
 
                         if (surfaceCreating) {
                             mIsCreating = true;
+                            didSurface = true;
                             if (DEBUG) Log.v(TAG, "onSurfaceCreated("
                                     + mSurfaceHolder + "): " + this);
                             onSurfaceCreated(mSurfaceHolder);
@@ -637,6 +641,7 @@
                                     + mSurfaceHolder + ", " + mFormat
                                     + ", " + mCurWidth + ", " + mCurHeight
                                     + "): " + this);
+                            didSurface = true;
                             onSurfaceChanged(mSurfaceHolder, mFormat,
                                     mCurWidth, mCurHeight);
                             SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
@@ -661,6 +666,26 @@
                             }
                         }
 
+                        if (didSurface && !mReportedVisible) {
+                            // This wallpaper is currently invisible, but its
+                            // surface has changed.  At this point let's tell it
+                            // again that it is invisible in case the report about
+                            // the surface caused it to start running.  We really
+                            // don't want wallpapers running when not visible.
+                            if (mIsCreating) {
+                                // Some wallpapers will ignore this call if they
+                                // had previously been told they were invisble,
+                                // so if we are creating a new surface then toggle
+                                // the state to get them to notice.
+                                if (DEBUG) Log.v(TAG, "onVisibilityChanged(true) at surface: "
+                                        + this);
+                                onVisibilityChanged(true);
+                            }
+                            if (DEBUG) Log.v(TAG, "onVisibilityChanged(false) at surface: "
+                                        + this);
+                            onVisibilityChanged(false);
+                        }
+
                     } finally {
                         mIsCreating = false;
                         mSurfaceCreated = true;
@@ -701,6 +726,7 @@
             onCreate(mSurfaceHolder);
             
             mInitializing = false;
+            mReportedVisible = false;
             updateSurface(false, false, false);
         }
         
@@ -711,7 +737,7 @@
                 mIWallpaperEngine.mReqWidth = desiredWidth;
                 mIWallpaperEngine.mReqHeight = desiredHeight;
                 onDesiredSizeChanged(desiredWidth, desiredHeight);
-                doOffsetsChanged();
+                doOffsetsChanged(true);
             }
         }
         
@@ -733,6 +759,7 @@
                         // If becoming visible, in preview mode the surface
                         // may have been destroyed so now we need to make
                         // sure it is re-created.
+                        doOffsetsChanged(false);
                         updateSurface(false, false, false);
                     }
                     onVisibilityChanged(visible);
@@ -740,11 +767,15 @@
             }
         }
         
-        void doOffsetsChanged() {
+        void doOffsetsChanged(boolean always) {
             if (mDestroyed) {
                 return;
             }
-            
+
+            if (!always && !mOffsetsChanged) {
+                return;
+            }
+
             float xOffset;
             float yOffset;
             float xOffsetStep;
@@ -759,15 +790,19 @@
                 mPendingSync = false;
                 mOffsetMessageEnqueued = false;
             }
-            
+
             if (mSurfaceCreated) {
-                if (DEBUG) Log.v(TAG, "Offsets change in " + this
-                        + ": " + xOffset + "," + yOffset);
-                final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
-                final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
-                final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
-                final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
-                onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
+                if (mReportedVisible) {
+                    if (DEBUG) Log.v(TAG, "Offsets change in " + this
+                            + ": " + xOffset + "," + yOffset);
+                    final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
+                    final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
+                    final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
+                    final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
+                    onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
+                } else {
+                    mOffsetsChanged = true;
+                }
             }
             
             if (sync) {
@@ -953,7 +988,7 @@
                     mEngine.doVisibilityChanged(message.arg1 != 0);
                     break;
                 case MSG_WALLPAPER_OFFSETS: {
-                    mEngine.doOffsetsChanged();
+                    mEngine.doOffsetsChanged(true);
                 } break;
                 case MSG_WALLPAPER_COMMAND: {
                     WallpaperCommand cmd = (WallpaperCommand)message.obj;
@@ -962,7 +997,7 @@
                 case MSG_WINDOW_RESIZED: {
                     final boolean reportDraw = message.arg1 != 0;
                     mEngine.updateSurface(true, false, reportDraw);
-                    mEngine.doOffsetsChanged();
+                    mEngine.doOffsetsChanged(true);
                 } break;
                 case MSG_TOUCH_EVENT: {
                     boolean skip = false;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 192d32b..1a4caa7 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -2533,6 +2533,7 @@
 
             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
                     && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
+            wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
 
             win.mRelayoutCalled = true;
             final int oldVisibility = win.mViewVisibility;
@@ -7925,11 +7926,26 @@
                 }
 
                 if (windowAnimationBackgroundColor != 0) {
+                    // If this window that wants black is the current wallpaper
+                    // target, then the black goes *below* the wallpaper so we
+                    // don't cause the wallpaper to suddenly disappear.
+                    WindowState target = windowAnimationBackground;
+                    if (mWallpaperTarget == windowAnimationBackground
+                            || mLowerWallpaperTarget == windowAnimationBackground
+                            || mUpperWallpaperTarget == windowAnimationBackground) {
+                        for (i=0; i<mWindows.size(); i++) {
+                            WindowState w = mWindows.get(i);
+                            if (w.mIsWallpaper) {
+                                target = w;
+                                break;
+                            }
+                        }
+                    }
                     if (mWindowAnimationBackgroundSurface == null) {
                         mWindowAnimationBackgroundSurface = new DimSurface(mFxSession);
                     }
                     mWindowAnimationBackgroundSurface.show(dw, dh,
-                            windowAnimationBackground.mAnimLayer - LAYER_OFFSET_DIM,
+                            target.mAnimLayer - LAYER_OFFSET_DIM,
                             windowAnimationBackgroundColor);
                 } else if (mWindowAnimationBackgroundSurface != null) {
                     mWindowAnimationBackgroundSurface.hide();