Live wallpapers become a little more real.
This adds a new theme for having a wallpaper, and fixes up the window manager
to do the right thing when transitioning between a windows with and without
wallpapers (between two windows with wallpapers is not yet addressed).
The wallpaper API now has callbacks to tell you when to start/stop animating.
Also fiddle the image wallpaper to be a little more interesting.
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 1b7efeb..69c48d3 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -403,6 +403,11 @@
final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
+ // If non-null, this is the currently visible window that is associated
+ // with the wallpaper.
+ WindowState mWallpaperTarget = null;
+ int mWallpaperAnimLayerAdjustment;
+
AppWindowToken mFocusedApp = null;
PowerManagerService mPowerManager;
@@ -1180,15 +1185,23 @@
int N = localmWindows.size();
WindowState w = null;
int i = N;
+ boolean visible = false;
while (i > 0) {
i--;
w = (WindowState)localmWindows.get(i);
- if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isVisibleOrAdding()) {
+ if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()) {
+ visible = true;
break;
}
}
- if (w != null) {
+ if (!visible) w = null;
+ mWallpaperTarget = w;
+
+ if (visible) {
+ mWallpaperAnimLayerAdjustment = w.mAppToken != null
+ ? w.mAppToken.animLayerAdjustment : 0;
+
// Now w is the window we are supposed to be behind... but we
// need to be sure to also be behind any of its attached windows,
// AND any starting window associated with it.
@@ -1220,6 +1233,24 @@
while (curWallpaperIndex > 0) {
curWallpaperIndex--;
WindowState wallpaper = token.windows.get(curWallpaperIndex);
+
+ // First, make sure the client has the current visibility
+ // state.
+ if (wallpaper.mWallpaperVisible != visible) {
+ wallpaper.mWallpaperVisible = visible;
+ try {
+ if (DEBUG_VISIBILITY) Log.v(TAG,
+ "Setting visibility of wallpaper " + wallpaper
+ + ": " + visible);
+ wallpaper.mClient.dispatchAppVisibility(visible);
+ } catch (RemoteException e) {
+ }
+ }
+
+ wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
+ if (DEBUG_LAYERS) Log.v(TAG, "Wallpaper win " + wallpaper
+ + " anim layer: " + wallpaper.mAnimLayer);
+
// First, if this window is at the current index, then all
// is well.
if (wallpaper == w) {
@@ -1248,6 +1279,24 @@
return changed;
}
+ void setWallpaperAnimLayerAdjustment(int adj) {
+ if (DEBUG_LAYERS) Log.v(TAG, "Setting wallpaper layer adj to " + adj);
+ mWallpaperAnimLayerAdjustment = adj;
+ 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);
+ wallpaper.mAnimLayer = wallpaper.mLayer + adj;
+ if (DEBUG_LAYERS) Log.v(TAG, "Wallpaper win " + wallpaper
+ + " anim layer: " + wallpaper.mAnimLayer);
+ }
+ }
+ }
+
public int addWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets) {
@@ -1867,6 +1916,9 @@
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client);
if (win != null && win.finishDrawingLocked()) {
+ if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
+ adjustWallpaperWindowsLocked();
+ }
mLayoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
@@ -5842,6 +5894,7 @@
Surface mSurface;
boolean mAttachedHidden; // is our parent window hidden?
boolean mLastHidden; // was this window last hidden?
+ boolean mWallpaperVisible; // for wallpaper, what was last vis report?
int mRequestedWidth;
int mRequestedHeight;
int mLastRequestedWidth;
@@ -6518,6 +6571,8 @@
mAnimLayer = mLayer;
if (mIsImWindow) {
mAnimLayer += mInputMethodAnimLayerAdjustment;
+ } else if (mIsWallpaper) {
+ mAnimLayer += mWallpaperAnimLayerAdjustment;
}
if (DEBUG_LAYERS) Log.v(TAG, "Stepping win " + this
+ " anim layer: " + mAnimLayer);
@@ -6604,6 +6659,19 @@
Transformation appTransformation =
(mAppToken != null && mAppToken.hasTransformation)
? mAppToken.transformation : null;
+
+ // Wallpapers are animated based on the "real" window they
+ // are currently targeting.
+ if (mAttrs.type == TYPE_WALLPAPER && mWallpaperTarget != null) {
+ if (mWallpaperTarget.mHasLocalTransformation) {
+ attachedTransformation = mWallpaperTarget.mTransformation;
+ }
+ if (mWallpaperTarget.mAppToken != null &&
+ mWallpaperTarget.mAppToken.hasTransformation) {
+ appTransformation = mWallpaperTarget.mAppToken.transformation;
+ }
+ }
+
if (selfTransformation || attachedTransformation != null
|| appTransformation != null) {
// cache often used attributes locally
@@ -6926,7 +6994,8 @@
if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
- pw.print(" mIsFloatingLayer="); pw.println(mIsFloatingLayer);
+ pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
+ pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
}
pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
pw.print(" mSubLayer="); pw.print(mSubLayer);
@@ -7212,6 +7281,9 @@
if (w == mInputMethodTarget) {
setInputMethodAnimLayerAdjustment(adj);
}
+ if (w == mWallpaperTarget) {
+ setWallpaperAnimLayerAdjustment(adj);
+ }
}
}
@@ -7978,6 +8050,8 @@
}
if (w.mIsImWindow) {
w.mAnimLayer += mInputMethodAnimLayerAdjustment;
+ } else if (w.mIsWallpaper) {
+ w.mAnimLayer += mWallpaperAnimLayerAdjustment;
}
if (DEBUG_LAYERS) Log.v(TAG, "Assign layer " + w + ": "
+ w.mAnimLayer);
@@ -8659,7 +8733,8 @@
}
boolean opaqueDrawn = w.isOpaqueDrawn();
- if (opaqueDrawn && w.isFullscreen(dw, dh)) {
+ if ((opaqueDrawn && w.isFullscreen(dw, dh))
+ || attrs.type == TYPE_WALLPAPER) {
// This window completely covers everything behind it,
// so we want to leave all of them as unblurred (for
// performance reasons).
@@ -9316,7 +9391,9 @@
pw.print( " no DimAnimator ");
}
pw.print(" mInputMethodAnimLayerAdjustment=");
- pw.println(mInputMethodAnimLayerAdjustment);
+ pw.print(mInputMethodAnimLayerAdjustment);
+ pw.print(" mWallpaperAnimLayerAdjustment=");
+ pw.println(mWallpaperAnimLayerAdjustment);
pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
pw.print(" mAppsFreezingScreen="); pw.println(mAppsFreezingScreen);