blob: 016541fe3e9060ab60b39b8a531034cbb643512b [file] [log] [blame]
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.service.wallpaper;
18
Dianne Hackborn067e5f62014-09-07 23:14:30 -070019import android.content.res.TypedArray;
Filip Gruszczynski4544b922015-04-16 13:18:58 -070020import android.graphics.Canvas;
Dianne Hackborn067e5f62014-09-07 23:14:30 -070021import android.os.SystemProperties;
Dianne Hackborn067e5f62014-09-07 23:14:30 -070022import android.view.WindowInsets;
Jeff Brown3d110b22014-11-21 19:01:13 -080023
Dianne Hackborn067e5f62014-09-07 23:14:30 -070024import com.android.internal.R;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070025import com.android.internal.os.HandlerCaller;
Griff Hazena0938022015-03-13 10:01:41 -070026import com.android.internal.util.ScreenShapeHelper;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070027import com.android.internal.view.BaseIWindow;
28import com.android.internal.view.BaseSurfaceHolder;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070029
Dianne Hackbornd6847842010-01-12 18:14:19 -080030import android.annotation.SdkConstant;
31import android.annotation.SdkConstant.SdkConstantType;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070032import android.app.Service;
Dianne Hackborn759a39e2009-08-09 17:20:27 -070033import android.app.WallpaperManager;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070034import android.content.Context;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070035import android.content.Intent;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080036import android.content.res.Configuration;
Mathias Agopian62bf4a02010-09-08 16:32:27 -070037import android.graphics.PixelFormat;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070038import android.graphics.Rect;
Jeff Brown3d110b22014-11-21 19:01:13 -080039import android.hardware.display.DisplayManager;
40import android.hardware.display.DisplayManager.DisplayListener;
Dianne Hackborn75804932009-10-20 20:15:20 -070041import android.os.Bundle;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070042import android.os.IBinder;
Dianne Hackborn19382ac2009-09-11 21:13:37 -070043import android.os.Looper;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070044import android.os.Message;
45import android.os.RemoteException;
46import android.util.Log;
Craig Mautner6881a102012-07-27 13:04:51 -070047import android.view.Display;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070048import android.view.Gravity;
49import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -070050import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -070051import android.view.InputDevice;
Jeff Brown4952dfd2011-11-30 19:23:22 -080052import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -080053import android.view.InputEventReceiver;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -070054import android.view.MotionEvent;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070055import android.view.SurfaceHolder;
56import android.view.View;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -070057import android.view.ViewGroup;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070058import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -070059import android.view.WindowManagerGlobal;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070060
Dianne Hackborn527de8e2011-08-22 16:10:36 -070061import java.io.FileDescriptor;
62import java.io.PrintWriter;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -080063import java.util.ArrayList;
64
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070065/**
66 * A wallpaper service is responsible for showing a live wallpaper behind
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080067 * applications that would like to sit on top of it. This service object
68 * itself does very little -- its only purpose is to generate instances of
Dianne Hackborne4260f42009-11-18 21:15:59 -080069 * {@link Engine} as needed. Implementing a wallpaper thus
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080070 * involves subclassing from this, subclassing an Engine implementation,
71 * and implementing {@link #onCreateEngine()} to return a new instance of
72 * your engine.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070073 */
74public abstract class WallpaperService extends Service {
75 /**
76 * The {@link Intent} that must be declared as handled by the service.
Dianne Hackbornd6847842010-01-12 18:14:19 -080077 * To be supported, the service must also require the
78 * {@link android.Manifest.permission#BIND_WALLPAPER} permission so
79 * that other applications can not abuse it.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070080 */
Dianne Hackbornd6847842010-01-12 18:14:19 -080081 @SdkConstant(SdkConstantType.SERVICE_ACTION)
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070082 public static final String SERVICE_INTERFACE =
Dianne Hackbornd6847842010-01-12 18:14:19 -080083 "android.service.wallpaper.WallpaperService";
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070084
Dianne Hackborneb034652009-09-07 00:49:58 -070085 /**
86 * Name under which a WallpaperService component publishes information
87 * about itself. This meta-data must reference an XML resource containing
88 * a <code>&lt;{@link android.R.styleable#Wallpaper wallpaper}&gt;</code>
89 * tag.
90 */
91 public static final String SERVICE_META_DATA = "android.service.wallpaper";
Craig Mautnerb1ef3692012-11-16 17:31:04 -080092
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070093 static final String TAG = "WallpaperService";
Dianne Hackborn72c82ab2009-08-11 21:13:54 -070094 static final boolean DEBUG = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070095
96 private static final int DO_ATTACH = 10;
97 private static final int DO_DETACH = 20;
Dianne Hackborn284ac932009-08-28 10:34:25 -070098 private static final int DO_SET_DESIRED_SIZE = 30;
Dianne Hackborn067e5f62014-09-07 23:14:30 -070099 private static final int DO_SET_DISPLAY_PADDING = 40;
100
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700101 private static final int MSG_UPDATE_SURFACE = 10000;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700102 private static final int MSG_VISIBILITY_CHANGED = 10010;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700103 private static final int MSG_WALLPAPER_OFFSETS = 10020;
Dianne Hackborn75804932009-10-20 20:15:20 -0700104 private static final int MSG_WALLPAPER_COMMAND = 10025;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700105 private static final int MSG_WINDOW_RESIZED = 10030;
Craig Mautner5702d4d2012-06-30 14:10:16 -0700106 private static final int MSG_WINDOW_MOVED = 10035;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700107 private static final int MSG_TOUCH_EVENT = 10040;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700108
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -0800109 private final ArrayList<Engine> mActiveEngines
110 = new ArrayList<Engine>();
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700111
Dianne Hackborn75804932009-10-20 20:15:20 -0700112 static final class WallpaperCommand {
113 String action;
114 int x;
115 int y;
116 int z;
117 Bundle extras;
118 boolean sync;
119 }
120
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700121 /**
122 * The actual implementation of a wallpaper. A wallpaper service may
123 * have multiple instances running (for example as a real wallpaper
124 * and as a preview), each of which is represented by its own Engine
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700125 * instance. You must implement {@link WallpaperService#onCreateEngine()}
126 * to return your concrete Engine implementation.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700127 */
128 public class Engine {
129 IWallpaperEngineWrapper mIWallpaperEngine;
130
131 // Copies from mIWallpaperEngine.
132 HandlerCaller mCaller;
133 IWallpaperConnection mConnection;
134 IBinder mWindowToken;
135
136 boolean mInitializing = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700137 boolean mVisible;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700138 boolean mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700139 boolean mDestroyed;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700140
141 // Current window state.
142 boolean mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700143 boolean mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700144 boolean mIsCreating;
145 boolean mDrawingAllowed;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700146 boolean mOffsetsChanged;
Jeff Sharkey35be7562012-04-18 19:16:15 -0700147 boolean mFixedSizeAllowed;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700148 int mWidth;
149 int mHeight;
150 int mFormat;
151 int mType;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700152 int mCurWidth;
153 int mCurHeight;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700154 int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700155 int mWindowPrivateFlags =
156 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700157 int mCurWindowFlags = mWindowFlags;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700158 int mCurWindowPrivateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700159 final Rect mVisibleInsets = new Rect();
160 final Rect mWinFrame = new Rect();
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800161 final Rect mOverscanInsets = new Rect();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700162 final Rect mContentInsets = new Rect();
Adrian Roosfa104232014-06-20 16:10:14 -0700163 final Rect mStableInsets = new Rect();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700164 final Rect mDispatchedOverscanInsets = new Rect();
165 final Rect mDispatchedContentInsets = new Rect();
166 final Rect mDispatchedStableInsets = new Rect();
167 final Rect mFinalSystemInsets = new Rect();
168 final Rect mFinalStableInsets = new Rect();
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700169 final Configuration mConfiguration = new Configuration();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700170
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700171 private boolean mWindowIsRound;
172
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700173 final WindowManager.LayoutParams mLayout
174 = new WindowManager.LayoutParams();
175 IWindowSession mSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700176 InputChannel mInputChannel;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700177
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700178 final Object mLock = new Object();
179 boolean mOffsetMessageEnqueued;
180 float mPendingXOffset;
181 float mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800182 float mPendingXOffsetStep;
183 float mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700184 boolean mPendingSync;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700185 MotionEvent mPendingMove;
Jeff Brown3d110b22014-11-21 19:01:13 -0800186
187 DisplayManager mDisplayManager;
188 Display mDisplay;
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700189 private int mDisplayState;
Jeff Brown3d110b22014-11-21 19:01:13 -0800190
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700191 final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700192 {
Jeff Brown24572372011-06-09 19:05:15 -0700193 mRequestedFormat = PixelFormat.RGBX_8888;
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700194 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700195
196 @Override
197 public boolean onAllowLockCanvas() {
198 return mDrawingAllowed;
199 }
200
201 @Override
202 public void onRelayoutContainer() {
203 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
204 mCaller.sendMessage(msg);
205 }
206
207 @Override
208 public void onUpdateSurface() {
209 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
210 mCaller.sendMessage(msg);
211 }
212
213 public boolean isCreating() {
214 return mIsCreating;
215 }
216
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800217 @Override
218 public void setFixedSize(int width, int height) {
Jeff Sharkey35be7562012-04-18 19:16:15 -0700219 if (!mFixedSizeAllowed) {
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800220 // Regular apps can't do this. It can only work for
221 // certain designs of window animations, so you can't
222 // rely on it.
223 throw new UnsupportedOperationException(
224 "Wallpapers currently only support sizing from layout");
225 }
Michael Jurkab8f939f2011-02-01 20:50:30 -0800226 super.setFixedSize(width, height);
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800227 }
228
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700229 public void setKeepScreenOn(boolean screenOn) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700230 throw new UnsupportedOperationException(
231 "Wallpapers do not support keep screen on");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700232 }
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700233
234 @Override
235 public Canvas lockCanvas() {
236 if (mDisplayState == Display.STATE_DOZE
237 || mDisplayState == Display.STATE_DOZE_SUSPEND) {
238 try {
239 mSession.pokeDrawLock(mWindow);
240 } catch (RemoteException e) {
241 // System server died, can be ignored.
242 }
243 }
244 return super.lockCanvas();
245 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700246 };
Jeff Brown32cbc38552011-12-01 14:01:49 -0800247
248 final class WallpaperInputEventReceiver extends InputEventReceiver {
249 public WallpaperInputEventReceiver(InputChannel inputChannel, Looper looper) {
250 super(inputChannel, looper);
251 }
252
Jeff Brown46b9ac02010-04-22 18:58:52 -0700253 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800254 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700255 boolean handled = false;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700256 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800257 if (event instanceof MotionEvent
258 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800259 MotionEvent dup = MotionEvent.obtainNoHistory((MotionEvent)event);
260 dispatchPointer(dup);
Jeff Brown3915bb82010-11-05 15:02:16 -0700261 handled = true;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700262 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700263 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800264 finishInputEvent(event, handled);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700265 }
266 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800267 }
268 WallpaperInputEventReceiver mInputEventReceiver;
269
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700270 final BaseIWindow mWindow = new BaseIWindow() {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700271 @Override
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800272 public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Adrian Roosfa104232014-06-20 16:10:14 -0700273 Rect visibleInsets, Rect stableInsets, boolean reportDraw,
274 Configuration newConfig) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700275 Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
276 reportDraw ? 1 : 0);
277 mCaller.sendMessage(msg);
278 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700279
280 @Override
281 public void moved(int newX, int newY) {
282 Message msg = mCaller.obtainMessageII(MSG_WINDOW_MOVED, newX, newY);
283 mCaller.sendMessage(msg);
284 }
285
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700286 @Override
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700287 public void dispatchAppVisibility(boolean visible) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700288 // We don't do this in preview mode; we'll let the preview
289 // activity tell us when to run.
290 if (!mIWallpaperEngine.mIsPreview) {
291 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
292 visible ? 1 : 0);
293 mCaller.sendMessage(msg);
294 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700295 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700296
297 @Override
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800298 public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
299 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700300 synchronized (mLock) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700301 if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700302 mPendingXOffset = x;
303 mPendingYOffset = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800304 mPendingXOffsetStep = xStep;
305 mPendingYOffsetStep = yStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700306 if (sync) {
307 mPendingSync = true;
308 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700309 if (!mOffsetMessageEnqueued) {
310 mOffsetMessageEnqueued = true;
311 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
312 mCaller.sendMessage(msg);
313 }
314 }
315 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700316
317 @Override
Dianne Hackborn75804932009-10-20 20:15:20 -0700318 public void dispatchWallpaperCommand(String action, int x, int y,
319 int z, Bundle extras, boolean sync) {
320 synchronized (mLock) {
321 if (DEBUG) Log.v(TAG, "Dispatch wallpaper command: " + x + ", " + y);
322 WallpaperCommand cmd = new WallpaperCommand();
323 cmd.action = action;
324 cmd.x = x;
325 cmd.y = y;
326 cmd.z = z;
327 cmd.extras = extras;
328 cmd.sync = sync;
329 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_COMMAND);
330 msg.obj = cmd;
331 mCaller.sendMessage(msg);
332 }
333 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700334 };
335
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700336 /**
337 * Provides access to the surface in which this wallpaper is drawn.
338 */
339 public SurfaceHolder getSurfaceHolder() {
340 return mSurfaceHolder;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700341 }
342
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700343 /**
344 * Convenience for {@link WallpaperManager#getDesiredMinimumWidth()
345 * WallpaperManager.getDesiredMinimumWidth()}, returning the width
346 * that the system would like this wallpaper to run in.
347 */
348 public int getDesiredMinimumWidth() {
349 return mIWallpaperEngine.mReqWidth;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700350 }
351
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700352 /**
353 * Convenience for {@link WallpaperManager#getDesiredMinimumHeight()
354 * WallpaperManager.getDesiredMinimumHeight()}, returning the height
355 * that the system would like this wallpaper to run in.
356 */
357 public int getDesiredMinimumHeight() {
358 return mIWallpaperEngine.mReqHeight;
359 }
360
361 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700362 * Return whether the wallpaper is currently visible to the user,
363 * this is the last value supplied to
364 * {@link #onVisibilityChanged(boolean)}.
365 */
366 public boolean isVisible() {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700367 return mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700368 }
369
370 /**
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700371 * Returns true if this engine is running in preview mode -- that is,
372 * it is being shown to the user before they select it as the actual
373 * wallpaper.
374 */
375 public boolean isPreview() {
376 return mIWallpaperEngine.mIsPreview;
377 }
378
379 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700380 * Control whether this wallpaper will receive raw touch events
381 * from the window manager as the user interacts with the window
382 * that is currently displaying the wallpaper. By default they
383 * are turned off. If enabled, the events will be received in
384 * {@link #onTouchEvent(MotionEvent)}.
385 */
386 public void setTouchEventsEnabled(boolean enabled) {
387 mWindowFlags = enabled
388 ? (mWindowFlags&~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
389 : (mWindowFlags|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
390 if (mCreated) {
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700391 updateSurface(false, false, false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700392 }
393 }
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700394
395 /**
396 * Control whether this wallpaper will receive notifications when the wallpaper
397 * has been scrolled. By default, wallpapers will receive notifications, although
398 * the default static image wallpapers do not. It is a performance optimization to
399 * set this to false.
400 *
401 * @param enabled whether the wallpaper wants to receive offset notifications
402 */
403 public void setOffsetNotificationsEnabled(boolean enabled) {
404 mWindowPrivateFlags = enabled
405 ? (mWindowPrivateFlags |
406 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS)
407 : (mWindowPrivateFlags &
408 ~WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS);
409 if (mCreated) {
410 updateSurface(false, false, false);
411 }
412 }
Jeff Sharkey35be7562012-04-18 19:16:15 -0700413
414 /** {@hide} */
415 public void setFixedSizeAllowed(boolean allowed) {
416 mFixedSizeAllowed = allowed;
417 }
418
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700419 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700420 * Called once to initialize the engine. After returning, the
421 * engine's surface will be created by the framework.
422 */
423 public void onCreate(SurfaceHolder surfaceHolder) {
424 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700425
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700426 /**
427 * Called right before the engine is going away. After this the
428 * surface will be destroyed and this Engine object is no longer
429 * valid.
430 */
431 public void onDestroy() {
432 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700433
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700434 /**
435 * Called to inform you of the wallpaper becoming visible or
436 * hidden. <em>It is very important that a wallpaper only use
437 * CPU while it is visible.</em>.
438 */
439 public void onVisibilityChanged(boolean visible) {
440 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700441
442 /**
443 * Called with the current insets that are in effect for the wallpaper.
444 * This gives you the part of the overall wallpaper surface that will
445 * generally be visible to the user (ignoring position offsets applied to it).
446 *
447 * @param insets Insets to apply.
448 */
449 public void onApplyWindowInsets(WindowInsets insets) {
450 }
451
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700452 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700453 * Called as the user performs touch-screen interaction with the
454 * window that is currently showing this wallpaper. Note that the
455 * events you receive here are driven by the actual application the
Marco Nelissenae87bd02009-09-17 09:44:43 -0700456 * user is interacting with, so if it is slow you will get fewer
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700457 * move events.
458 */
459 public void onTouchEvent(MotionEvent event) {
460 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700461
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700462 /**
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700463 * Called to inform you of the wallpaper's offsets changing
464 * within its contain, corresponding to the container's
465 * call to {@link WallpaperManager#setWallpaperOffsets(IBinder, float, float)
466 * WallpaperManager.setWallpaperOffsets()}.
467 */
468 public void onOffsetsChanged(float xOffset, float yOffset,
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800469 float xOffsetStep, float yOffsetStep,
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700470 int xPixelOffset, int yPixelOffset) {
471 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700472
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700473 /**
Dianne Hackborn75804932009-10-20 20:15:20 -0700474 * Process a command that was sent to the wallpaper with
Dianne Hackborn13bf82602009-11-05 21:45:51 -0800475 * {@link WallpaperManager#sendWallpaperCommand}.
Dianne Hackborn75804932009-10-20 20:15:20 -0700476 * The default implementation does nothing, and always returns null
477 * as the result.
478 *
479 * @param action The name of the command to perform. This tells you
480 * what to do and how to interpret the rest of the arguments.
481 * @param x Generic integer parameter.
482 * @param y Generic integer parameter.
483 * @param z Generic integer parameter.
484 * @param extras Any additional parameters.
485 * @param resultRequested If true, the caller is requesting that
486 * a result, appropriate for the command, be returned back.
487 * @return If returning a result, create a Bundle and place the
488 * result data in to it. Otherwise return null.
489 */
490 public Bundle onCommand(String action, int x, int y, int z,
491 Bundle extras, boolean resultRequested) {
492 return null;
493 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700494
Dianne Hackborn75804932009-10-20 20:15:20 -0700495 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700496 * Called when an application has changed the desired virtual size of
497 * the wallpaper.
498 */
499 public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
500 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700501
Dianne Hackborn284ac932009-08-28 10:34:25 -0700502 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700503 * Convenience for {@link SurfaceHolder.Callback#surfaceChanged
504 * SurfaceHolder.Callback.surfaceChanged()}.
505 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700506 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
507 }
508
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700509 /**
Dianne Hackborn1d28f9c2010-07-13 20:38:06 -0700510 * Convenience for {@link SurfaceHolder.Callback2#surfaceRedrawNeeded
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700511 * SurfaceHolder.Callback.surfaceRedrawNeeded()}.
512 */
513 public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
514 }
515
516 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700517 * Convenience for {@link SurfaceHolder.Callback#surfaceCreated
518 * SurfaceHolder.Callback.surfaceCreated()}.
519 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700520 public void onSurfaceCreated(SurfaceHolder holder) {
521 }
522
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700523 /**
524 * Convenience for {@link SurfaceHolder.Callback#surfaceDestroyed
525 * SurfaceHolder.Callback.surfaceDestroyed()}.
526 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700527 public void onSurfaceDestroyed(SurfaceHolder holder) {
528 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700529
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700530 protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
531 out.print(prefix); out.print("mInitializing="); out.print(mInitializing);
532 out.print(" mDestroyed="); out.println(mDestroyed);
533 out.print(prefix); out.print("mVisible="); out.print(mVisible);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700534 out.print(" mReportedVisible="); out.println(mReportedVisible);
Jeff Brown3d110b22014-11-21 19:01:13 -0800535 out.print(prefix); out.print("mDisplay="); out.println(mDisplay);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700536 out.print(prefix); out.print("mCreated="); out.print(mCreated);
537 out.print(" mSurfaceCreated="); out.print(mSurfaceCreated);
538 out.print(" mIsCreating="); out.print(mIsCreating);
539 out.print(" mDrawingAllowed="); out.println(mDrawingAllowed);
540 out.print(prefix); out.print("mWidth="); out.print(mWidth);
541 out.print(" mCurWidth="); out.print(mCurWidth);
542 out.print(" mHeight="); out.print(mHeight);
543 out.print(" mCurHeight="); out.println(mCurHeight);
544 out.print(prefix); out.print("mType="); out.print(mType);
545 out.print(" mWindowFlags="); out.print(mWindowFlags);
546 out.print(" mCurWindowFlags="); out.println(mCurWindowFlags);
Dianne Hackbornd052a942014-11-21 15:23:13 -0800547 out.print(prefix); out.print("mWindowPrivateFlags="); out.print(mWindowPrivateFlags);
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700548 out.print(" mCurWindowPrivateFlags="); out.println(mCurWindowPrivateFlags);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700549 out.print(prefix); out.print("mVisibleInsets=");
550 out.print(mVisibleInsets.toShortString());
551 out.print(" mWinFrame="); out.print(mWinFrame.toShortString());
552 out.print(" mContentInsets="); out.println(mContentInsets.toShortString());
553 out.print(prefix); out.print("mConfiguration="); out.println(mConfiguration);
554 out.print(prefix); out.print("mLayout="); out.println(mLayout);
555 synchronized (mLock) {
556 out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
557 out.print(" mPendingXOffset="); out.println(mPendingXOffset);
558 out.print(prefix); out.print("mPendingXOffsetStep=");
559 out.print(mPendingXOffsetStep);
560 out.print(" mPendingXOffsetStep="); out.println(mPendingXOffsetStep);
561 out.print(prefix); out.print("mOffsetMessageEnqueued=");
562 out.print(mOffsetMessageEnqueued);
563 out.print(" mPendingSync="); out.println(mPendingSync);
564 if (mPendingMove != null) {
565 out.print(prefix); out.print("mPendingMove="); out.println(mPendingMove);
566 }
567 }
568 }
569
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700570 private void dispatchPointer(MotionEvent event) {
Jeff Brown33bbfd22011-02-24 20:55:35 -0800571 if (event.isTouchEvent()) {
572 synchronized (mLock) {
573 if (event.getAction() == MotionEvent.ACTION_MOVE) {
574 mPendingMove = event;
575 } else {
576 mPendingMove = null;
577 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700578 }
Jeff Brown33bbfd22011-02-24 20:55:35 -0800579 Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
580 mCaller.sendMessage(msg);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800581 } else {
582 event.recycle();
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700583 }
584 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700585
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700586 void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700587 if (mDestroyed) {
588 Log.w(TAG, "Ignoring updateSurface: destroyed");
589 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700590
591 boolean fixedSize = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700592 int myWidth = mSurfaceHolder.getRequestedWidth();
Romain Guy980a9382010-01-08 15:06:28 -0800593 if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700594 else fixedSize = true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700595 int myHeight = mSurfaceHolder.getRequestedHeight();
Romain Guy980a9382010-01-08 15:06:28 -0800596 if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700597 else fixedSize = true;
598
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700599 final boolean creating = !mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700600 final boolean surfaceCreating = !mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700601 final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700602 boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700603 boolean insetsChanged = !mCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700604 final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700605 final boolean flagsChanged = mCurWindowFlags != mWindowFlags ||
606 mCurWindowPrivateFlags != mWindowPrivateFlags;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700607 if (forceRelayout || creating || surfaceCreating || formatChanged || sizeChanged
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -0700608 || typeChanged || flagsChanged || redrawNeeded
609 || !mIWallpaperEngine.mShownReported) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700610
Dianne Hackborn284ac932009-08-28 10:34:25 -0700611 if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700612 + " format=" + formatChanged + " size=" + sizeChanged);
613
614 try {
615 mWidth = myWidth;
616 mHeight = myHeight;
617 mFormat = mSurfaceHolder.getRequestedFormat();
618 mType = mSurfaceHolder.getRequestedType();
619
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700620 mLayout.x = 0;
621 mLayout.y = 0;
622 mLayout.width = myWidth;
623 mLayout.height = myHeight;
624
625 mLayout.format = mFormat;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700626
627 mCurWindowFlags = mWindowFlags;
628 mLayout.flags = mWindowFlags
629 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
630 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
631 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
632 ;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700633 mCurWindowPrivateFlags = mWindowPrivateFlags;
634 mLayout.privateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700635
636 mLayout.memoryType = mType;
637 mLayout.token = mWindowToken;
638
639 if (!mCreated) {
Filip Gruszczynskid66ba062015-03-23 12:59:02 -0700640 // Retrieve watch round info
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700641 TypedArray windowStyle = obtainStyledAttributes(
642 com.android.internal.R.styleable.Window);
Griff Hazena0938022015-03-13 10:01:41 -0700643 mWindowIsRound = ScreenShapeHelper.getWindowIsRound(getResources());
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700644 windowStyle.recycle();
645
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700646 // Add window
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700647 mLayout.type = mIWallpaperEngine.mWindowType;
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -0700648 mLayout.gravity = Gravity.START|Gravity.TOP;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -0700649 mLayout.setTitle(WallpaperService.this.getClass().getName());
Dianne Hackborn284ac932009-08-28 10:34:25 -0700650 mLayout.windowAnimations =
651 com.android.internal.R.style.Animation_Wallpaper;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700652 mInputChannel = new InputChannel();
Craig Mautner6881a102012-07-27 13:04:51 -0700653 if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE,
Adrian Roos37d7a682014-11-06 18:15:16 +0100654 Display.DEFAULT_DISPLAY, mContentInsets, mStableInsets,
655 mInputChannel) < 0) {
Mattias Peterssond9463f52011-01-12 15:38:55 +0100656 Log.w(TAG, "Failed to add window while updating wallpaper surface.");
657 return;
658 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700659 mCreated = true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700660
Jeff Brown32cbc38552011-12-01 14:01:49 -0800661 mInputEventReceiver = new WallpaperInputEventReceiver(
662 mInputChannel, Looper.myLooper());
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700663 }
664
665 mSurfaceHolder.mSurfaceLock.lock();
666 mDrawingAllowed = true;
667
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700668 if (!fixedSize) {
669 mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
670 } else {
671 mLayout.surfaceInsets.set(0, 0, 0, 0);
672 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700673 final int relayoutResult = mSession.relayout(
Dianne Hackborn9a230e02011-10-06 11:51:27 -0700674 mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800675 View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
Adrian Roosfa104232014-06-20 16:10:14 -0700676 mVisibleInsets, mStableInsets, mConfiguration, mSurfaceHolder.mSurface);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700677
Dianne Hackborn284ac932009-08-28 10:34:25 -0700678 if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700679 + ", frame=" + mWinFrame);
680
Adrian Roos2ae38052014-12-09 17:03:01 +0000681 int w = mWinFrame.width();
682 int h = mWinFrame.height();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700683
684 if (!fixedSize) {
685 final Rect padding = mIWallpaperEngine.mDisplayPadding;
686 w += padding.left + padding.right;
687 h += padding.top + padding.bottom;
688 mOverscanInsets.left += padding.left;
689 mOverscanInsets.top += padding.top;
690 mOverscanInsets.right += padding.right;
691 mOverscanInsets.bottom += padding.bottom;
692 mContentInsets.left += padding.left;
693 mContentInsets.top += padding.top;
694 mContentInsets.right += padding.right;
695 mContentInsets.bottom += padding.bottom;
696 mStableInsets.left += padding.left;
697 mStableInsets.top += padding.top;
698 mStableInsets.right += padding.right;
699 mStableInsets.bottom += padding.bottom;
700 }
701
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700702 if (mCurWidth != w) {
703 sizeChanged = true;
704 mCurWidth = w;
705 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700706 if (mCurHeight != h) {
707 sizeChanged = true;
708 mCurHeight = h;
709 }
Jeff Brown30bc34f2011-01-25 12:56:56 -0800710
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700711 insetsChanged |= !mDispatchedOverscanInsets.equals(mOverscanInsets);
712 insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
713 insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
714
Jeff Brown30bc34f2011-01-25 12:56:56 -0800715 mSurfaceHolder.setSurfaceFrameSize(w, h);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700716 mSurfaceHolder.mSurfaceLock.unlock();
717
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700718 if (!mSurfaceHolder.mSurface.isValid()) {
719 reportSurfaceDestroyed();
720 if (DEBUG) Log.v(TAG, "Layout: Surface destroyed");
721 return;
722 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700723
724 boolean didSurface = false;
725
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700726 try {
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700727 mSurfaceHolder.ungetCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700728
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700729 if (surfaceCreating) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700730 mIsCreating = true;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700731 didSurface = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700732 if (DEBUG) Log.v(TAG, "onSurfaceCreated("
733 + mSurfaceHolder + "): " + this);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700734 onSurfaceCreated(mSurfaceHolder);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700735 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700736 if (callbacks != null) {
737 for (SurfaceHolder.Callback c : callbacks) {
738 c.surfaceCreated(mSurfaceHolder);
739 }
740 }
741 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700742
Jeff Brown98365d72012-08-19 20:30:52 -0700743 redrawNeeded |= creating || (relayoutResult
744 & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700745
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700746 if (forceReport || creating || surfaceCreating
747 || formatChanged || sizeChanged) {
Dianne Hackborncbf15042009-08-18 18:29:09 -0700748 if (DEBUG) {
749 RuntimeException e = new RuntimeException();
750 e.fillInStackTrace();
751 Log.w(TAG, "forceReport=" + forceReport + " creating=" + creating
752 + " formatChanged=" + formatChanged
753 + " sizeChanged=" + sizeChanged, e);
754 }
Dianne Hackborn284ac932009-08-28 10:34:25 -0700755 if (DEBUG) Log.v(TAG, "onSurfaceChanged("
756 + mSurfaceHolder + ", " + mFormat
757 + ", " + mCurWidth + ", " + mCurHeight
758 + "): " + this);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700759 didSurface = true;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700760 onSurfaceChanged(mSurfaceHolder, mFormat,
761 mCurWidth, mCurHeight);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700762 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700763 if (callbacks != null) {
764 for (SurfaceHolder.Callback c : callbacks) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700765 c.surfaceChanged(mSurfaceHolder, mFormat,
766 mCurWidth, mCurHeight);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700767 }
768 }
769 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700770
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700771 if (insetsChanged) {
772 mDispatchedOverscanInsets.set(mOverscanInsets);
773 mDispatchedContentInsets.set(mContentInsets);
774 mDispatchedStableInsets.set(mStableInsets);
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700775 mFinalSystemInsets.set(mDispatchedOverscanInsets);
776 mFinalStableInsets.set(mDispatchedStableInsets);
Filip Gruszczynskid66ba062015-03-23 12:59:02 -0700777 mFinalSystemInsets.bottom = mIWallpaperEngine.mDisplayPadding.bottom;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700778 WindowInsets insets = new WindowInsets(mFinalSystemInsets,
Griff Hazena0938022015-03-13 10:01:41 -0700779 null, mFinalStableInsets, mWindowIsRound);
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700780 onApplyWindowInsets(insets);
781 }
782
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700783 if (redrawNeeded) {
784 onSurfaceRedrawNeeded(mSurfaceHolder);
785 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
786 if (callbacks != null) {
787 for (SurfaceHolder.Callback c : callbacks) {
788 if (c instanceof SurfaceHolder.Callback2) {
789 ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
790 mSurfaceHolder);
791 }
792 }
793 }
794 }
795
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700796 if (didSurface && !mReportedVisible) {
797 // This wallpaper is currently invisible, but its
798 // surface has changed. At this point let's tell it
799 // again that it is invisible in case the report about
800 // the surface caused it to start running. We really
801 // don't want wallpapers running when not visible.
802 if (mIsCreating) {
803 // Some wallpapers will ignore this call if they
804 // had previously been told they were invisble,
805 // so if we are creating a new surface then toggle
806 // the state to get them to notice.
807 if (DEBUG) Log.v(TAG, "onVisibilityChanged(true) at surface: "
808 + this);
809 onVisibilityChanged(true);
810 }
811 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false) at surface: "
812 + this);
813 onVisibilityChanged(false);
814 }
815
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700816 } finally {
817 mIsCreating = false;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700818 mSurfaceCreated = true;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700819 if (redrawNeeded) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700820 mSession.finishDrawing(mWindow);
821 }
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -0700822 mIWallpaperEngine.reportShown();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700823 }
824 } catch (RemoteException ex) {
825 }
826 if (DEBUG) Log.v(
827 TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
828 " w=" + mLayout.width + " h=" + mLayout.height);
829 }
830 }
831
832 void attach(IWallpaperEngineWrapper wrapper) {
Dianne Hackborncbf15042009-08-18 18:29:09 -0700833 if (DEBUG) Log.v(TAG, "attach: " + this + " wrapper=" + wrapper);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700834 if (mDestroyed) {
835 return;
836 }
837
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700838 mIWallpaperEngine = wrapper;
839 mCaller = wrapper.mCaller;
840 mConnection = wrapper.mConnection;
841 mWindowToken = wrapper.mWindowToken;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700842 mSurfaceHolder.setSizeFromLayout();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700843 mInitializing = true;
Jeff Brownf9e989d2013-04-04 23:04:03 -0700844 mSession = WindowManagerGlobal.getWindowSession();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700845
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700846 mWindow.setSession(mSession);
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -0700847
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700848 mLayout.packageName = getPackageName();
849
Jeff Brown3d110b22014-11-21 19:01:13 -0800850 mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
851 mDisplayManager.registerDisplayListener(mDisplayListener, mCaller.getHandler());
852 mDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700853 mDisplayState = mDisplay.getState();
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -0700854
Dianne Hackborn284ac932009-08-28 10:34:25 -0700855 if (DEBUG) Log.v(TAG, "onCreate(): " + this);
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700856 onCreate(mSurfaceHolder);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700857
858 mInitializing = false;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700859 mReportedVisible = false;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700860 updateSurface(false, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700861 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700862
Dianne Hackborn284ac932009-08-28 10:34:25 -0700863 void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
864 if (!mDestroyed) {
865 if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
866 + desiredWidth + "," + desiredHeight + "): " + this);
Joe Onoratodcfae5c2010-10-28 18:03:23 -0700867 mIWallpaperEngine.mReqWidth = desiredWidth;
868 mIWallpaperEngine.mReqHeight = desiredHeight;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700869 onDesiredSizeChanged(desiredWidth, desiredHeight);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700870 doOffsetsChanged(true);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700871 }
872 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700873
874 void doDisplayPaddingChanged(Rect padding) {
875 if (!mDestroyed) {
876 if (DEBUG) Log.v(TAG, "onDisplayPaddingChanged(" + padding + "): " + this);
877 if (!mIWallpaperEngine.mDisplayPadding.equals(padding)) {
878 mIWallpaperEngine.mDisplayPadding.set(padding);
879 updateSurface(true, false, false);
880 }
881 }
882 }
883
Dianne Hackborn284ac932009-08-28 10:34:25 -0700884 void doVisibilityChanged(boolean visible) {
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -0800885 if (!mDestroyed) {
886 mVisible = visible;
887 reportVisibility();
888 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700889 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700890
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700891 void reportVisibility() {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700892 if (!mDestroyed) {
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700893 mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState();
894 boolean visible = mVisible && mDisplayState != Display.STATE_OFF;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700895 if (mReportedVisible != visible) {
896 mReportedVisible = visible;
897 if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
898 + "): " + this);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700899 if (visible) {
900 // If becoming visible, in preview mode the surface
901 // may have been destroyed so now we need to make
902 // sure it is re-created.
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700903 doOffsetsChanged(false);
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700904 updateSurface(false, false, false);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700905 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700906 onVisibilityChanged(visible);
907 }
Dianne Hackborn284ac932009-08-28 10:34:25 -0700908 }
909 }
910
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700911 void doOffsetsChanged(boolean always) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700912 if (mDestroyed) {
913 return;
914 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700915
916 if (!always && !mOffsetsChanged) {
917 return;
918 }
919
Dianne Hackborn284ac932009-08-28 10:34:25 -0700920 float xOffset;
921 float yOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800922 float xOffsetStep;
923 float yOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700924 boolean sync;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700925 synchronized (mLock) {
926 xOffset = mPendingXOffset;
927 yOffset = mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800928 xOffsetStep = mPendingXOffsetStep;
929 yOffsetStep = mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700930 sync = mPendingSync;
931 mPendingSync = false;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700932 mOffsetMessageEnqueued = false;
933 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700934
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700935 if (mSurfaceCreated) {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700936 if (mReportedVisible) {
937 if (DEBUG) Log.v(TAG, "Offsets change in " + this
938 + ": " + xOffset + "," + yOffset);
939 final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
940 final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
941 final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
942 final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
943 onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
944 } else {
945 mOffsetsChanged = true;
946 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700947 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700948
949 if (sync) {
950 try {
951 if (DEBUG) Log.v(TAG, "Reporting offsets change complete");
952 mSession.wallpaperOffsetsComplete(mWindow.asBinder());
953 } catch (RemoteException e) {
954 }
955 }
Dianne Hackborn284ac932009-08-28 10:34:25 -0700956 }
957
Dianne Hackborn75804932009-10-20 20:15:20 -0700958 void doCommand(WallpaperCommand cmd) {
959 Bundle result;
960 if (!mDestroyed) {
961 result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
962 cmd.extras, cmd.sync);
963 } else {
964 result = null;
965 }
966 if (cmd.sync) {
967 try {
968 if (DEBUG) Log.v(TAG, "Reporting command complete");
969 mSession.wallpaperCommandComplete(mWindow.asBinder(), result);
970 } catch (RemoteException e) {
971 }
972 }
973 }
974
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700975 void reportSurfaceDestroyed() {
976 if (mSurfaceCreated) {
977 mSurfaceCreated = false;
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700978 mSurfaceHolder.ungetCallbacks();
979 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
980 if (callbacks != null) {
981 for (SurfaceHolder.Callback c : callbacks) {
982 c.surfaceDestroyed(mSurfaceHolder);
983 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700984 }
Dianne Hackborn284ac932009-08-28 10:34:25 -0700985 if (DEBUG) Log.v(TAG, "onSurfaceDestroyed("
986 + mSurfaceHolder + "): " + this);
987 onSurfaceDestroyed(mSurfaceHolder);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700988 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700989 }
990
991 void detach() {
992 if (mDestroyed) {
993 return;
994 }
995
996 mDestroyed = true;
Jeff Brown3d110b22014-11-21 19:01:13 -0800997
998 if (mDisplayManager != null) {
999 mDisplayManager.unregisterDisplayListener(mDisplayListener);
1000 }
1001
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001002 if (mVisible) {
1003 mVisible = false;
1004 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
1005 onVisibilityChanged(false);
1006 }
1007
1008 reportSurfaceDestroyed();
Dianne Hackborn284ac932009-08-28 10:34:25 -07001009
1010 if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
1011 onDestroy();
Jeff Brown3d110b22014-11-21 19:01:13 -08001012
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001013 if (mCreated) {
1014 try {
Dianne Hackbornba3e31d2010-04-22 18:59:03 -07001015 if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
1016 + mSurfaceHolder.getSurface() + " of: " + this);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001017
Jeff Brown32cbc38552011-12-01 14:01:49 -08001018 if (mInputEventReceiver != null) {
1019 mInputEventReceiver.dispose();
1020 mInputEventReceiver = null;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001021 }
1022
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001023 mSession.remove(mWindow);
1024 } catch (RemoteException e) {
1025 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001026 mSurfaceHolder.mSurface.release();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001027 mCreated = false;
Jeff Brown349703e2010-06-22 01:27:15 -07001028
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001029 // Dispose the input channel after removing the window so the Window Manager
1030 // doesn't interpret the input channel being closed as an abnormal termination.
1031 if (mInputChannel != null) {
1032 mInputChannel.dispose();
1033 mInputChannel = null;
Jeff Brown349703e2010-06-22 01:27:15 -07001034 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001035 }
1036 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001037
1038 private final DisplayListener mDisplayListener = new DisplayListener() {
1039 @Override
1040 public void onDisplayChanged(int displayId) {
1041 if (mDisplay.getDisplayId() == displayId) {
1042 reportVisibility();
1043 }
1044 }
1045
1046 @Override
1047 public void onDisplayRemoved(int displayId) {
1048 }
1049
1050 @Override
1051 public void onDisplayAdded(int displayId) {
1052 }
1053 };
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001054 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001055
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001056 class IWallpaperEngineWrapper extends IWallpaperEngine.Stub
1057 implements HandlerCaller.Callback {
1058 private final HandlerCaller mCaller;
1059
1060 final IWallpaperConnection mConnection;
1061 final IBinder mWindowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001062 final int mWindowType;
1063 final boolean mIsPreview;
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001064 boolean mShownReported;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001065 int mReqWidth;
1066 int mReqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001067 final Rect mDisplayPadding = new Rect();
1068
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001069 Engine mEngine;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001070
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001071 IWallpaperEngineWrapper(WallpaperService context,
1072 IWallpaperConnection conn, IBinder windowToken,
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001073 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
Mita Yunaa8dc2e2012-12-10 18:32:03 -08001074 mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001075 mConnection = conn;
1076 mWindowToken = windowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001077 mWindowType = windowType;
1078 mIsPreview = isPreview;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001079 mReqWidth = reqWidth;
1080 mReqHeight = reqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001081 mDisplayPadding.set(padding);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001082
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001083 Message msg = mCaller.obtainMessage(DO_ATTACH);
1084 mCaller.sendMessage(msg);
1085 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001086
Dianne Hackborn284ac932009-08-28 10:34:25 -07001087 public void setDesiredSize(int width, int height) {
1088 Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height);
1089 mCaller.sendMessage(msg);
1090 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001091
1092 public void setDisplayPadding(Rect padding) {
1093 Message msg = mCaller.obtainMessageO(DO_SET_DISPLAY_PADDING, padding);
1094 mCaller.sendMessage(msg);
1095 }
1096
Dianne Hackborn284ac932009-08-28 10:34:25 -07001097 public void setVisibility(boolean visible) {
1098 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
1099 visible ? 1 : 0);
1100 mCaller.sendMessage(msg);
1101 }
1102
Dianne Hackborn6adba242009-11-10 11:10:09 -08001103 public void dispatchPointer(MotionEvent event) {
1104 if (mEngine != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001105 mEngine.dispatchPointer(event);
Jeff Brown32cbc38552011-12-01 14:01:49 -08001106 } else {
1107 event.recycle();
Dianne Hackborn6adba242009-11-10 11:10:09 -08001108 }
1109 }
Jeff Brown9f3bdfe2010-10-13 06:01:27 -07001110
1111 public void dispatchWallpaperCommand(String action, int x, int y,
1112 int z, Bundle extras) {
1113 if (mEngine != null) {
1114 mEngine.mWindow.dispatchWallpaperCommand(action, x, y, z, extras, false);
1115 }
1116 }
1117
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001118 public void reportShown() {
1119 if (!mShownReported) {
1120 mShownReported = true;
1121 try {
1122 mConnection.engineShown(this);
1123 } catch (RemoteException e) {
1124 Log.w(TAG, "Wallpaper host disappeared", e);
1125 return;
1126 }
1127 }
1128 }
1129
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001130 public void destroy() {
1131 Message msg = mCaller.obtainMessage(DO_DETACH);
1132 mCaller.sendMessage(msg);
1133 }
1134
1135 public void executeMessage(Message message) {
1136 switch (message.what) {
1137 case DO_ATTACH: {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001138 try {
1139 mConnection.attachEngine(this);
1140 } catch (RemoteException e) {
1141 Log.w(TAG, "Wallpaper host disappeared", e);
1142 return;
1143 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001144 Engine engine = onCreateEngine();
1145 mEngine = engine;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001146 mActiveEngines.add(engine);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001147 engine.attach(this);
1148 return;
1149 }
1150 case DO_DETACH: {
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001151 mActiveEngines.remove(mEngine);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001152 mEngine.detach();
1153 return;
1154 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001155 case DO_SET_DESIRED_SIZE: {
1156 mEngine.doDesiredSizeChanged(message.arg1, message.arg2);
1157 return;
1158 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001159 case DO_SET_DISPLAY_PADDING: {
1160 mEngine.doDisplayPaddingChanged((Rect) message.obj);
1161 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001162 case MSG_UPDATE_SURFACE:
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001163 mEngine.updateSurface(true, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001164 break;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001165 case MSG_VISIBILITY_CHANGED:
1166 if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
1167 + ": " + message.arg1);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001168 mEngine.doVisibilityChanged(message.arg1 != 0);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001169 break;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001170 case MSG_WALLPAPER_OFFSETS: {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001171 mEngine.doOffsetsChanged(true);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001172 } break;
Dianne Hackborn75804932009-10-20 20:15:20 -07001173 case MSG_WALLPAPER_COMMAND: {
1174 WallpaperCommand cmd = (WallpaperCommand)message.obj;
1175 mEngine.doCommand(cmd);
1176 } break;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001177 case MSG_WINDOW_RESIZED: {
1178 final boolean reportDraw = message.arg1 != 0;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001179 mEngine.updateSurface(true, false, reportDraw);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001180 mEngine.doOffsetsChanged(true);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001181 } break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07001182 case MSG_WINDOW_MOVED: {
1183 // Do nothing. What does it mean for a Wallpaper to move?
1184 } break;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001185 case MSG_TOUCH_EVENT: {
Jeff Brown840db1f2010-10-21 17:36:54 -07001186 boolean skip = false;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001187 MotionEvent ev = (MotionEvent)message.obj;
Jeff Brown840db1f2010-10-21 17:36:54 -07001188 if (ev.getAction() == MotionEvent.ACTION_MOVE) {
1189 synchronized (mEngine.mLock) {
1190 if (mEngine.mPendingMove == ev) {
1191 mEngine.mPendingMove = null;
1192 } else {
1193 // this is not the motion event we are looking for....
1194 skip = true;
1195 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001196 }
1197 }
Jeff Brown840db1f2010-10-21 17:36:54 -07001198 if (!skip) {
1199 if (DEBUG) Log.v(TAG, "Delivering touch event: " + ev);
1200 mEngine.onTouchEvent(ev);
1201 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001202 ev.recycle();
1203 } break;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001204 default :
1205 Log.w(TAG, "Unknown message type " + message.what);
1206 }
1207 }
1208 }
1209
1210 /**
1211 * Implements the internal {@link IWallpaperService} interface to convert
1212 * incoming calls to it back to calls on an {@link WallpaperService}.
1213 */
1214 class IWallpaperServiceWrapper extends IWallpaperService.Stub {
1215 private final WallpaperService mTarget;
1216
1217 public IWallpaperServiceWrapper(WallpaperService context) {
1218 mTarget = context;
1219 }
1220
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001221 @Override
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001222 public void attach(IWallpaperConnection conn, IBinder windowToken,
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001223 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001224 new IWallpaperEngineWrapper(mTarget, conn, windowToken,
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001225 windowType, isPreview, reqWidth, reqHeight, padding);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001226 }
1227 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001228
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001229 @Override
1230 public void onCreate() {
1231 super.onCreate();
1232 }
1233
1234 @Override
1235 public void onDestroy() {
1236 super.onDestroy();
1237 for (int i=0; i<mActiveEngines.size(); i++) {
1238 mActiveEngines.get(i).detach();
1239 }
1240 mActiveEngines.clear();
1241 }
1242
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001243 /**
1244 * Implement to return the implementation of the internal accessibility
1245 * service interface. Subclasses should not override.
1246 */
1247 @Override
1248 public final IBinder onBind(Intent intent) {
1249 return new IWallpaperServiceWrapper(this);
1250 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001251
Dianne Hackborn23ef7b42009-11-18 18:20:39 -08001252 /**
1253 * Must be implemented to return a new instance of the wallpaper's engine.
1254 * Note that multiple instances may be active at the same time, such as
1255 * when the wallpaper is currently set as the active wallpaper and the user
1256 * is in the wallpaper picker viewing a preview of it as well.
1257 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001258 public abstract Engine onCreateEngine();
Dianne Hackborn527de8e2011-08-22 16:10:36 -07001259
1260 @Override
1261 protected void dump(FileDescriptor fd, PrintWriter out, String[] args) {
1262 out.print("State of wallpaper "); out.print(this); out.println(":");
1263 for (int i=0; i<mActiveEngines.size(); i++) {
1264 Engine engine = mActiveEngines.get(i);
1265 out.print(" Engine "); out.print(engine); out.println(":");
1266 engine.dump(" ", fd, out, args);
1267 }
1268 }
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001269}