More wallpaper fixes: scroll position, visibility, leaking.

This fixes a bunch of edge cases in updating the wallpaper's scroll position
and visibility when switching between wallpapers and traveling through the UI.

It also fixes some leaks of wallpaper tokens and windows.
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 6047742..e828681 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -392,6 +392,12 @@
                 }
             }
             mContext.unbindService(mWallpaperConnection);
+            try {
+                if (DEBUG) Log.v(TAG, "Removing window token: "
+                        + mWallpaperConnection.mToken);
+                mIWindowManager.removeWindowToken(mWallpaperConnection.mToken);
+            } catch (RemoteException e) {
+            }
             mWallpaperConnection = null;
         }
     }
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 988c3d5..a00a756 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1205,6 +1205,7 @@
             // The window is visible to the compositor...  but is it visible
             // to the user?  That is what the wallpaper cares about.
             visible = !w.mObscured;
+            if (DEBUG_WALLPAPER) Log.v(TAG, "Wallpaper visibility: " + visible);
             
             // If the wallpaper target is animating, we may need to copy
             // its layer adjustment.
@@ -1354,6 +1355,9 @@
         
         if (rawChanged) {
             try {
+                if (DEBUG_WALLPAPER) Log.v(TAG, "Report new wp offset "
+                        + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
+                        + " y=" + wallpaperWin.mWallpaperY);
                 wallpaperWin.mClient.dispatchWallpaperOffsets(
                         wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY);
             } catch (RemoteException e) {
@@ -1390,6 +1394,39 @@
         return changed;
     }
     
+    void updateWallpaperVisibilityLocked() {
+        final boolean visible = mWallpaperTarget != null
+                && !mWallpaperTarget.mObscured;
+        final int dw = mDisplay.getWidth();
+        final int dh = mDisplay.getHeight();
+        
+        int curTokenIndex = mWallpaperTokens.size();
+        while (curTokenIndex > 0) {
+            curTokenIndex--;
+            WindowToken token = mWallpaperTokens.get(curTokenIndex);
+            int curWallpaperIndex = token.windows.size();
+            while (curWallpaperIndex > 0) {
+                curWallpaperIndex--;
+                WindowState wallpaper = token.windows.get(curWallpaperIndex);
+                if (visible) {
+                    updateWallpaperOffsetLocked(mWallpaperTarget,
+                            wallpaper, dw, dh);                        
+                }
+                
+                if (wallpaper.mWallpaperVisible != visible) {
+                    wallpaper.mWallpaperVisible = visible;
+                    try {
+                        if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Log.v(TAG,
+                                "Setting visibility of wallpaper " + wallpaper
+                                + ": " + visible);
+                        wallpaper.mClient.dispatchAppVisibility(visible);
+                    } catch (RemoteException e) {
+                    }
+                }
+            }
+        }
+    }
+    
     void sendPointerToWallpaperLocked(WindowState srcWin,
             MotionEvent pointer, long eventTime) {
         int curTokenIndex = mWallpaperTokens.size();
@@ -1727,11 +1764,6 @@
             mInputMethodDialogs.remove(win);
         }
 
-        if (win.mAttrs.type == TYPE_WALLPAPER ||
-                (win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
-            adjustWallpaperWindowsLocked();
-        }
-        
         final WindowToken token = win.mToken;
         final AppWindowToken atoken = win.mAppToken;
         token.windows.remove(win);
@@ -1769,6 +1801,11 @@
             }
         }
 
+        if (win.mAttrs.type == TYPE_WALLPAPER ||
+                (win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
+            adjustWallpaperWindowsLocked();
+        }
+        
         if (!mInLayout) {
             assignLayersLocked();
             mLayoutNeeded = true;
@@ -6323,6 +6360,8 @@
             visible.set(vf);
 
             final Rect frame = mFrame;
+            final int fw = frame.width();
+            final int fh = frame.height();
 
             //System.out.println("In: w=" + w + " h=" + h + " container=" +
             //                   container + " x=" + mAttrs.x + " y=" + mAttrs.y);
@@ -6359,6 +6398,12 @@
             visibleInsets.right = frame.right-visible.right;
             visibleInsets.bottom = frame.bottom-visible.bottom;
 
+            if (mIsWallpaper && (fw != frame.width() || fh != frame.height())
+                    && mWallpaperTarget != null) {
+                updateWallpaperOffsetLocked(mWallpaperTarget, this,
+                        mDisplay.getWidth(), mDisplay.getHeight());
+            }
+            
             if (localLOGV) {
                 //if ("com.google.android.youtube".equals(mAttrs.packageName)
                 //        && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
@@ -6507,7 +6552,8 @@
                 Surface.openTransaction();
                 try {
                     try {
-                        mSurface.setPosition(mFrame.left, mFrame.top);
+                        mSurface.setPosition(mFrame.left + mXOffset,
+                                mFrame.top + mYOffset);
                         mSurface.setLayer(mAnimLayer);
                         mSurface.hide();
                         if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
@@ -8900,6 +8946,8 @@
                     focusDisplayed = true;
                 }
 
+                final boolean obscuredChanged = w.mObscured != obscured;
+                
                 // Update effect.
                 if (!(w.mObscured=obscured)) {
                     if (w.mSurface != null) {
@@ -9001,6 +9049,13 @@
                         }
                     }
                 }
+                
+                if (obscuredChanged && mWallpaperTarget == w) {
+                    // This is the wallpaper target and its obscured state
+                    // changed... make sure the current wallaper's visibility
+                    // has been updated accordingly.
+                    updateWallpaperVisibilityLocked();
+                }
             }
             
             if (backgroundFillerShown == false && mBackgroundFillerShown) {