am 284ac93a: More work on wallpapers: animations, lifecycle, scaling, etc.

Merge commit '284ac93aa30642fda87d5c40263a1263677c21cd' into eclair-plus-aosp

* commit '284ac93aa30642fda87d5c40263a1263677c21cd':
  More work on wallpapers: animations, lifecycle, scaling, etc.
This commit is contained in:
Dianne Hackborn
2009-08-30 10:57:59 -07:00
committed by Android Git Automerger
15 changed files with 376 additions and 86 deletions

View File

@@ -16,6 +16,7 @@
package android.app;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.app.IWallpaperManagerCallback;
import android.content.ComponentName;
@@ -36,7 +37,8 @@ interface IWallpaperManager {
/**
* Get the wallpaper.
*/
ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb);
ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
out Bundle outParams);
/**
* Clear the wallpaper.

View File

@@ -21,13 +21,18 @@ import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ViewRoot;
@@ -51,7 +56,7 @@ public class WallpaperManager {
static class Globals extends IWallpaperManagerCallback.Stub {
private IWallpaperManager mService;
private Drawable mWallpaper;
private Bitmap mWallpaper;
Globals() {
IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
@@ -69,7 +74,7 @@ public class WallpaperManager {
}
}
public Drawable peekWallpaper(Context context) {
public Bitmap peekWallpaperBitmap(Context context) {
synchronized (this) {
if (mWallpaper != null) {
return mWallpaper;
@@ -79,18 +84,82 @@ public class WallpaperManager {
}
}
private Drawable getCurrentWallpaperLocked(Context context) {
private Bitmap getCurrentWallpaperLocked(Context context) {
try {
ParcelFileDescriptor fd = mService.getWallpaper(this);
Bundle params = new Bundle();
ParcelFileDescriptor fd = mService.getWallpaper(this, params);
if (fd != null) {
Bitmap bm = BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, null);
if (bm != null) {
// For now clear the density until we figure out how
// to deal with it for wallpapers.
bm.setDensity(0);
return new BitmapDrawable(context.getResources(), bm);
int width = params.getInt("width", 0);
int height = params.getInt("height", 0);
if (width <= 0 || height <= 0) {
// Degenerate case: no size requested, just load
// bitmap as-is.
Bitmap bm = BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, null);
try {
fd.close();
} catch (IOException e) {
}
if (bm != null) {
bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
}
return bm;
}
// Load the bitmap with full color depth, to preserve
// quality for later processing.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bm = BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, options);
try {
fd.close();
} catch (IOException e) {
}
if (bm == null) {
return bm;
}
bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
// This is the final bitmap we want to return.
Bitmap newbm = Bitmap.createBitmap(width, height,
bm.getConfig());
newbm.setDensity(DisplayMetrics.DENSITY_DEVICE);
Canvas c = new Canvas(newbm);
c.setDensity(DisplayMetrics.DENSITY_DEVICE);
Rect targetRect = new Rect();
targetRect.left = targetRect.top = 0;
targetRect.right = bm.getWidth();
targetRect.bottom = bm.getHeight();
int deltaw = width - targetRect.right;
int deltah = height - targetRect.bottom;
if (deltaw > 0 || deltah > 0) {
// We need to scale up so it covers the entire
// area.
float scale = 1.0f;
if (deltaw > deltah) {
scale = width / (float)targetRect.right;
} else {
scale = height / (float)targetRect.bottom;
}
targetRect.right = (int)(targetRect.right*scale);
targetRect.bottom = (int)(targetRect.bottom*scale);
deltaw = width - targetRect.right;
deltah = height - targetRect.bottom;
}
targetRect.offset(deltaw/2, deltah/2);
Paint paint = new Paint();
paint.setFilterBitmap(true);
paint.setDither(true);
c.drawBitmap(bm, null, targetRect, paint);
bm.recycle();
return newbm;
}
} catch (RemoteException e) {
}
@@ -149,7 +218,8 @@ public class WallpaperManager {
* null pointer if these is none.
*/
public Drawable peekDrawable() {
return getGlobals().peekWallpaper(mContext);
Bitmap bm = getGlobals().peekWallpaperBitmap(mContext);
return bm != null ? new BitmapDrawable(mContext.getResources(), bm) : null;
}
/**

View File

@@ -20,5 +20,7 @@ package android.service.wallpaper;
* @hide
*/
oneway interface IWallpaperEngine {
void setDesiredSize(int width, int height);
void setVisibility(boolean visible);
void destroy();
}

View File

@@ -55,6 +55,7 @@ public abstract class WallpaperService extends Service {
private static final int DO_ATTACH = 10;
private static final int DO_DETACH = 20;
private static final int DO_SET_DESIRED_SIZE = 30;
private static final int MSG_UPDATE_SURFACE = 10000;
private static final int MSG_VISIBILITY_CHANGED = 10010;
@@ -78,6 +79,8 @@ public abstract class WallpaperService extends Service {
IBinder mWindowToken;
boolean mInitializing = true;
boolean mVisible;
boolean mDestroyed;
// Current window state.
boolean mCreated;
@@ -129,8 +132,15 @@ public abstract class WallpaperService extends Service {
return mIsCreating;
}
@Override
public void setFixedSize(int width, int height) {
throw new UnsupportedOperationException(
"Wallpapers currently only support sizing from layout");
}
public void setKeepScreenOn(boolean screenOn) {
// Ignore.
throw new UnsupportedOperationException(
"Wallpapers do not support keep screen on");
}
};
@@ -166,9 +176,13 @@ public abstract class WallpaperService extends Service {
@Override
public void dispatchAppVisibility(boolean visible) {
Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
visible ? 1 : 0);
mCaller.sendMessage(msg);
// We don't do this in preview mode; we'll let the preview
// activity tell us when to run.
if (!mIWallpaperEngine.mIsPreview) {
Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
visible ? 1 : 0);
mCaller.sendMessage(msg);
}
}
@Override
@@ -211,6 +225,15 @@ public abstract class WallpaperService extends Service {
return mIWallpaperEngine.mReqHeight;
}
/**
* Return whether the wallpaper is currently visible to the user,
* this is the last value supplied to
* {@link #onVisibilityChanged(boolean)}.
*/
public boolean isVisible() {
return mVisible;
}
/**
* Returns true if this engine is running in preview mode -- that is,
* it is being shown to the user before they select it as the actual
@@ -279,6 +302,13 @@ public abstract class WallpaperService extends Service {
int xPixelOffset, int yPixelOffset) {
}
/**
* Called when an application has changed the desired virtual size of
* the wallpaper.
*/
public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
}
/**
* Convenience for {@link SurfaceHolder.Callback#surfaceChanged
* SurfaceHolder.Callback.surfaceChanged()}.
@@ -301,6 +331,10 @@ public abstract class WallpaperService extends Service {
}
void updateSurface(boolean forceRelayout, boolean forceReport) {
if (mDestroyed) {
Log.w(TAG, "Ignoring updateSurface: destroyed");
}
int myWidth = mSurfaceHolder.getRequestedWidth();
if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.FILL_PARENT;
int myHeight = mSurfaceHolder.getRequestedHeight();
@@ -314,7 +348,7 @@ public abstract class WallpaperService extends Service {
if (forceRelayout || creating || formatChanged || sizeChanged
|| typeChanged || flagsChanged) {
if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
+ " format=" + formatChanged + " size=" + sizeChanged);
try {
@@ -343,6 +377,8 @@ public abstract class WallpaperService extends Service {
if (!mCreated) {
mLayout.type = mIWallpaperEngine.mWindowType;
mLayout.gravity = Gravity.LEFT|Gravity.TOP;
mLayout.windowAnimations =
com.android.internal.R.style.Animation_Wallpaper;
mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets);
}
@@ -354,7 +390,7 @@ public abstract class WallpaperService extends Service {
View.VISIBLE, false, mWinFrame, mContentInsets,
mVisibleInsets, mSurfaceHolder.mSurface);
if (DEBUG) Log.i(TAG, "New surface: " + mSurfaceHolder.mSurface
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
+ ", frame=" + mWinFrame);
int w = mWinFrame.width();
@@ -384,6 +420,8 @@ public abstract class WallpaperService extends Service {
if (!mCreated) {
mIsCreating = true;
if (DEBUG) Log.v(TAG, "onSurfaceCreated("
+ mSurfaceHolder + "): " + this);
onSurfaceCreated(mSurfaceHolder);
if (callbacks != null) {
for (SurfaceHolder.Callback c : callbacks) {
@@ -399,6 +437,10 @@ public abstract class WallpaperService extends Service {
+ " formatChanged=" + formatChanged
+ " sizeChanged=" + sizeChanged, e);
}
if (DEBUG) Log.v(TAG, "onSurfaceChanged("
+ mSurfaceHolder + ", " + mFormat
+ ", " + mCurWidth + ", " + mCurHeight
+ "): " + this);
onSurfaceChanged(mSurfaceHolder, mFormat,
mCurWidth, mCurHeight);
if (callbacks != null) {
@@ -425,26 +467,73 @@ public abstract class WallpaperService extends Service {
void attach(IWallpaperEngineWrapper wrapper) {
if (DEBUG) Log.v(TAG, "attach: " + this + " wrapper=" + wrapper);
if (mDestroyed) {
return;
}
mIWallpaperEngine = wrapper;
mCaller = wrapper.mCaller;
mConnection = wrapper.mConnection;
mWindowToken = wrapper.mWindowToken;
// XXX temp -- should run in size from layout (screen) mode.
mSurfaceHolder.setFixedSize(mIWallpaperEngine.mReqWidth,
mIWallpaperEngine.mReqHeight);
//mSurfaceHolder.setSizeFromLayout();
mSurfaceHolder.setSizeFromLayout();
mInitializing = true;
mSession = ViewRoot.getWindowSession(getMainLooper());
mWindow.setSession(mSession);
if (DEBUG) Log.v(TAG, "onCreate(): " + this);
onCreate(mSurfaceHolder);
mInitializing = false;
updateSurface(false, false);
}
void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
if (!mDestroyed) {
if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
+ desiredWidth + "," + desiredHeight + "): " + this);
onDesiredSizeChanged(desiredWidth, desiredHeight);
}
}
void doVisibilityChanged(boolean visible) {
if (!mDestroyed) {
mVisible = visible;
if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
+ "): " + this);
onVisibilityChanged(visible);
}
}
void doOffsetsChanged() {
if (mDestroyed) {
return;
}
float xOffset;
float yOffset;
synchronized (mLock) {
xOffset = mPendingXOffset;
yOffset = mPendingYOffset;
mOffsetMessageEnqueued = false;
}
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, xPixels, yPixels);
}
void detach() {
onDestroy();
mDestroyed = true;
if (mVisible) {
mVisible = false;
if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
onVisibilityChanged(false);
}
if (mDestroyReportNeeded) {
mDestroyReportNeeded = false;
SurfaceHolder.Callback callbacks[];
@@ -456,7 +545,14 @@ public abstract class WallpaperService extends Service {
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceDestroyed(mSurfaceHolder);
}
if (DEBUG) Log.v(TAG, "onSurfaceDestroyed("
+ mSurfaceHolder + "): " + this);
onSurfaceDestroyed(mSurfaceHolder);
}
if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
onDestroy();
if (mCreated) {
try {
mSession.remove(mWindow);
@@ -492,16 +588,21 @@ public abstract class WallpaperService extends Service {
mReqWidth = reqWidth;
mReqHeight = reqHeight;
try {
conn.attachEngine(this);
} catch (RemoteException e) {
destroy();
}
Message msg = mCaller.obtainMessage(DO_ATTACH);
mCaller.sendMessage(msg);
}
public void setDesiredSize(int width, int height) {
Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height);
mCaller.sendMessage(msg);
}
public void setVisibility(boolean visible) {
Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
visible ? 1 : 0);
mCaller.sendMessage(msg);
}
public void destroy() {
Message msg = mCaller.obtainMessage(DO_DETACH);
mCaller.sendMessage(msg);
@@ -510,6 +611,12 @@ public abstract class WallpaperService extends Service {
public void executeMessage(Message message) {
switch (message.what) {
case DO_ATTACH: {
try {
mConnection.attachEngine(this);
} catch (RemoteException e) {
Log.w(TAG, "Wallpaper host disappeared", e);
return;
}
Engine engine = onCreateEngine();
mEngine = engine;
engine.attach(this);
@@ -519,29 +626,20 @@ public abstract class WallpaperService extends Service {
mEngine.detach();
return;
}
case DO_SET_DESIRED_SIZE: {
mEngine.doDesiredSizeChanged(message.arg1, message.arg2);
return;
}
case MSG_UPDATE_SURFACE:
mEngine.updateSurface(true, false);
break;
case MSG_VISIBILITY_CHANGED:
if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
+ ": " + message.arg1);
mEngine.onVisibilityChanged(message.arg1 != 0);
mEngine.doVisibilityChanged(message.arg1 != 0);
break;
case MSG_WALLPAPER_OFFSETS: {
float xOffset;
float yOffset;
synchronized (mEngine.mLock) {
xOffset = mEngine.mPendingXOffset;
yOffset = mEngine.mPendingYOffset;
mEngine.mOffsetMessageEnqueued = false;
}
if (DEBUG) Log.v(TAG, "Offsets change in " + mEngine
+ ": " + xOffset + "," + yOffset);
final int availw = mReqWidth-mEngine.mCurWidth;
final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
final int availh = mReqHeight-mEngine.mCurHeight;
final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
mEngine.onOffsetsChanged(xOffset, yOffset, xPixels, yPixels);
mEngine.doOffsetsChanged();
} break;
case MSG_WINDOW_RESIZED: {
final boolean reportDraw = message.arg1 != 0;

View File

@@ -33,51 +33,49 @@ import android.content.BroadcastReceiver;
*/
public class ImageWallpaper extends WallpaperService {
WallpaperManager mWallpaperManager;
ImageWallpaper.DrawableEngine mEngine;
private WallpaperObserver mReceiver;
@Override
public void onCreate() {
super.onCreate();
mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
mReceiver = new WallpaperObserver();
registerReceiver(mReceiver, filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
public Engine onCreateEngine() {
mEngine = new DrawableEngine();
return mEngine;
}
class WallpaperObserver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
mEngine.updateWallpaper();
mEngine.drawFrame();
}
return new DrawableEngine();
}
class DrawableEngine extends Engine {
private final Object mLock = new Object();
private final Rect mBounds = new Rect();
private WallpaperObserver mReceiver;
Drawable mBackground;
float mXOffset;
float mYOffset;
class WallpaperObserver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
updateWallpaper();
drawFrame();
}
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
mReceiver = new WallpaperObserver();
registerReceiver(mReceiver, filter);
updateWallpaper();
surfaceHolder.setSizeFromLayout();
//setTouchEventsEnabled(true);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
@Override
public void onVisibilityChanged(boolean visible) {
drawFrame();

View File

@@ -898,7 +898,7 @@
<permission android:name="android.permission.BIND_WALLPAPER"
android:label="@string/permlab_bindWallpaper"
android:description="@string/permdesc_bindWallpaper"
android:protectionLevel="signature" />
android:protectionLevel="signatureOrSystem" />
<!-- Allows low-level access to setting the orientation (actually
rotation) of the screen. Not for use by normal applications. -->

View File

@@ -27,4 +27,6 @@
android:duration="@android:integer/config_mediumAnimTime" />
<translate android:fromXDelta="-150%" android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -26,4 +26,6 @@
android:duration="@android:integer/config_mediumAnimTime" />
<translate android:fromXDelta="0%" android:toXDelta="100%"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>

View File

@@ -26,4 +26,6 @@
android:duration="@android:integer/config_mediumAnimTime" />
<translate android:fromXDelta="100%" android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -27,4 +27,6 @@
android:duration="@android:integer/config_mediumAnimTime" />
<translate android:fromXDelta="0" android:toXDelta="-150%"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/options_panel_exit.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator">
<scale android:fromXScale="3.0" android:toXScale="1.0"
android:fromYScale="3.0" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_longAnimTime" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_longAnimTime" />
</set>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/options_panel_exit.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/accelerate_interpolator">
<scale android:fromXScale="1.0" android:toXScale="3.0"
android:fromYScale="1.0" android:toYScale="3.0"
android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_longAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_longAnimTime"/>
</set>

View File

@@ -160,6 +160,12 @@
<item name="windowExitAnimation">@anim/fade_out</item>
</style>
<!-- Standard animations for wallpapers. -->
<style name="Animation.Wallpaper">
<item name="windowEnterAnimation">@anim/wallpaper_enter</item>
<item name="windowExitAnimation">@anim/wallpaper_exit</item>
</style>
<!-- Status Bar Styles -->
<style name="TextAppearance.StatusBarTitle">

View File

@@ -32,6 +32,7 @@ import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.FileObserver;
@@ -232,6 +233,16 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
mWidth = width;
mHeight = height;
saveSettingsLocked();
if (mWallpaperConnection != null) {
if (mWallpaperConnection.mEngine != null) {
try {
mWallpaperConnection.mEngine.setDesiredSize(
width, height);
} catch (RemoteException e) {
}
notifyCallbacksLocked();
}
}
}
}
}
@@ -248,9 +259,14 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb) {
public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
Bundle outParams) {
synchronized (mLock) {
try {
if (outParams != null) {
outParams.putInt("width", mWidth);
outParams.putInt("height", mHeight);
}
mCallbacks.register(cb);
File f = WALLPAPER_FILE;
if (!f.exists()) {

View File

@@ -412,6 +412,8 @@ public class WindowManagerService extends IWindowManager.Stub
// to another, and this is the higher one in Z-order.
WindowState mUpperWallpaperTarget = null;
int mWallpaperAnimLayerAdjustment;
float mLastWallpaperX;
float mLastWallpaperY;
AppWindowToken mFocusedApp = null;
@@ -1371,6 +1373,11 @@ public class WindowManagerService extends IWindowManager.Stub
// what is below it for later.
foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
if (visible) {
mLastWallpaperX = mWallpaperTarget.mWallpaperX;
mLastWallpaperY = mWallpaperTarget.mWallpaperY;
}
// Start stepping backwards from here, ensuring that our wallpaper windows
// are correctly placed.
int curTokenIndex = mWallpaperTokens.size();
@@ -1383,8 +1390,7 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState wallpaper = token.windows.get(curWallpaperIndex);
if (visible) {
updateWallpaperOffsetLocked(mWallpaperTarget,
wallpaper, dw, dh);
updateWallpaperOffsetLocked(wallpaper, dw, dh);
}
// First, make sure the client has the current visibility
@@ -1455,36 +1461,35 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
boolean updateWallpaperOffsetLocked(WindowState target,
WindowState wallpaperWin, int dw, int dh) {
boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh) {
boolean changed = false;
boolean rawChanged = false;
if (target.mWallpaperX >= 0) {
if (mLastWallpaperX >= 0) {
int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
int offset = availw > 0 ? -(int)(availw*target.mWallpaperX+.5f) : 0;
int offset = availw > 0 ? -(int)(availw*mLastWallpaperX+.5f) : 0;
changed = wallpaperWin.mXOffset != offset;
if (changed) {
if (DEBUG_WALLPAPER) Log.v(TAG, "Update wallpaper "
+ wallpaperWin + " x: " + offset);
wallpaperWin.mXOffset = offset;
}
if (wallpaperWin.mWallpaperX != target.mWallpaperX) {
wallpaperWin.mWallpaperX = target.mWallpaperX;
if (wallpaperWin.mWallpaperX != mLastWallpaperX) {
wallpaperWin.mWallpaperX = mLastWallpaperX;
rawChanged = true;
}
}
if (target.mWallpaperY >= 0) {
if (mLastWallpaperY >= 0) {
int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
int offset = availh > 0 ? -(int)(availh*target.mWallpaperY+.5f) : 0;
int offset = availh > 0 ? -(int)(availh*mLastWallpaperY+.5f) : 0;
if (wallpaperWin.mYOffset != offset) {
if (DEBUG_WALLPAPER) Log.v(TAG, "Update wallpaper "
+ wallpaperWin + " y: " + offset);
changed = true;
wallpaperWin.mYOffset = offset;
}
if (wallpaperWin.mWallpaperY != target.mWallpaperY) {
wallpaperWin.mWallpaperY = target.mWallpaperY;
if (wallpaperWin.mWallpaperY != mLastWallpaperY) {
wallpaperWin.mWallpaperY = mLastWallpaperY;
rawChanged = true;
}
}
@@ -1511,6 +1516,8 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState target = mWallpaperTarget;
if (target != null) {
mLastWallpaperX = target.mWallpaperX;
mLastWallpaperY = target.mWallpaperY;
int curTokenIndex = mWallpaperTokens.size();
while (curTokenIndex > 0) {
curTokenIndex--;
@@ -1519,7 +1526,7 @@ public class WindowManagerService extends IWindowManager.Stub
while (curWallpaperIndex > 0) {
curWallpaperIndex--;
WindowState wallpaper = token.windows.get(curWallpaperIndex);
if (updateWallpaperOffsetLocked(target, wallpaper, dw, dh)) {
if (updateWallpaperOffsetLocked(wallpaper, dw, dh)) {
wallpaper.computeShownFrameLocked();
changed = true;
}
@@ -1545,8 +1552,7 @@ public class WindowManagerService extends IWindowManager.Stub
curWallpaperIndex--;
WindowState wallpaper = token.windows.get(curWallpaperIndex);
if (visible) {
updateWallpaperOffsetLocked(mWallpaperTarget,
wallpaper, dw, dh);
updateWallpaperOffsetLocked(wallpaper, dw, dh);
}
if (wallpaper.mWallpaperVisible != visible) {
@@ -2188,6 +2194,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
newConfig = updateOrientationFromAppTokensLocked(null, null);
performLayoutAndPlaceSurfacesLocked();
if (displayed && win.mIsWallpaper) {
updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
mDisplay.getHeight());
}
if (win.mAppToken != null) {
win.mAppToken.updateReportedVisibilityLocked();
}
@@ -3010,6 +3020,23 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
// If this is a translucent or wallpaper window, then don't
// show a starting window -- the current effect (a full-screen
// opaque starting window that fades away to the real contents
// when it is ready) does not work for this.
if (theme != 0) {
AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
com.android.internal.R.styleable.Window);
if (ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
return;
}
if (ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
return;
}
}
mStartingIconInTransition = true;
wtoken.startingData = new StartingData(
pkg, theme, nonLocalizedLabel,
@@ -6544,10 +6571,9 @@ public class WindowManagerService extends IWindowManager.Stub
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 (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
mDisplay.getHeight());
}
if (localLOGV) {
@@ -9851,6 +9877,10 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
}
pw.print(" mInTouchMode="); pw.println(mInTouchMode);
pw.print(" mSystemBooted="); pw.print(mSystemBooted);
pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
@@ -9865,6 +9895,8 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(mInputMethodAnimLayerAdjustment);
pw.print(" mWallpaperAnimLayerAdjustment=");
pw.println(mWallpaperAnimLayerAdjustment);
pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
pw.print(" mAppsFreezingScreen="); pw.println(mAppsFreezingScreen);