blob: 3b436cdb985e50cc46797659c2d20b570e84d4fa [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
Lucas Dupinc40608c2017-04-14 18:33:08 -070019import android.annotation.Nullable;
Dianne Hackbornd6847842010-01-12 18:14:19 -080020import android.annotation.SdkConstant;
21import android.annotation.SdkConstant.SdkConstantType;
Mathew Inwoodd237a742018-08-10 09:58:47 +010022import android.annotation.UnsupportedAppUsage;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070023import android.app.Service;
Lucas Dupin84b89d92017-05-09 12:16:19 -070024import android.app.WallpaperColors;
Dianne Hackborn759a39e2009-08-09 17:20:27 -070025import android.app.WallpaperManager;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070026import android.content.Context;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070027import android.content.Intent;
Lucas Dupin84b89d92017-05-09 12:16:19 -070028import android.content.res.TypedArray;
29import android.graphics.Bitmap;
30import android.graphics.Canvas;
Mathias Agopian62bf4a02010-09-08 16:32:27 -070031import android.graphics.PixelFormat;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070032import android.graphics.Rect;
Lucas Dupin84b89d92017-05-09 12:16:19 -070033import android.graphics.drawable.Drawable;
Jeff Brown3d110b22014-11-21 19:01:13 -080034import android.hardware.display.DisplayManager;
35import android.hardware.display.DisplayManager.DisplayListener;
Mathew Inwood55418ea2018-12-20 15:30:45 +000036import android.os.Build;
Dianne Hackborn75804932009-10-20 20:15:20 -070037import android.os.Bundle;
Lucas Dupin65b47652017-07-19 17:32:26 -070038import android.os.Handler;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070039import android.os.IBinder;
Dianne Hackborn19382ac2009-09-11 21:13:37 -070040import android.os.Looper;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070041import android.os.Message;
42import android.os.RemoteException;
Lucas Dupin65b47652017-07-19 17:32:26 -070043import android.os.SystemClock;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070044import android.util.Log;
Lucas Dupin84b89d92017-05-09 12:16:19 -070045import android.util.MergedConfiguration;
Craig Mautner6881a102012-07-27 13:04:51 -070046import android.view.Display;
Adrian Roos5c6b6222017-11-07 17:36:10 +010047import android.view.DisplayCutout;
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;
Lucas Dupin84b89d92017-05-09 12:16:19 -070058import android.view.WindowInsets;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070059import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -070060import android.view.WindowManagerGlobal;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070061
Lucas Dupin65b47652017-07-19 17:32:26 -070062import com.android.internal.annotations.VisibleForTesting;
Lucas Dupin84b89d92017-05-09 12:16:19 -070063import com.android.internal.os.HandlerCaller;
64import com.android.internal.view.BaseIWindow;
65import com.android.internal.view.BaseSurfaceHolder;
66
Dianne Hackborn527de8e2011-08-22 16:10:36 -070067import java.io.FileDescriptor;
68import java.io.PrintWriter;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -080069import java.util.ArrayList;
Lucas Dupin65b47652017-07-19 17:32:26 -070070import java.util.function.Supplier;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -080071
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070072/**
73 * A wallpaper service is responsible for showing a live wallpaper behind
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080074 * applications that would like to sit on top of it. This service object
75 * itself does very little -- its only purpose is to generate instances of
Dianne Hackborne4260f42009-11-18 21:15:59 -080076 * {@link Engine} as needed. Implementing a wallpaper thus
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080077 * involves subclassing from this, subclassing an Engine implementation,
78 * and implementing {@link #onCreateEngine()} to return a new instance of
79 * your engine.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070080 */
81public abstract class WallpaperService extends Service {
82 /**
83 * The {@link Intent} that must be declared as handled by the service.
Dianne Hackbornd6847842010-01-12 18:14:19 -080084 * To be supported, the service must also require the
85 * {@link android.Manifest.permission#BIND_WALLPAPER} permission so
86 * that other applications can not abuse it.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070087 */
Dianne Hackbornd6847842010-01-12 18:14:19 -080088 @SdkConstant(SdkConstantType.SERVICE_ACTION)
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070089 public static final String SERVICE_INTERFACE =
Dianne Hackbornd6847842010-01-12 18:14:19 -080090 "android.service.wallpaper.WallpaperService";
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070091
Dianne Hackborneb034652009-09-07 00:49:58 -070092 /**
93 * Name under which a WallpaperService component publishes information
94 * about itself. This meta-data must reference an XML resource containing
95 * a <code>&lt;{@link android.R.styleable#Wallpaper wallpaper}&gt;</code>
96 * tag.
97 */
98 public static final String SERVICE_META_DATA = "android.service.wallpaper";
Craig Mautnerb1ef3692012-11-16 17:31:04 -080099
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700100 static final String TAG = "WallpaperService";
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700101 static final boolean DEBUG = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700102
103 private static final int DO_ATTACH = 10;
104 private static final int DO_DETACH = 20;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700105 private static final int DO_SET_DESIRED_SIZE = 30;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700106 private static final int DO_SET_DISPLAY_PADDING = 40;
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700107 private static final int DO_IN_AMBIENT_MODE = 50;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700108
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700109 private static final int MSG_UPDATE_SURFACE = 10000;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700110 private static final int MSG_VISIBILITY_CHANGED = 10010;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700111 private static final int MSG_WALLPAPER_OFFSETS = 10020;
Dianne Hackborn75804932009-10-20 20:15:20 -0700112 private static final int MSG_WALLPAPER_COMMAND = 10025;
Mathew Inwoodd237a742018-08-10 09:58:47 +0100113 @UnsupportedAppUsage
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700114 private static final int MSG_WINDOW_RESIZED = 10030;
Craig Mautner5702d4d2012-06-30 14:10:16 -0700115 private static final int MSG_WINDOW_MOVED = 10035;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700116 private static final int MSG_TOUCH_EVENT = 10040;
Lucas Dupin50ba9912017-07-14 11:55:05 -0700117 private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
Lucas Dupin65b47652017-07-19 17:32:26 -0700118
119 private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
120
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -0800121 private final ArrayList<Engine> mActiveEngines
122 = new ArrayList<Engine>();
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700123
Dianne Hackborn75804932009-10-20 20:15:20 -0700124 static final class WallpaperCommand {
125 String action;
126 int x;
127 int y;
128 int z;
129 Bundle extras;
130 boolean sync;
131 }
132
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700133 /**
134 * The actual implementation of a wallpaper. A wallpaper service may
135 * have multiple instances running (for example as a real wallpaper
136 * and as a preview), each of which is represented by its own Engine
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700137 * instance. You must implement {@link WallpaperService#onCreateEngine()}
138 * to return your concrete Engine implementation.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700139 */
140 public class Engine {
141 IWallpaperEngineWrapper mIWallpaperEngine;
142
143 // Copies from mIWallpaperEngine.
144 HandlerCaller mCaller;
145 IWallpaperConnection mConnection;
146 IBinder mWindowToken;
147
148 boolean mInitializing = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700149 boolean mVisible;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700150 boolean mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700151 boolean mDestroyed;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700152
153 // Current window state.
154 boolean mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700155 boolean mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700156 boolean mIsCreating;
157 boolean mDrawingAllowed;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700158 boolean mOffsetsChanged;
Jeff Sharkey35be7562012-04-18 19:16:15 -0700159 boolean mFixedSizeAllowed;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700160 int mWidth;
161 int mHeight;
162 int mFormat;
163 int mType;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700164 int mCurWidth;
165 int mCurHeight;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700166 int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700167 int mWindowPrivateFlags =
168 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700169 int mCurWindowFlags = mWindowFlags;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700170 int mCurWindowPrivateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700171 final Rect mVisibleInsets = new Rect();
172 final Rect mWinFrame = new Rect();
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800173 final Rect mOverscanInsets = new Rect();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700174 final Rect mContentInsets = new Rect();
Adrian Roosfa104232014-06-20 16:10:14 -0700175 final Rect mStableInsets = new Rect();
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700176 final Rect mOutsets = new Rect();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700177 final Rect mDispatchedOverscanInsets = new Rect();
178 final Rect mDispatchedContentInsets = new Rect();
179 final Rect mDispatchedStableInsets = new Rect();
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700180 final Rect mDispatchedOutsets = new Rect();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700181 final Rect mFinalSystemInsets = new Rect();
182 final Rect mFinalStableInsets = new Rect();
Jorim Jaggi2e95a482016-01-14 17:36:55 -0800183 final Rect mBackdropFrame = new Rect();
Adrian Roos5c6b6222017-11-07 17:36:10 +0100184 final DisplayCutout.ParcelableWrapper mDisplayCutout =
185 new DisplayCutout.ParcelableWrapper();
186 DisplayCutout mDispatchedDisplayCutout = DisplayCutout.NO_CUTOUT;
Andrii Kulian44607962017-03-16 11:06:24 -0700187 final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700188
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700189 final WindowManager.LayoutParams mLayout
190 = new WindowManager.LayoutParams();
191 IWindowSession mSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700192 InputChannel mInputChannel;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700193
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700194 final Object mLock = new Object();
195 boolean mOffsetMessageEnqueued;
Mathew Inwood55418ea2018-12-20 15:30:45 +0000196 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700197 float mPendingXOffset;
198 float mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800199 float mPendingXOffsetStep;
200 float mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700201 boolean mPendingSync;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700202 MotionEvent mPendingMove;
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700203 boolean mIsInAmbientMode;
Jeff Brown3d110b22014-11-21 19:01:13 -0800204
Lucas Dupin65b47652017-07-19 17:32:26 -0700205 // Needed for throttling onComputeColors.
206 private long mLastColorInvalidation;
207 private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
Lucas Dupin416fe952017-08-14 10:58:40 -0700208 private final Supplier<Long> mClockFunction;
209 private final Handler mHandler;
Lucas Dupin65b47652017-07-19 17:32:26 -0700210
Jeff Brown3d110b22014-11-21 19:01:13 -0800211 DisplayManager mDisplayManager;
212 Display mDisplay;
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700213 private int mDisplayState;
Jeff Brown3d110b22014-11-21 19:01:13 -0800214
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700215 final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700216 {
Jeff Brown24572372011-06-09 19:05:15 -0700217 mRequestedFormat = PixelFormat.RGBX_8888;
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700218 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700219
220 @Override
221 public boolean onAllowLockCanvas() {
222 return mDrawingAllowed;
223 }
224
225 @Override
226 public void onRelayoutContainer() {
227 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
228 mCaller.sendMessage(msg);
229 }
230
231 @Override
232 public void onUpdateSurface() {
233 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
234 mCaller.sendMessage(msg);
235 }
236
237 public boolean isCreating() {
238 return mIsCreating;
239 }
240
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800241 @Override
242 public void setFixedSize(int width, int height) {
Jeff Sharkey35be7562012-04-18 19:16:15 -0700243 if (!mFixedSizeAllowed) {
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800244 // Regular apps can't do this. It can only work for
245 // certain designs of window animations, so you can't
246 // rely on it.
247 throw new UnsupportedOperationException(
248 "Wallpapers currently only support sizing from layout");
249 }
Michael Jurkab8f939f2011-02-01 20:50:30 -0800250 super.setFixedSize(width, height);
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800251 }
252
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700253 public void setKeepScreenOn(boolean screenOn) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700254 throw new UnsupportedOperationException(
255 "Wallpapers do not support keep screen on");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700256 }
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700257
John Reck6bc70142016-10-26 16:49:17 -0700258 private void prepareToDraw() {
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700259 if (mDisplayState == Display.STATE_DOZE
260 || mDisplayState == Display.STATE_DOZE_SUSPEND) {
261 try {
262 mSession.pokeDrawLock(mWindow);
263 } catch (RemoteException e) {
264 // System server died, can be ignored.
265 }
266 }
John Reck6bc70142016-10-26 16:49:17 -0700267 }
268
269 @Override
270 public Canvas lockCanvas() {
271 prepareToDraw();
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700272 return super.lockCanvas();
273 }
John Reck6bc70142016-10-26 16:49:17 -0700274
275 @Override
276 public Canvas lockCanvas(Rect dirty) {
277 prepareToDraw();
278 return super.lockCanvas(dirty);
279 }
280
281 @Override
282 public Canvas lockHardwareCanvas() {
283 prepareToDraw();
284 return super.lockHardwareCanvas();
285 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700286 };
Jeff Brown32cbc38552011-12-01 14:01:49 -0800287
288 final class WallpaperInputEventReceiver extends InputEventReceiver {
289 public WallpaperInputEventReceiver(InputChannel inputChannel, Looper looper) {
290 super(inputChannel, looper);
291 }
292
Jeff Brown46b9ac02010-04-22 18:58:52 -0700293 @Override
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700294 public void onInputEvent(InputEvent event, int displayId) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700295 boolean handled = false;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700296 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800297 if (event instanceof MotionEvent
298 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800299 MotionEvent dup = MotionEvent.obtainNoHistory((MotionEvent)event);
300 dispatchPointer(dup);
Jeff Brown3915bb82010-11-05 15:02:16 -0700301 handled = true;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700302 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700303 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800304 finishInputEvent(event, handled);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700305 }
306 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800307 }
308 WallpaperInputEventReceiver mInputEventReceiver;
309
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700310 final BaseIWindow mWindow = new BaseIWindow() {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700311 @Override
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800312 public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700313 Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Andrii Kulian44607962017-03-16 11:06:24 -0700314 MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout,
Adrian Roos5c6b6222017-11-07 17:36:10 +0100315 boolean alwaysConsumeNavBar, int displayId,
316 DisplayCutout.ParcelableWrapper displayCutout) {
Filip Gruszczynski03850592015-07-01 08:35:28 -0700317 Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED,
318 reportDraw ? 1 : 0, outsets);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700319 mCaller.sendMessage(msg);
320 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700321
322 @Override
323 public void moved(int newX, int newY) {
324 Message msg = mCaller.obtainMessageII(MSG_WINDOW_MOVED, newX, newY);
325 mCaller.sendMessage(msg);
326 }
327
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700328 @Override
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700329 public void dispatchAppVisibility(boolean visible) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700330 // We don't do this in preview mode; we'll let the preview
331 // activity tell us when to run.
332 if (!mIWallpaperEngine.mIsPreview) {
333 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
334 visible ? 1 : 0);
335 mCaller.sendMessage(msg);
336 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700337 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700338
339 @Override
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800340 public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
341 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700342 synchronized (mLock) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700343 if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700344 mPendingXOffset = x;
345 mPendingYOffset = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800346 mPendingXOffsetStep = xStep;
347 mPendingYOffsetStep = yStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700348 if (sync) {
349 mPendingSync = true;
350 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700351 if (!mOffsetMessageEnqueued) {
352 mOffsetMessageEnqueued = true;
353 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
354 mCaller.sendMessage(msg);
355 }
356 }
357 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700358
359 @Override
Dianne Hackborn75804932009-10-20 20:15:20 -0700360 public void dispatchWallpaperCommand(String action, int x, int y,
361 int z, Bundle extras, boolean sync) {
362 synchronized (mLock) {
363 if (DEBUG) Log.v(TAG, "Dispatch wallpaper command: " + x + ", " + y);
364 WallpaperCommand cmd = new WallpaperCommand();
365 cmd.action = action;
366 cmd.x = x;
367 cmd.y = y;
368 cmd.z = z;
369 cmd.extras = extras;
370 cmd.sync = sync;
371 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_COMMAND);
372 msg.obj = cmd;
373 mCaller.sendMessage(msg);
374 }
375 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700376 };
Lucas Dupin416fe952017-08-14 10:58:40 -0700377
378 /**
379 * Default constructor
380 */
381 public Engine() {
382 this(SystemClock::elapsedRealtime, Handler.getMain());
383 }
384
385 /**
386 * Constructor used for test purposes.
387 *
388 * @param clockFunction Supplies current times in millis.
389 * @param handler Used for posting/deferring asynchronous calls.
390 * @hide
391 */
392 @VisibleForTesting
393 public Engine(Supplier<Long> clockFunction, Handler handler) {
394 mClockFunction = clockFunction;
395 mHandler = handler;
396 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700397
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700398 /**
399 * Provides access to the surface in which this wallpaper is drawn.
400 */
401 public SurfaceHolder getSurfaceHolder() {
402 return mSurfaceHolder;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700403 }
404
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700405 /**
406 * Convenience for {@link WallpaperManager#getDesiredMinimumWidth()
407 * WallpaperManager.getDesiredMinimumWidth()}, returning the width
408 * that the system would like this wallpaper to run in.
409 */
410 public int getDesiredMinimumWidth() {
411 return mIWallpaperEngine.mReqWidth;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700412 }
413
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700414 /**
415 * Convenience for {@link WallpaperManager#getDesiredMinimumHeight()
416 * WallpaperManager.getDesiredMinimumHeight()}, returning the height
417 * that the system would like this wallpaper to run in.
418 */
419 public int getDesiredMinimumHeight() {
420 return mIWallpaperEngine.mReqHeight;
421 }
422
423 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700424 * Return whether the wallpaper is currently visible to the user,
425 * this is the last value supplied to
426 * {@link #onVisibilityChanged(boolean)}.
427 */
428 public boolean isVisible() {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700429 return mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700430 }
431
432 /**
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700433 * Returns true if this engine is running in preview mode -- that is,
434 * it is being shown to the user before they select it as the actual
435 * wallpaper.
436 */
437 public boolean isPreview() {
438 return mIWallpaperEngine.mIsPreview;
439 }
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700440
441 /**
442 * Returns true if this engine is running in ambient mode -- that is,
443 * it is being shown in low power mode, in always on display.
444 * @hide
445 */
446 public boolean isInAmbientMode() {
447 return mIsInAmbientMode;
448 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700449
450 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700451 * Control whether this wallpaper will receive raw touch events
452 * from the window manager as the user interacts with the window
453 * that is currently displaying the wallpaper. By default they
454 * are turned off. If enabled, the events will be received in
455 * {@link #onTouchEvent(MotionEvent)}.
456 */
457 public void setTouchEventsEnabled(boolean enabled) {
458 mWindowFlags = enabled
459 ? (mWindowFlags&~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
460 : (mWindowFlags|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
461 if (mCreated) {
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700462 updateSurface(false, false, false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700463 }
464 }
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700465
466 /**
467 * Control whether this wallpaper will receive notifications when the wallpaper
468 * has been scrolled. By default, wallpapers will receive notifications, although
469 * the default static image wallpapers do not. It is a performance optimization to
470 * set this to false.
471 *
472 * @param enabled whether the wallpaper wants to receive offset notifications
473 */
474 public void setOffsetNotificationsEnabled(boolean enabled) {
475 mWindowPrivateFlags = enabled
476 ? (mWindowPrivateFlags |
477 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS)
478 : (mWindowPrivateFlags &
479 ~WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS);
480 if (mCreated) {
481 updateSurface(false, false, false);
482 }
483 }
Jeff Sharkey35be7562012-04-18 19:16:15 -0700484
485 /** {@hide} */
Mathew Inwoodd237a742018-08-10 09:58:47 +0100486 @UnsupportedAppUsage
Jeff Sharkey35be7562012-04-18 19:16:15 -0700487 public void setFixedSizeAllowed(boolean allowed) {
488 mFixedSizeAllowed = allowed;
489 }
490
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700491 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700492 * Called once to initialize the engine. After returning, the
493 * engine's surface will be created by the framework.
494 */
495 public void onCreate(SurfaceHolder surfaceHolder) {
496 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700497
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700498 /**
499 * Called right before the engine is going away. After this the
500 * surface will be destroyed and this Engine object is no longer
501 * valid.
502 */
503 public void onDestroy() {
504 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700505
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700506 /**
507 * Called to inform you of the wallpaper becoming visible or
508 * hidden. <em>It is very important that a wallpaper only use
509 * CPU while it is visible.</em>.
510 */
511 public void onVisibilityChanged(boolean visible) {
512 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700513
514 /**
515 * Called with the current insets that are in effect for the wallpaper.
516 * This gives you the part of the overall wallpaper surface that will
517 * generally be visible to the user (ignoring position offsets applied to it).
518 *
519 * @param insets Insets to apply.
520 */
521 public void onApplyWindowInsets(WindowInsets insets) {
522 }
523
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700524 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700525 * Called as the user performs touch-screen interaction with the
526 * window that is currently showing this wallpaper. Note that the
527 * events you receive here are driven by the actual application the
Marco Nelissenae87bd02009-09-17 09:44:43 -0700528 * user is interacting with, so if it is slow you will get fewer
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700529 * move events.
530 */
531 public void onTouchEvent(MotionEvent event) {
532 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700533
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700534 /**
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700535 * Called to inform you of the wallpaper's offsets changing
536 * within its contain, corresponding to the container's
537 * call to {@link WallpaperManager#setWallpaperOffsets(IBinder, float, float)
538 * WallpaperManager.setWallpaperOffsets()}.
539 */
540 public void onOffsetsChanged(float xOffset, float yOffset,
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800541 float xOffsetStep, float yOffsetStep,
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700542 int xPixelOffset, int yPixelOffset) {
543 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700544
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700545 /**
Dianne Hackborn75804932009-10-20 20:15:20 -0700546 * Process a command that was sent to the wallpaper with
Dianne Hackborn13bf82602009-11-05 21:45:51 -0800547 * {@link WallpaperManager#sendWallpaperCommand}.
Dianne Hackborn75804932009-10-20 20:15:20 -0700548 * The default implementation does nothing, and always returns null
549 * as the result.
550 *
551 * @param action The name of the command to perform. This tells you
552 * what to do and how to interpret the rest of the arguments.
553 * @param x Generic integer parameter.
554 * @param y Generic integer parameter.
555 * @param z Generic integer parameter.
556 * @param extras Any additional parameters.
557 * @param resultRequested If true, the caller is requesting that
558 * a result, appropriate for the command, be returned back.
559 * @return If returning a result, create a Bundle and place the
560 * result data in to it. Otherwise return null.
561 */
562 public Bundle onCommand(String action, int x, int y, int z,
563 Bundle extras, boolean resultRequested) {
564 return null;
565 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700566
Dianne Hackborn75804932009-10-20 20:15:20 -0700567 /**
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700568 * Called when the device enters or exits ambient mode.
569 *
570 * @param inAmbientMode {@code true} if in ambient mode.
Lucas Dupin660d5732017-12-19 10:05:19 -0800571 * @param animated {@code true} if you'll have te opportunity of animating your transition
572 * {@code false} when the screen will blank and the wallpaper should be
573 * set to ambient mode immediately.
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700574 * @hide
575 */
Lucas Dupin660d5732017-12-19 10:05:19 -0800576 public void onAmbientModeChanged(boolean inAmbientMode, boolean animated) {
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700577 }
578
579 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700580 * Called when an application has changed the desired virtual size of
581 * the wallpaper.
582 */
583 public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
584 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700585
Dianne Hackborn284ac932009-08-28 10:34:25 -0700586 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700587 * Convenience for {@link SurfaceHolder.Callback#surfaceChanged
588 * SurfaceHolder.Callback.surfaceChanged()}.
589 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700590 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
591 }
592
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700593 /**
Dianne Hackborn1d28f9c2010-07-13 20:38:06 -0700594 * Convenience for {@link SurfaceHolder.Callback2#surfaceRedrawNeeded
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700595 * SurfaceHolder.Callback.surfaceRedrawNeeded()}.
596 */
597 public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
598 }
599
600 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700601 * Convenience for {@link SurfaceHolder.Callback#surfaceCreated
602 * SurfaceHolder.Callback.surfaceCreated()}.
603 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700604 public void onSurfaceCreated(SurfaceHolder holder) {
605 }
606
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700607 /**
608 * Convenience for {@link SurfaceHolder.Callback#surfaceDestroyed
609 * SurfaceHolder.Callback.surfaceDestroyed()}.
610 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700611 public void onSurfaceDestroyed(SurfaceHolder holder) {
612 }
Lucas Dupinc40608c2017-04-14 18:33:08 -0700613
614 /**
615 * Notifies the engine that wallpaper colors changed significantly.
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700616 * This will trigger a {@link #onComputeColors()} call.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700617 */
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700618 public void notifyColorsChanged() {
Lucas Dupin65b47652017-07-19 17:32:26 -0700619 final long now = mClockFunction.get();
Lucas Dupin65b47652017-07-19 17:32:26 -0700620 if (now - mLastColorInvalidation < NOTIFY_COLORS_RATE_LIMIT_MS) {
621 Log.w(TAG, "This call has been deferred. You should only call "
622 + "notifyColorsChanged() once every "
623 + (NOTIFY_COLORS_RATE_LIMIT_MS / 1000f) + " seconds.");
Lucas Dupin416fe952017-08-14 10:58:40 -0700624 if (!mHandler.hasCallbacks(mNotifyColorsChanged)) {
625 mHandler.postDelayed(mNotifyColorsChanged, NOTIFY_COLORS_RATE_LIMIT_MS);
Lucas Dupin65b47652017-07-19 17:32:26 -0700626 }
627 return;
628 }
629 mLastColorInvalidation = now;
Lucas Dupin416fe952017-08-14 10:58:40 -0700630 mHandler.removeCallbacks(mNotifyColorsChanged);
Lucas Dupin65b47652017-07-19 17:32:26 -0700631
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700632 try {
Lucas Dupin65b47652017-07-19 17:32:26 -0700633 final WallpaperColors newColors = onComputeColors();
634 if (mConnection != null) {
635 mConnection.onWallpaperColorsChanged(newColors);
636 } else {
637 Log.w(TAG, "Can't notify system because wallpaper connection "
638 + "was not established.");
639 }
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700640 } catch (RemoteException e) {
Lucas Dupin65b47652017-07-19 17:32:26 -0700641 Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700642 }
Lucas Dupinc40608c2017-04-14 18:33:08 -0700643 }
644
645 /**
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700646 * Called by the system when it needs to know what colors the wallpaper is using.
Lucas Dupin65b47652017-07-19 17:32:26 -0700647 * You might return null if no color information is available at the moment.
648 * In that case you might want to call {@link #notifyColorsChanged()} when
649 * color information becomes available.
Lucas Dupin84b89d92017-05-09 12:16:19 -0700650 * <p>
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700651 * The simplest way of creating a {@link android.app.WallpaperColors} object is by using
Lucas Dupin84b89d92017-05-09 12:16:19 -0700652 * {@link android.app.WallpaperColors#fromBitmap(Bitmap)} or
653 * {@link android.app.WallpaperColors#fromDrawable(Drawable)}, but you can also specify
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700654 * your main colors by constructing a {@link android.app.WallpaperColors} object manually.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700655 *
Lucas Dupin84b89d92017-05-09 12:16:19 -0700656 * @return Wallpaper colors.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700657 */
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700658 public @Nullable WallpaperColors onComputeColors() {
Lucas Dupinc40608c2017-04-14 18:33:08 -0700659 return null;
660 }
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700661
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700662 /**
663 * Sets internal engine state. Only for testing.
664 * @param created {@code true} or {@code false}.
665 * @hide
666 */
667 @VisibleForTesting
668 public void setCreated(boolean created) {
669 mCreated = created;
670 }
671
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700672 protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
673 out.print(prefix); out.print("mInitializing="); out.print(mInitializing);
674 out.print(" mDestroyed="); out.println(mDestroyed);
675 out.print(prefix); out.print("mVisible="); out.print(mVisible);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700676 out.print(" mReportedVisible="); out.println(mReportedVisible);
Jeff Brown3d110b22014-11-21 19:01:13 -0800677 out.print(prefix); out.print("mDisplay="); out.println(mDisplay);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700678 out.print(prefix); out.print("mCreated="); out.print(mCreated);
679 out.print(" mSurfaceCreated="); out.print(mSurfaceCreated);
680 out.print(" mIsCreating="); out.print(mIsCreating);
681 out.print(" mDrawingAllowed="); out.println(mDrawingAllowed);
682 out.print(prefix); out.print("mWidth="); out.print(mWidth);
683 out.print(" mCurWidth="); out.print(mCurWidth);
684 out.print(" mHeight="); out.print(mHeight);
685 out.print(" mCurHeight="); out.println(mCurHeight);
686 out.print(prefix); out.print("mType="); out.print(mType);
687 out.print(" mWindowFlags="); out.print(mWindowFlags);
688 out.print(" mCurWindowFlags="); out.println(mCurWindowFlags);
Dianne Hackbornd052a942014-11-21 15:23:13 -0800689 out.print(prefix); out.print("mWindowPrivateFlags="); out.print(mWindowPrivateFlags);
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700690 out.print(" mCurWindowPrivateFlags="); out.println(mCurWindowPrivateFlags);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700691 out.print(prefix); out.print("mVisibleInsets=");
692 out.print(mVisibleInsets.toShortString());
693 out.print(" mWinFrame="); out.print(mWinFrame.toShortString());
694 out.print(" mContentInsets="); out.println(mContentInsets.toShortString());
Andrii Kulian44607962017-03-16 11:06:24 -0700695 out.print(prefix); out.print("mConfiguration=");
696 out.println(mMergedConfiguration.getMergedConfiguration());
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700697 out.print(prefix); out.print("mLayout="); out.println(mLayout);
698 synchronized (mLock) {
699 out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
700 out.print(" mPendingXOffset="); out.println(mPendingXOffset);
701 out.print(prefix); out.print("mPendingXOffsetStep=");
702 out.print(mPendingXOffsetStep);
703 out.print(" mPendingXOffsetStep="); out.println(mPendingXOffsetStep);
704 out.print(prefix); out.print("mOffsetMessageEnqueued=");
705 out.print(mOffsetMessageEnqueued);
706 out.print(" mPendingSync="); out.println(mPendingSync);
707 if (mPendingMove != null) {
708 out.print(prefix); out.print("mPendingMove="); out.println(mPendingMove);
709 }
710 }
711 }
712
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700713 private void dispatchPointer(MotionEvent event) {
Jeff Brown33bbfd22011-02-24 20:55:35 -0800714 if (event.isTouchEvent()) {
715 synchronized (mLock) {
716 if (event.getAction() == MotionEvent.ACTION_MOVE) {
717 mPendingMove = event;
718 } else {
719 mPendingMove = null;
720 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700721 }
Jeff Brown33bbfd22011-02-24 20:55:35 -0800722 Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
723 mCaller.sendMessage(msg);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700724 } else {
725 event.recycle();
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700726 }
727 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700728
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700729 void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700730 if (mDestroyed) {
731 Log.w(TAG, "Ignoring updateSurface: destroyed");
732 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700733
734 boolean fixedSize = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700735 int myWidth = mSurfaceHolder.getRequestedWidth();
Romain Guy980a9382010-01-08 15:06:28 -0800736 if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700737 else fixedSize = true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700738 int myHeight = mSurfaceHolder.getRequestedHeight();
Romain Guy980a9382010-01-08 15:06:28 -0800739 if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700740 else fixedSize = true;
741
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700742 final boolean creating = !mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700743 final boolean surfaceCreating = !mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700744 final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700745 boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700746 boolean insetsChanged = !mCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700747 final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700748 final boolean flagsChanged = mCurWindowFlags != mWindowFlags ||
749 mCurWindowPrivateFlags != mWindowPrivateFlags;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700750 if (forceRelayout || creating || surfaceCreating || formatChanged || sizeChanged
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -0700751 || typeChanged || flagsChanged || redrawNeeded
752 || !mIWallpaperEngine.mShownReported) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700753
Dianne Hackborn284ac932009-08-28 10:34:25 -0700754 if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700755 + " format=" + formatChanged + " size=" + sizeChanged);
756
757 try {
758 mWidth = myWidth;
759 mHeight = myHeight;
760 mFormat = mSurfaceHolder.getRequestedFormat();
761 mType = mSurfaceHolder.getRequestedType();
762
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700763 mLayout.x = 0;
764 mLayout.y = 0;
765 mLayout.width = myWidth;
766 mLayout.height = myHeight;
767
768 mLayout.format = mFormat;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700769
770 mCurWindowFlags = mWindowFlags;
771 mLayout.flags = mWindowFlags
772 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
Jorim Jaggi526505d2016-05-24 00:29:19 -0700773 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700774 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
Jorim Jaggi526505d2016-05-24 00:29:19 -0700775 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700776 mCurWindowPrivateFlags = mWindowPrivateFlags;
777 mLayout.privateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700778
779 mLayout.memoryType = mType;
780 mLayout.token = mWindowToken;
781
782 if (!mCreated) {
Filip Gruszczynskid66ba062015-03-23 12:59:02 -0700783 // Retrieve watch round info
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700784 TypedArray windowStyle = obtainStyledAttributes(
785 com.android.internal.R.styleable.Window);
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700786 windowStyle.recycle();
787
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700788 // Add window
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700789 mLayout.type = mIWallpaperEngine.mWindowType;
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -0700790 mLayout.gravity = Gravity.START|Gravity.TOP;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -0700791 mLayout.setTitle(WallpaperService.this.getClass().getName());
Dianne Hackborn284ac932009-08-28 10:34:25 -0700792 mLayout.windowAnimations =
793 com.android.internal.R.style.Animation_Wallpaper;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700794 mInputChannel = new InputChannel();
Craig Mautner6881a102012-07-27 13:04:51 -0700795 if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE,
Adrian Roos9e370f22018-03-06 18:19:45 +0100796 Display.DEFAULT_DISPLAY, mWinFrame, mContentInsets, mStableInsets,
797 mOutsets, mDisplayCutout, mInputChannel) < 0) {
Mattias Peterssond9463f52011-01-12 15:38:55 +0100798 Log.w(TAG, "Failed to add window while updating wallpaper surface.");
799 return;
800 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700801 mCreated = true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700802
Jeff Brown32cbc38552011-12-01 14:01:49 -0800803 mInputEventReceiver = new WallpaperInputEventReceiver(
804 mInputChannel, Looper.myLooper());
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700805 }
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700806
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700807 mSurfaceHolder.mSurfaceLock.lock();
808 mDrawingAllowed = true;
809
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700810 if (!fixedSize) {
811 mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700812 mLayout.surfaceInsets.left += mOutsets.left;
813 mLayout.surfaceInsets.top += mOutsets.top;
814 mLayout.surfaceInsets.right += mOutsets.right;
815 mLayout.surfaceInsets.bottom += mOutsets.bottom;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700816 } else {
817 mLayout.surfaceInsets.set(0, 0, 0, 0);
818 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700819 final int relayoutResult = mSession.relayout(
Dianne Hackborn9a230e02011-10-06 11:51:27 -0700820 mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
chaviwbe43ac82018-04-04 15:14:49 -0700821 View.VISIBLE, 0, -1, mWinFrame, mOverscanInsets, mContentInsets,
Jorim Jaggi2e95a482016-01-14 17:36:55 -0800822 mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
Adrian Roos5c6b6222017-11-07 17:36:10 +0100823 mDisplayCutout, mMergedConfiguration, mSurfaceHolder.mSurface);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700824
Dianne Hackborn284ac932009-08-28 10:34:25 -0700825 if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700826 + ", frame=" + mWinFrame);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700827
Adrian Roos2ae38052014-12-09 17:03:01 +0000828 int w = mWinFrame.width();
829 int h = mWinFrame.height();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700830
831 if (!fixedSize) {
832 final Rect padding = mIWallpaperEngine.mDisplayPadding;
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700833 w += padding.left + padding.right + mOutsets.left + mOutsets.right;
834 h += padding.top + padding.bottom + mOutsets.top + mOutsets.bottom;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700835 mOverscanInsets.left += padding.left;
836 mOverscanInsets.top += padding.top;
837 mOverscanInsets.right += padding.right;
838 mOverscanInsets.bottom += padding.bottom;
839 mContentInsets.left += padding.left;
840 mContentInsets.top += padding.top;
841 mContentInsets.right += padding.right;
842 mContentInsets.bottom += padding.bottom;
843 mStableInsets.left += padding.left;
844 mStableInsets.top += padding.top;
845 mStableInsets.right += padding.right;
846 mStableInsets.bottom += padding.bottom;
Adrian Roos5c6b6222017-11-07 17:36:10 +0100847 mDisplayCutout.set(mDisplayCutout.get().inset(-padding.left, -padding.top,
848 -padding.right, -padding.bottom));
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700849 }
850
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700851 if (mCurWidth != w) {
852 sizeChanged = true;
853 mCurWidth = w;
854 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700855 if (mCurHeight != h) {
856 sizeChanged = true;
857 mCurHeight = h;
858 }
Jeff Brown30bc34f2011-01-25 12:56:56 -0800859
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700860 if (DEBUG) {
861 Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight);
862 }
863
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700864 insetsChanged |= !mDispatchedOverscanInsets.equals(mOverscanInsets);
865 insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
866 insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700867 insetsChanged |= !mDispatchedOutsets.equals(mOutsets);
Adrian Roos5c6b6222017-11-07 17:36:10 +0100868 insetsChanged |= !mDispatchedDisplayCutout.equals(mDisplayCutout.get());
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700869
Jeff Brown30bc34f2011-01-25 12:56:56 -0800870 mSurfaceHolder.setSurfaceFrameSize(w, h);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700871 mSurfaceHolder.mSurfaceLock.unlock();
872
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700873 if (!mSurfaceHolder.mSurface.isValid()) {
874 reportSurfaceDestroyed();
875 if (DEBUG) Log.v(TAG, "Layout: Surface destroyed");
876 return;
877 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700878
879 boolean didSurface = false;
880
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700881 try {
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700882 mSurfaceHolder.ungetCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700883
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700884 if (surfaceCreating) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700885 mIsCreating = true;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700886 didSurface = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700887 if (DEBUG) Log.v(TAG, "onSurfaceCreated("
888 + mSurfaceHolder + "): " + this);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700889 onSurfaceCreated(mSurfaceHolder);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700890 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700891 if (callbacks != null) {
892 for (SurfaceHolder.Callback c : callbacks) {
893 c.surfaceCreated(mSurfaceHolder);
894 }
895 }
896 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700897
Jeff Brown98365d72012-08-19 20:30:52 -0700898 redrawNeeded |= creating || (relayoutResult
899 & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700900
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700901 if (forceReport || creating || surfaceCreating
902 || formatChanged || sizeChanged) {
Dianne Hackborncbf15042009-08-18 18:29:09 -0700903 if (DEBUG) {
904 RuntimeException e = new RuntimeException();
905 e.fillInStackTrace();
906 Log.w(TAG, "forceReport=" + forceReport + " creating=" + creating
907 + " formatChanged=" + formatChanged
908 + " sizeChanged=" + sizeChanged, e);
909 }
Dianne Hackborn284ac932009-08-28 10:34:25 -0700910 if (DEBUG) Log.v(TAG, "onSurfaceChanged("
911 + mSurfaceHolder + ", " + mFormat
912 + ", " + mCurWidth + ", " + mCurHeight
913 + "): " + this);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700914 didSurface = true;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700915 onSurfaceChanged(mSurfaceHolder, mFormat,
916 mCurWidth, mCurHeight);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700917 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700918 if (callbacks != null) {
919 for (SurfaceHolder.Callback c : callbacks) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700920 c.surfaceChanged(mSurfaceHolder, mFormat,
921 mCurWidth, mCurHeight);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700922 }
923 }
924 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700925
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700926 if (insetsChanged) {
927 mDispatchedOverscanInsets.set(mOverscanInsets);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700928 mDispatchedOverscanInsets.left += mOutsets.left;
929 mDispatchedOverscanInsets.top += mOutsets.top;
930 mDispatchedOverscanInsets.right += mOutsets.right;
931 mDispatchedOverscanInsets.bottom += mOutsets.bottom;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700932 mDispatchedContentInsets.set(mContentInsets);
933 mDispatchedStableInsets.set(mStableInsets);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700934 mDispatchedOutsets.set(mOutsets);
Adrian Roos5c6b6222017-11-07 17:36:10 +0100935 mDispatchedDisplayCutout = mDisplayCutout.get();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700936 mFinalSystemInsets.set(mDispatchedOverscanInsets);
937 mFinalStableInsets.set(mDispatchedStableInsets);
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700938 WindowInsets insets = new WindowInsets(mFinalSystemInsets,
Adam Powell01f280d2015-05-18 16:07:42 -0700939 null, mFinalStableInsets,
Adrian Roosd4970af2017-11-10 15:48:01 +0100940 getResources().getConfiguration().isScreenRound(), false,
Adrian Roos5c6b6222017-11-07 17:36:10 +0100941 mDispatchedDisplayCutout);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700942 if (DEBUG) {
943 Log.v(TAG, "dispatching insets=" + insets);
944 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700945 onApplyWindowInsets(insets);
946 }
947
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700948 if (redrawNeeded) {
949 onSurfaceRedrawNeeded(mSurfaceHolder);
950 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
951 if (callbacks != null) {
952 for (SurfaceHolder.Callback c : callbacks) {
953 if (c instanceof SurfaceHolder.Callback2) {
954 ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
955 mSurfaceHolder);
956 }
957 }
958 }
959 }
960
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700961 if (didSurface && !mReportedVisible) {
962 // This wallpaper is currently invisible, but its
963 // surface has changed. At this point let's tell it
964 // again that it is invisible in case the report about
965 // the surface caused it to start running. We really
966 // don't want wallpapers running when not visible.
967 if (mIsCreating) {
968 // Some wallpapers will ignore this call if they
969 // had previously been told they were invisble,
970 // so if we are creating a new surface then toggle
971 // the state to get them to notice.
972 if (DEBUG) Log.v(TAG, "onVisibilityChanged(true) at surface: "
973 + this);
974 onVisibilityChanged(true);
975 }
976 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false) at surface: "
977 + this);
978 onVisibilityChanged(false);
979 }
980
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700981 } finally {
982 mIsCreating = false;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700983 mSurfaceCreated = true;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700984 if (redrawNeeded) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700985 mSession.finishDrawing(mWindow);
986 }
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -0700987 mIWallpaperEngine.reportShown();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700988 }
989 } catch (RemoteException ex) {
990 }
991 if (DEBUG) Log.v(
992 TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
993 " w=" + mLayout.width + " h=" + mLayout.height);
994 }
995 }
Lucas Dupin65b47652017-07-19 17:32:26 -0700996
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700997 void attach(IWallpaperEngineWrapper wrapper) {
Dianne Hackborncbf15042009-08-18 18:29:09 -0700998 if (DEBUG) Log.v(TAG, "attach: " + this + " wrapper=" + wrapper);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700999 if (mDestroyed) {
1000 return;
1001 }
1002
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001003 mIWallpaperEngine = wrapper;
1004 mCaller = wrapper.mCaller;
1005 mConnection = wrapper.mConnection;
1006 mWindowToken = wrapper.mWindowToken;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001007 mSurfaceHolder.setSizeFromLayout();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001008 mInitializing = true;
Jeff Brownf9e989d2013-04-04 23:04:03 -07001009 mSession = WindowManagerGlobal.getWindowSession();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001010
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001011 mWindow.setSession(mSession);
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -07001012
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001013 mLayout.packageName = getPackageName();
1014
Jeff Brown3d110b22014-11-21 19:01:13 -08001015 mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
1016 mDisplayManager.registerDisplayListener(mDisplayListener, mCaller.getHandler());
1017 mDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001018 mDisplayState = mDisplay.getState();
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -07001019
Dianne Hackborn284ac932009-08-28 10:34:25 -07001020 if (DEBUG) Log.v(TAG, "onCreate(): " + this);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001021 onCreate(mSurfaceHolder);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001022
1023 mInitializing = false;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001024 mReportedVisible = false;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001025 updateSurface(false, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001026 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001027
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001028 /**
1029 * Executes life cycle event and updates internal ambient mode state based on
1030 * message sent from handler.
1031 *
Lucas Dupin660d5732017-12-19 10:05:19 -08001032 * @param inAmbientMode {@code true} if in ambient mode.
1033 * @param animated {@code true} if the transition will be animated.
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001034 * @hide
1035 */
1036 @VisibleForTesting
Lucas Dupin660d5732017-12-19 10:05:19 -08001037 public void doAmbientModeChanged(boolean inAmbientMode, boolean animated) {
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001038 if (!mDestroyed) {
1039 if (DEBUG) {
Lucas Dupin660d5732017-12-19 10:05:19 -08001040 Log.v(TAG, "onAmbientModeChanged(" + inAmbientMode + ", "
1041 + animated + "): " + this);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001042 }
1043 mIsInAmbientMode = inAmbientMode;
1044 if (mCreated) {
Lucas Dupin660d5732017-12-19 10:05:19 -08001045 onAmbientModeChanged(inAmbientMode, animated);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001046 }
1047 }
1048 }
1049
Dianne Hackborn284ac932009-08-28 10:34:25 -07001050 void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
1051 if (!mDestroyed) {
1052 if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
1053 + desiredWidth + "," + desiredHeight + "): " + this);
Joe Onoratodcfae5c2010-10-28 18:03:23 -07001054 mIWallpaperEngine.mReqWidth = desiredWidth;
1055 mIWallpaperEngine.mReqHeight = desiredHeight;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001056 onDesiredSizeChanged(desiredWidth, desiredHeight);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001057 doOffsetsChanged(true);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001058 }
1059 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001060
1061 void doDisplayPaddingChanged(Rect padding) {
1062 if (!mDestroyed) {
1063 if (DEBUG) Log.v(TAG, "onDisplayPaddingChanged(" + padding + "): " + this);
1064 if (!mIWallpaperEngine.mDisplayPadding.equals(padding)) {
1065 mIWallpaperEngine.mDisplayPadding.set(padding);
1066 updateSurface(true, false, false);
1067 }
1068 }
1069 }
1070
Dianne Hackborn284ac932009-08-28 10:34:25 -07001071 void doVisibilityChanged(boolean visible) {
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001072 if (!mDestroyed) {
1073 mVisible = visible;
1074 reportVisibility();
1075 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001076 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001077
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001078 void reportVisibility() {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001079 if (!mDestroyed) {
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001080 mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState();
1081 boolean visible = mVisible && mDisplayState != Display.STATE_OFF;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001082 if (mReportedVisible != visible) {
1083 mReportedVisible = visible;
1084 if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
1085 + "): " + this);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001086 if (visible) {
1087 // If becoming visible, in preview mode the surface
1088 // may have been destroyed so now we need to make
1089 // sure it is re-created.
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001090 doOffsetsChanged(false);
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001091 updateSurface(false, false, false);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001092 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001093 onVisibilityChanged(visible);
1094 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001095 }
1096 }
1097
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001098 void doOffsetsChanged(boolean always) {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001099 if (mDestroyed) {
1100 return;
1101 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001102
1103 if (!always && !mOffsetsChanged) {
1104 return;
1105 }
1106
Dianne Hackborn284ac932009-08-28 10:34:25 -07001107 float xOffset;
1108 float yOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001109 float xOffsetStep;
1110 float yOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001111 boolean sync;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001112 synchronized (mLock) {
1113 xOffset = mPendingXOffset;
1114 yOffset = mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001115 xOffsetStep = mPendingXOffsetStep;
1116 yOffsetStep = mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001117 sync = mPendingSync;
1118 mPendingSync = false;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001119 mOffsetMessageEnqueued = false;
1120 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001121
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001122 if (mSurfaceCreated) {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001123 if (mReportedVisible) {
1124 if (DEBUG) Log.v(TAG, "Offsets change in " + this
1125 + ": " + xOffset + "," + yOffset);
1126 final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
1127 final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
1128 final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
1129 final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
1130 onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
1131 } else {
1132 mOffsetsChanged = true;
1133 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001134 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001135
1136 if (sync) {
1137 try {
1138 if (DEBUG) Log.v(TAG, "Reporting offsets change complete");
1139 mSession.wallpaperOffsetsComplete(mWindow.asBinder());
1140 } catch (RemoteException e) {
1141 }
1142 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001143 }
1144
Dianne Hackborn75804932009-10-20 20:15:20 -07001145 void doCommand(WallpaperCommand cmd) {
1146 Bundle result;
1147 if (!mDestroyed) {
1148 result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
1149 cmd.extras, cmd.sync);
1150 } else {
1151 result = null;
1152 }
1153 if (cmd.sync) {
1154 try {
1155 if (DEBUG) Log.v(TAG, "Reporting command complete");
1156 mSession.wallpaperCommandComplete(mWindow.asBinder(), result);
1157 } catch (RemoteException e) {
1158 }
1159 }
1160 }
1161
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001162 void reportSurfaceDestroyed() {
1163 if (mSurfaceCreated) {
1164 mSurfaceCreated = false;
Dianne Hackborndc8a7f62010-05-10 11:29:34 -07001165 mSurfaceHolder.ungetCallbacks();
1166 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
1167 if (callbacks != null) {
1168 for (SurfaceHolder.Callback c : callbacks) {
1169 c.surfaceDestroyed(mSurfaceHolder);
1170 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001171 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001172 if (DEBUG) Log.v(TAG, "onSurfaceDestroyed("
1173 + mSurfaceHolder + "): " + this);
1174 onSurfaceDestroyed(mSurfaceHolder);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001175 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001176 }
1177
1178 void detach() {
1179 if (mDestroyed) {
1180 return;
1181 }
1182
1183 mDestroyed = true;
Jeff Brown3d110b22014-11-21 19:01:13 -08001184
1185 if (mDisplayManager != null) {
1186 mDisplayManager.unregisterDisplayListener(mDisplayListener);
1187 }
1188
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001189 if (mVisible) {
1190 mVisible = false;
1191 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
1192 onVisibilityChanged(false);
1193 }
1194
1195 reportSurfaceDestroyed();
Dianne Hackborn284ac932009-08-28 10:34:25 -07001196
1197 if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
1198 onDestroy();
Jeff Brown3d110b22014-11-21 19:01:13 -08001199
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001200 if (mCreated) {
1201 try {
Dianne Hackbornba3e31d2010-04-22 18:59:03 -07001202 if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
1203 + mSurfaceHolder.getSurface() + " of: " + this);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001204
Jeff Brown32cbc38552011-12-01 14:01:49 -08001205 if (mInputEventReceiver != null) {
1206 mInputEventReceiver.dispose();
1207 mInputEventReceiver = null;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001208 }
1209
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001210 mSession.remove(mWindow);
1211 } catch (RemoteException e) {
1212 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001213 mSurfaceHolder.mSurface.release();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001214 mCreated = false;
Jeff Brown349703e2010-06-22 01:27:15 -07001215
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001216 // Dispose the input channel after removing the window so the Window Manager
1217 // doesn't interpret the input channel being closed as an abnormal termination.
1218 if (mInputChannel != null) {
1219 mInputChannel.dispose();
1220 mInputChannel = null;
Jeff Brown349703e2010-06-22 01:27:15 -07001221 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001222 }
1223 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001224
1225 private final DisplayListener mDisplayListener = new DisplayListener() {
1226 @Override
1227 public void onDisplayChanged(int displayId) {
1228 if (mDisplay.getDisplayId() == displayId) {
1229 reportVisibility();
1230 }
1231 }
1232
1233 @Override
1234 public void onDisplayRemoved(int displayId) {
1235 }
1236
1237 @Override
1238 public void onDisplayAdded(int displayId) {
1239 }
1240 };
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001241 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001242
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001243 class IWallpaperEngineWrapper extends IWallpaperEngine.Stub
1244 implements HandlerCaller.Callback {
1245 private final HandlerCaller mCaller;
1246
1247 final IWallpaperConnection mConnection;
1248 final IBinder mWindowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001249 final int mWindowType;
1250 final boolean mIsPreview;
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001251 boolean mShownReported;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001252 int mReqWidth;
1253 int mReqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001254 final Rect mDisplayPadding = new Rect();
1255
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001256 Engine mEngine;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001257
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001258 IWallpaperEngineWrapper(WallpaperService context,
1259 IWallpaperConnection conn, IBinder windowToken,
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001260 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
Mita Yunaa8dc2e2012-12-10 18:32:03 -08001261 mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001262 mConnection = conn;
1263 mWindowToken = windowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001264 mWindowType = windowType;
1265 mIsPreview = isPreview;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001266 mReqWidth = reqWidth;
1267 mReqHeight = reqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001268 mDisplayPadding.set(padding);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001269
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001270 Message msg = mCaller.obtainMessage(DO_ATTACH);
1271 mCaller.sendMessage(msg);
1272 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001273
Dianne Hackborn284ac932009-08-28 10:34:25 -07001274 public void setDesiredSize(int width, int height) {
1275 Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height);
1276 mCaller.sendMessage(msg);
1277 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001278
1279 public void setDisplayPadding(Rect padding) {
1280 Message msg = mCaller.obtainMessageO(DO_SET_DISPLAY_PADDING, padding);
1281 mCaller.sendMessage(msg);
1282 }
1283
Dianne Hackborn284ac932009-08-28 10:34:25 -07001284 public void setVisibility(boolean visible) {
1285 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
1286 visible ? 1 : 0);
1287 mCaller.sendMessage(msg);
1288 }
1289
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001290 @Override
Lucas Dupin660d5732017-12-19 10:05:19 -08001291 public void setInAmbientMode(boolean inAmbientDisplay, boolean animated)
1292 throws RemoteException {
1293 Message msg = mCaller.obtainMessageII(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0,
1294 animated ? 1 : 0);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001295 mCaller.sendMessage(msg);
1296 }
1297
Dianne Hackborn6adba242009-11-10 11:10:09 -08001298 public void dispatchPointer(MotionEvent event) {
1299 if (mEngine != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001300 mEngine.dispatchPointer(event);
Jeff Brown32cbc38552011-12-01 14:01:49 -08001301 } else {
1302 event.recycle();
Dianne Hackborn6adba242009-11-10 11:10:09 -08001303 }
1304 }
Jeff Brown9f3bdfe2010-10-13 06:01:27 -07001305
1306 public void dispatchWallpaperCommand(String action, int x, int y,
1307 int z, Bundle extras) {
1308 if (mEngine != null) {
1309 mEngine.mWindow.dispatchWallpaperCommand(action, x, y, z, extras, false);
1310 }
1311 }
1312
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001313 public void reportShown() {
1314 if (!mShownReported) {
1315 mShownReported = true;
1316 try {
1317 mConnection.engineShown(this);
1318 } catch (RemoteException e) {
1319 Log.w(TAG, "Wallpaper host disappeared", e);
1320 return;
1321 }
1322 }
1323 }
1324
Lucas Dupin50ba9912017-07-14 11:55:05 -07001325 public void requestWallpaperColors() {
1326 Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS);
1327 mCaller.sendMessage(msg);
1328 }
1329
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001330 public void destroy() {
1331 Message msg = mCaller.obtainMessage(DO_DETACH);
1332 mCaller.sendMessage(msg);
1333 }
1334
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001335 @Override
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001336 public void executeMessage(Message message) {
1337 switch (message.what) {
1338 case DO_ATTACH: {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001339 try {
1340 mConnection.attachEngine(this);
1341 } catch (RemoteException e) {
1342 Log.w(TAG, "Wallpaper host disappeared", e);
1343 return;
1344 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001345 Engine engine = onCreateEngine();
1346 mEngine = engine;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001347 mActiveEngines.add(engine);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001348 engine.attach(this);
1349 return;
1350 }
1351 case DO_DETACH: {
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001352 mActiveEngines.remove(mEngine);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001353 mEngine.detach();
1354 return;
1355 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001356 case DO_SET_DESIRED_SIZE: {
1357 mEngine.doDesiredSizeChanged(message.arg1, message.arg2);
1358 return;
1359 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001360 case DO_SET_DISPLAY_PADDING: {
1361 mEngine.doDisplayPaddingChanged((Rect) message.obj);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001362 return;
1363 }
1364 case DO_IN_AMBIENT_MODE: {
Lucas Dupin660d5732017-12-19 10:05:19 -08001365 mEngine.doAmbientModeChanged(message.arg1 != 0, message.arg2 != 0);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001366 return;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001367 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001368 case MSG_UPDATE_SURFACE:
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001369 mEngine.updateSurface(true, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001370 break;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001371 case MSG_VISIBILITY_CHANGED:
1372 if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
1373 + ": " + message.arg1);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001374 mEngine.doVisibilityChanged(message.arg1 != 0);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001375 break;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001376 case MSG_WALLPAPER_OFFSETS: {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001377 mEngine.doOffsetsChanged(true);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001378 } break;
Dianne Hackborn75804932009-10-20 20:15:20 -07001379 case MSG_WALLPAPER_COMMAND: {
1380 WallpaperCommand cmd = (WallpaperCommand)message.obj;
1381 mEngine.doCommand(cmd);
1382 } break;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001383 case MSG_WINDOW_RESIZED: {
1384 final boolean reportDraw = message.arg1 != 0;
Filip Gruszczynski03850592015-07-01 08:35:28 -07001385 mEngine.mOutsets.set((Rect) message.obj);
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001386 mEngine.updateSurface(true, false, reportDraw);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001387 mEngine.doOffsetsChanged(true);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001388 } break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07001389 case MSG_WINDOW_MOVED: {
1390 // Do nothing. What does it mean for a Wallpaper to move?
1391 } break;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001392 case MSG_TOUCH_EVENT: {
Jeff Brown840db1f2010-10-21 17:36:54 -07001393 boolean skip = false;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001394 MotionEvent ev = (MotionEvent)message.obj;
Jeff Brown840db1f2010-10-21 17:36:54 -07001395 if (ev.getAction() == MotionEvent.ACTION_MOVE) {
1396 synchronized (mEngine.mLock) {
1397 if (mEngine.mPendingMove == ev) {
1398 mEngine.mPendingMove = null;
1399 } else {
1400 // this is not the motion event we are looking for....
1401 skip = true;
1402 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001403 }
1404 }
Jeff Brown840db1f2010-10-21 17:36:54 -07001405 if (!skip) {
1406 if (DEBUG) Log.v(TAG, "Delivering touch event: " + ev);
1407 mEngine.onTouchEvent(ev);
1408 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001409 ev.recycle();
1410 } break;
Lucas Dupin50ba9912017-07-14 11:55:05 -07001411 case MSG_REQUEST_WALLPAPER_COLORS: {
1412 if (mConnection == null) {
1413 break;
1414 }
1415 try {
1416 mConnection.onWallpaperColorsChanged(mEngine.onComputeColors());
1417 } catch (RemoteException e) {
1418 // Connection went away, nothing to do in here.
1419 }
1420 } break;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001421 default :
1422 Log.w(TAG, "Unknown message type " + message.what);
1423 }
1424 }
1425 }
1426
1427 /**
1428 * Implements the internal {@link IWallpaperService} interface to convert
1429 * incoming calls to it back to calls on an {@link WallpaperService}.
1430 */
1431 class IWallpaperServiceWrapper extends IWallpaperService.Stub {
1432 private final WallpaperService mTarget;
1433
1434 public IWallpaperServiceWrapper(WallpaperService context) {
1435 mTarget = context;
1436 }
1437
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001438 @Override
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001439 public void attach(IWallpaperConnection conn, IBinder windowToken,
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001440 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001441 new IWallpaperEngineWrapper(mTarget, conn, windowToken,
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001442 windowType, isPreview, reqWidth, reqHeight, padding);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001443 }
1444 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001445
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001446 @Override
1447 public void onCreate() {
1448 super.onCreate();
1449 }
1450
1451 @Override
1452 public void onDestroy() {
1453 super.onDestroy();
1454 for (int i=0; i<mActiveEngines.size(); i++) {
1455 mActiveEngines.get(i).detach();
1456 }
1457 mActiveEngines.clear();
1458 }
1459
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001460 /**
1461 * Implement to return the implementation of the internal accessibility
1462 * service interface. Subclasses should not override.
1463 */
1464 @Override
1465 public final IBinder onBind(Intent intent) {
1466 return new IWallpaperServiceWrapper(this);
1467 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001468
Dianne Hackborn23ef7b42009-11-18 18:20:39 -08001469 /**
1470 * Must be implemented to return a new instance of the wallpaper's engine.
1471 * Note that multiple instances may be active at the same time, such as
1472 * when the wallpaper is currently set as the active wallpaper and the user
1473 * is in the wallpaper picker viewing a preview of it as well.
1474 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001475 public abstract Engine onCreateEngine();
Dianne Hackborn527de8e2011-08-22 16:10:36 -07001476
1477 @Override
1478 protected void dump(FileDescriptor fd, PrintWriter out, String[] args) {
1479 out.print("State of wallpaper "); out.print(this); out.println(":");
1480 for (int i=0; i<mActiveEngines.size(); i++) {
1481 Engine engine = mActiveEngines.get(i);
1482 out.print(" Engine "); out.print(engine); out.println(":");
1483 engine.dump(" ", fd, out, args);
1484 }
1485 }
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001486}