blob: f944dd78dc3d62de6482b075305382a27deadd7d [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
Santiago Etchebehere44a28312020-01-14 15:27:11 -080019import android.annotation.FloatRange;
Lucas Dupinc40608c2017-04-14 18:33:08 -070020import android.annotation.Nullable;
Dianne Hackbornd6847842010-01-12 18:14:19 -080021import android.annotation.SdkConstant;
22import android.annotation.SdkConstant.SdkConstantType;
Lucas Dupin4c8c3272018-11-06 17:47:48 -080023import android.annotation.SystemApi;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070024import android.app.Service;
Lucas Dupin84b89d92017-05-09 12:16:19 -070025import android.app.WallpaperColors;
Lucas Dupin8f09a502018-07-27 16:47:45 +080026import android.app.WallpaperInfo;
Dianne Hackborn759a39e2009-08-09 17:20:27 -070027import android.app.WallpaperManager;
Artur Satayevdf439592019-12-10 17:47:53 +000028import android.compat.annotation.UnsupportedAppUsage;
wilsonshih8ccb9ce2018-12-04 11:44:31 +080029import android.content.Context;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070030import android.content.Intent;
Lucas Dupin84b89d92017-05-09 12:16:19 -070031import android.content.res.TypedArray;
32import android.graphics.Bitmap;
33import android.graphics.Canvas;
Mathias Agopian62bf4a02010-09-08 16:32:27 -070034import android.graphics.PixelFormat;
Valerie Hau30360552020-01-14 16:12:01 -080035import android.graphics.Point;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070036import android.graphics.Rect;
Lucas Dupin84b89d92017-05-09 12:16:19 -070037import android.graphics.drawable.Drawable;
Jeff Brown3d110b22014-11-21 19:01:13 -080038import android.hardware.display.DisplayManager;
39import android.hardware.display.DisplayManager.DisplayListener;
Mathew Inwood31755f92018-12-20 13:53:36 +000040import android.os.Build;
Dianne Hackborn75804932009-10-20 20:15:20 -070041import android.os.Bundle;
Lucas Dupin65b47652017-07-19 17:32:26 -070042import android.os.Handler;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070043import android.os.IBinder;
Dianne Hackborn19382ac2009-09-11 21:13:37 -070044import android.os.Looper;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070045import android.os.Message;
46import android.os.RemoteException;
Lucas Dupin65b47652017-07-19 17:32:26 -070047import android.os.SystemClock;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070048import android.util.Log;
Lucas Dupin84b89d92017-05-09 12:16:19 -070049import android.util.MergedConfiguration;
Craig Mautner6881a102012-07-27 13:04:51 -070050import android.view.Display;
Adrian Roos5c6b6222017-11-07 17:36:10 +010051import android.view.DisplayCutout;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070052import android.view.Gravity;
53import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -070054import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -070055import android.view.InputDevice;
Jeff Brown4952dfd2011-11-30 19:23:22 -080056import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -080057import android.view.InputEventReceiver;
Tiger Huang0426a332020-03-29 01:17:08 +080058import android.view.InsetsSourceControl;
wilsonshih8ccb9ce2018-12-04 11:44:31 +080059import android.view.InsetsState;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -070060import android.view.MotionEvent;
Robert Carr5fea55b2018-12-10 13:05:52 -080061import android.view.SurfaceControl;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070062import android.view.SurfaceHolder;
63import android.view.View;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -070064import android.view.ViewGroup;
Lucas Dupin84b89d92017-05-09 12:16:19 -070065import android.view.WindowInsets;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070066import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -070067import android.view.WindowManagerGlobal;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070068
Lucas Dupin65b47652017-07-19 17:32:26 -070069import com.android.internal.annotations.VisibleForTesting;
Lucas Dupin84b89d92017-05-09 12:16:19 -070070import com.android.internal.os.HandlerCaller;
71import com.android.internal.view.BaseIWindow;
72import com.android.internal.view.BaseSurfaceHolder;
73
Dianne Hackborn527de8e2011-08-22 16:10:36 -070074import java.io.FileDescriptor;
75import java.io.PrintWriter;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -080076import java.util.ArrayList;
wilsonshihb72ff9c2019-03-21 17:27:02 +080077import java.util.concurrent.atomic.AtomicBoolean;
Lucas Dupin65b47652017-07-19 17:32:26 -070078import java.util.function.Supplier;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -080079
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070080/**
81 * A wallpaper service is responsible for showing a live wallpaper behind
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080082 * applications that would like to sit on top of it. This service object
83 * itself does very little -- its only purpose is to generate instances of
Dianne Hackborne4260f42009-11-18 21:15:59 -080084 * {@link Engine} as needed. Implementing a wallpaper thus
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080085 * involves subclassing from this, subclassing an Engine implementation,
86 * and implementing {@link #onCreateEngine()} to return a new instance of
87 * your engine.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070088 */
89public abstract class WallpaperService extends Service {
90 /**
91 * The {@link Intent} that must be declared as handled by the service.
Dianne Hackbornd6847842010-01-12 18:14:19 -080092 * To be supported, the service must also require the
93 * {@link android.Manifest.permission#BIND_WALLPAPER} permission so
94 * that other applications can not abuse it.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070095 */
Dianne Hackbornd6847842010-01-12 18:14:19 -080096 @SdkConstant(SdkConstantType.SERVICE_ACTION)
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070097 public static final String SERVICE_INTERFACE =
Dianne Hackbornd6847842010-01-12 18:14:19 -080098 "android.service.wallpaper.WallpaperService";
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070099
Dianne Hackborneb034652009-09-07 00:49:58 -0700100 /**
101 * Name under which a WallpaperService component publishes information
102 * about itself. This meta-data must reference an XML resource containing
103 * a <code>&lt;{@link android.R.styleable#Wallpaper wallpaper}&gt;</code>
104 * tag.
105 */
106 public static final String SERVICE_META_DATA = "android.service.wallpaper";
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800107
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700108 static final String TAG = "WallpaperService";
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700109 static final boolean DEBUG = false;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700110
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700111 private static final int DO_ATTACH = 10;
112 private static final int DO_DETACH = 20;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700113 private static final int DO_SET_DESIRED_SIZE = 30;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700114 private static final int DO_SET_DISPLAY_PADDING = 40;
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700115 private static final int DO_IN_AMBIENT_MODE = 50;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700116
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700117 private static final int MSG_UPDATE_SURFACE = 10000;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700118 private static final int MSG_VISIBILITY_CHANGED = 10010;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700119 private static final int MSG_WALLPAPER_OFFSETS = 10020;
Dianne Hackborn75804932009-10-20 20:15:20 -0700120 private static final int MSG_WALLPAPER_COMMAND = 10025;
Mathew Inwoode3807372018-08-10 09:51:03 +0100121 @UnsupportedAppUsage
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700122 private static final int MSG_WINDOW_RESIZED = 10030;
Craig Mautner5702d4d2012-06-30 14:10:16 -0700123 private static final int MSG_WINDOW_MOVED = 10035;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700124 private static final int MSG_TOUCH_EVENT = 10040;
Lucas Dupin50ba9912017-07-14 11:55:05 -0700125 private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
Santiago Etchebehere44a28312020-01-14 15:27:11 -0800126 private static final int MSG_SCALE = 10100;
127
Lucas Dupin65b47652017-07-19 17:32:26 -0700128 private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
129
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -0800130 private final ArrayList<Engine> mActiveEngines
131 = new ArrayList<Engine>();
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700132
Dianne Hackborn75804932009-10-20 20:15:20 -0700133 static final class WallpaperCommand {
134 String action;
135 int x;
136 int y;
137 int z;
138 Bundle extras;
139 boolean sync;
140 }
wilsonshih81e10a72018-11-15 10:54:21 +0800141
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700142 /**
143 * The actual implementation of a wallpaper. A wallpaper service may
144 * have multiple instances running (for example as a real wallpaper
145 * and as a preview), each of which is represented by its own Engine
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700146 * instance. You must implement {@link WallpaperService#onCreateEngine()}
147 * to return your concrete Engine implementation.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700148 */
149 public class Engine {
150 IWallpaperEngineWrapper mIWallpaperEngine;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700151
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700152 // Copies from mIWallpaperEngine.
153 HandlerCaller mCaller;
154 IWallpaperConnection mConnection;
155 IBinder mWindowToken;
wilsonshih81e10a72018-11-15 10:54:21 +0800156
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700157 boolean mInitializing = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700158 boolean mVisible;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700159 boolean mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700160 boolean mDestroyed;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700161
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700162 // Current window state.
163 boolean mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700164 boolean mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700165 boolean mIsCreating;
166 boolean mDrawingAllowed;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700167 boolean mOffsetsChanged;
Jeff Sharkey35be7562012-04-18 19:16:15 -0700168 boolean mFixedSizeAllowed;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700169 int mWidth;
170 int mHeight;
171 int mFormat;
172 int mType;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700173 int mCurWidth;
174 int mCurHeight;
Santiago Etchebehere44a28312020-01-14 15:27:11 -0800175 float mZoom = 0f;
Lucas Dupin6155aa42018-09-05 11:15:52 -0700176 int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700177 int mWindowPrivateFlags =
178 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700179 int mCurWindowFlags = mWindowFlags;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700180 int mCurWindowPrivateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700181 final Rect mVisibleInsets = new Rect();
182 final Rect mWinFrame = new Rect();
183 final Rect mContentInsets = new Rect();
Adrian Roosfa104232014-06-20 16:10:14 -0700184 final Rect mStableInsets = new Rect();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700185 final Rect mDispatchedContentInsets = new Rect();
186 final Rect mDispatchedStableInsets = new Rect();
187 final Rect mFinalSystemInsets = new Rect();
188 final Rect mFinalStableInsets = new Rect();
Jorim Jaggi2e95a482016-01-14 17:36:55 -0800189 final Rect mBackdropFrame = new Rect();
Adrian Roos5c6b6222017-11-07 17:36:10 +0100190 final DisplayCutout.ParcelableWrapper mDisplayCutout =
191 new DisplayCutout.ParcelableWrapper();
192 DisplayCutout mDispatchedDisplayCutout = DisplayCutout.NO_CUTOUT;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200193 final InsetsState mInsetsState = new InsetsState();
Tiger Huang0426a332020-03-29 01:17:08 +0800194 final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0];
Andrii Kulian44607962017-03-16 11:06:24 -0700195 final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
Valerie Hau30360552020-01-14 16:12:01 -0800196 private final Point mSurfaceSize = new Point();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700197
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700198 final WindowManager.LayoutParams mLayout
199 = new WindowManager.LayoutParams();
200 IWindowSession mSession;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700201
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700202 final Object mLock = new Object();
203 boolean mOffsetMessageEnqueued;
Mathew Inwood31755f92018-12-20 13:53:36 +0000204 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700205 float mPendingXOffset;
206 float mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800207 float mPendingXOffsetStep;
208 float mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700209 boolean mPendingSync;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700210 MotionEvent mPendingMove;
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700211 boolean mIsInAmbientMode;
Jeff Brown3d110b22014-11-21 19:01:13 -0800212
Lucas Dupin65b47652017-07-19 17:32:26 -0700213 // Needed for throttling onComputeColors.
214 private long mLastColorInvalidation;
215 private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
Lucas Dupin416fe952017-08-14 10:58:40 -0700216 private final Supplier<Long> mClockFunction;
217 private final Handler mHandler;
Lucas Dupin65b47652017-07-19 17:32:26 -0700218
wilsonshih8ccb9ce2018-12-04 11:44:31 +0800219 private Display mDisplay;
220 private Context mDisplayContext;
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700221 private int mDisplayState;
Jeff Brown3d110b22014-11-21 19:01:13 -0800222
Robert Carr5fea55b2018-12-10 13:05:52 -0800223 SurfaceControl mSurfaceControl = new SurfaceControl();
224
Robert Carr2e20bcd2020-01-22 13:32:38 -0800225 // Unused relayout out-param
226 SurfaceControl mTmpSurfaceControl = new SurfaceControl();
227
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700228 final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700229 {
Jeff Brown24572372011-06-09 19:05:15 -0700230 mRequestedFormat = PixelFormat.RGBX_8888;
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700231 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700232
233 @Override
234 public boolean onAllowLockCanvas() {
235 return mDrawingAllowed;
236 }
237
238 @Override
239 public void onRelayoutContainer() {
240 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
241 mCaller.sendMessage(msg);
242 }
243
244 @Override
245 public void onUpdateSurface() {
246 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
247 mCaller.sendMessage(msg);
248 }
249
250 public boolean isCreating() {
251 return mIsCreating;
252 }
253
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800254 @Override
255 public void setFixedSize(int width, int height) {
Jeff Sharkey35be7562012-04-18 19:16:15 -0700256 if (!mFixedSizeAllowed) {
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800257 // Regular apps can't do this. It can only work for
258 // certain designs of window animations, so you can't
259 // rely on it.
260 throw new UnsupportedOperationException(
261 "Wallpapers currently only support sizing from layout");
262 }
Michael Jurkab8f939f2011-02-01 20:50:30 -0800263 super.setFixedSize(width, height);
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800264 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700265
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700266 public void setKeepScreenOn(boolean screenOn) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700267 throw new UnsupportedOperationException(
268 "Wallpapers do not support keep screen on");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700269 }
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700270
John Reck6bc70142016-10-26 16:49:17 -0700271 private void prepareToDraw() {
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700272 if (mDisplayState == Display.STATE_DOZE
273 || mDisplayState == Display.STATE_DOZE_SUSPEND) {
274 try {
275 mSession.pokeDrawLock(mWindow);
276 } catch (RemoteException e) {
277 // System server died, can be ignored.
278 }
279 }
John Reck6bc70142016-10-26 16:49:17 -0700280 }
281
282 @Override
283 public Canvas lockCanvas() {
284 prepareToDraw();
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700285 return super.lockCanvas();
286 }
John Reck6bc70142016-10-26 16:49:17 -0700287
288 @Override
289 public Canvas lockCanvas(Rect dirty) {
290 prepareToDraw();
291 return super.lockCanvas(dirty);
292 }
293
294 @Override
295 public Canvas lockHardwareCanvas() {
296 prepareToDraw();
297 return super.lockHardwareCanvas();
298 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700299 };
Jeff Brown32cbc38552011-12-01 14:01:49 -0800300
301 final class WallpaperInputEventReceiver extends InputEventReceiver {
302 public WallpaperInputEventReceiver(InputChannel inputChannel, Looper looper) {
303 super(inputChannel, looper);
304 }
305
Jeff Brown46b9ac02010-04-22 18:58:52 -0700306 @Override
Siarhei Vishniakou85ddfff2018-01-31 16:49:36 -0800307 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700308 boolean handled = false;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700309 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800310 if (event instanceof MotionEvent
311 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800312 MotionEvent dup = MotionEvent.obtainNoHistory((MotionEvent)event);
313 dispatchPointer(dup);
Jeff Brown3915bb82010-11-05 15:02:16 -0700314 handled = true;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700315 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700316 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800317 finishInputEvent(event, handled);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700318 }
319 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800320 }
321 WallpaperInputEventReceiver mInputEventReceiver;
322
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700323 final BaseIWindow mWindow = new BaseIWindow() {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700324 @Override
Jorim Jaggif081f062019-10-24 16:24:54 +0200325 public void resized(Rect frame, Rect contentInsets,
326 Rect visibleInsets, Rect stableInsets, boolean reportDraw,
Andrii Kulian44607962017-03-16 11:06:24 -0700327 MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout,
Brad Stenninge0573692019-03-11 13:52:46 -0700328 boolean alwaysConsumeSystemBars, int displayId,
Adrian Roos5c6b6222017-11-07 17:36:10 +0100329 DisplayCutout.ParcelableWrapper displayCutout) {
Jorim Jaggif081f062019-10-24 16:24:54 +0200330 Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
331 reportDraw ? 1 : 0);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700332 mCaller.sendMessage(msg);
333 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700334
335 @Override
336 public void moved(int newX, int newY) {
337 Message msg = mCaller.obtainMessageII(MSG_WINDOW_MOVED, newX, newY);
338 mCaller.sendMessage(msg);
339 }
340
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700341 @Override
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700342 public void dispatchAppVisibility(boolean visible) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700343 // We don't do this in preview mode; we'll let the preview
344 // activity tell us when to run.
345 if (!mIWallpaperEngine.mIsPreview) {
346 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
347 visible ? 1 : 0);
348 mCaller.sendMessage(msg);
349 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700350 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700351
352 @Override
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800353 public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
Lucas Dupin13f4b8a2020-02-19 13:41:52 -0800354 float zoom, boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700355 synchronized (mLock) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700356 if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700357 mPendingXOffset = x;
358 mPendingYOffset = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800359 mPendingXOffsetStep = xStep;
360 mPendingYOffsetStep = yStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700361 if (sync) {
362 mPendingSync = true;
363 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700364 if (!mOffsetMessageEnqueued) {
365 mOffsetMessageEnqueued = true;
366 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
367 mCaller.sendMessage(msg);
368 }
Lucas Dupin13f4b8a2020-02-19 13:41:52 -0800369 Message msg = mCaller.obtainMessageI(MSG_SCALE, Float.floatToIntBits(zoom));
370 mCaller.sendMessage(msg);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700371 }
372 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700373
374 @Override
Dianne Hackborn75804932009-10-20 20:15:20 -0700375 public void dispatchWallpaperCommand(String action, int x, int y,
376 int z, Bundle extras, boolean sync) {
377 synchronized (mLock) {
378 if (DEBUG) Log.v(TAG, "Dispatch wallpaper command: " + x + ", " + y);
379 WallpaperCommand cmd = new WallpaperCommand();
380 cmd.action = action;
381 cmd.x = x;
382 cmd.y = y;
383 cmd.z = z;
384 cmd.extras = extras;
385 cmd.sync = sync;
386 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_COMMAND);
387 msg.obj = cmd;
388 mCaller.sendMessage(msg);
389 }
390 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700391 };
Lucas Dupin416fe952017-08-14 10:58:40 -0700392
393 /**
394 * Default constructor
395 */
396 public Engine() {
397 this(SystemClock::elapsedRealtime, Handler.getMain());
398 }
399
400 /**
401 * Constructor used for test purposes.
402 *
403 * @param clockFunction Supplies current times in millis.
404 * @param handler Used for posting/deferring asynchronous calls.
405 * @hide
406 */
407 @VisibleForTesting
408 public Engine(Supplier<Long> clockFunction, Handler handler) {
409 mClockFunction = clockFunction;
410 mHandler = handler;
411 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700412
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700413 /**
414 * Provides access to the surface in which this wallpaper is drawn.
415 */
416 public SurfaceHolder getSurfaceHolder() {
417 return mSurfaceHolder;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700418 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700419
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700420 /**
421 * Convenience for {@link WallpaperManager#getDesiredMinimumWidth()
422 * WallpaperManager.getDesiredMinimumWidth()}, returning the width
423 * that the system would like this wallpaper to run in.
424 */
425 public int getDesiredMinimumWidth() {
426 return mIWallpaperEngine.mReqWidth;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700427 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700428
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700429 /**
430 * Convenience for {@link WallpaperManager#getDesiredMinimumHeight()
431 * WallpaperManager.getDesiredMinimumHeight()}, returning the height
432 * that the system would like this wallpaper to run in.
433 */
434 public int getDesiredMinimumHeight() {
435 return mIWallpaperEngine.mReqHeight;
436 }
wilsonshih81e10a72018-11-15 10:54:21 +0800437
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700438 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700439 * Return whether the wallpaper is currently visible to the user,
440 * this is the last value supplied to
441 * {@link #onVisibilityChanged(boolean)}.
442 */
443 public boolean isVisible() {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700444 return mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700445 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700446
Dianne Hackborn284ac932009-08-28 10:34:25 -0700447 /**
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700448 * Returns true if this engine is running in preview mode -- that is,
449 * it is being shown to the user before they select it as the actual
450 * wallpaper.
451 */
452 public boolean isPreview() {
453 return mIWallpaperEngine.mIsPreview;
454 }
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700455
456 /**
457 * Returns true if this engine is running in ambient mode -- that is,
Lucas Dupin8f09a502018-07-27 16:47:45 +0800458 * it is being shown in low power mode, on always on display.
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800459 * @hide
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700460 */
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800461 @SystemApi
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700462 public boolean isInAmbientMode() {
463 return mIsInAmbientMode;
464 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700465
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700466 /**
Lucas Dupin13f4b8a2020-02-19 13:41:52 -0800467 * This will be called when the wallpaper is first started. If true is returned, the system
468 * will zoom in the wallpaper by default and zoom it out as the user interacts,
469 * to create depth. Otherwise, zoom will have to be handled manually
470 * in {@link #onZoomChanged(float)}.
471 *
472 * @hide
473 */
474 public boolean shouldZoomOutWallpaper() {
475 return false;
476 }
477
478 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700479 * Control whether this wallpaper will receive raw touch events
480 * from the window manager as the user interacts with the window
481 * that is currently displaying the wallpaper. By default they
482 * are turned off. If enabled, the events will be received in
483 * {@link #onTouchEvent(MotionEvent)}.
484 */
485 public void setTouchEventsEnabled(boolean enabled) {
486 mWindowFlags = enabled
487 ? (mWindowFlags&~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
488 : (mWindowFlags|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
489 if (mCreated) {
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700490 updateSurface(false, false, false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700491 }
492 }
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700493
494 /**
495 * Control whether this wallpaper will receive notifications when the wallpaper
496 * has been scrolled. By default, wallpapers will receive notifications, although
497 * the default static image wallpapers do not. It is a performance optimization to
498 * set this to false.
499 *
500 * @param enabled whether the wallpaper wants to receive offset notifications
501 */
502 public void setOffsetNotificationsEnabled(boolean enabled) {
503 mWindowPrivateFlags = enabled
504 ? (mWindowPrivateFlags |
505 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS)
506 : (mWindowPrivateFlags &
507 ~WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS);
508 if (mCreated) {
509 updateSurface(false, false, false);
510 }
511 }
Jeff Sharkey35be7562012-04-18 19:16:15 -0700512
513 /** {@hide} */
Mathew Inwoode3807372018-08-10 09:51:03 +0100514 @UnsupportedAppUsage
Jeff Sharkey35be7562012-04-18 19:16:15 -0700515 public void setFixedSizeAllowed(boolean allowed) {
516 mFixedSizeAllowed = allowed;
517 }
518
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700519 /**
Santiago Etchebehere44a28312020-01-14 15:27:11 -0800520 * Returns the current scale of the surface
521 * @hide
522 */
523 @VisibleForTesting
524 public float getZoom() {
525 return mZoom;
526 }
527
528 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700529 * Called once to initialize the engine. After returning, the
530 * engine's surface will be created by the framework.
531 */
532 public void onCreate(SurfaceHolder surfaceHolder) {
533 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700534
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700535 /**
536 * Called right before the engine is going away. After this the
537 * surface will be destroyed and this Engine object is no longer
538 * valid.
539 */
540 public void onDestroy() {
541 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700542
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700543 /**
544 * Called to inform you of the wallpaper becoming visible or
545 * hidden. <em>It is very important that a wallpaper only use
546 * CPU while it is visible.</em>.
547 */
548 public void onVisibilityChanged(boolean visible) {
549 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700550
551 /**
552 * Called with the current insets that are in effect for the wallpaper.
553 * This gives you the part of the overall wallpaper surface that will
554 * generally be visible to the user (ignoring position offsets applied to it).
555 *
556 * @param insets Insets to apply.
557 */
558 public void onApplyWindowInsets(WindowInsets insets) {
559 }
560
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700561 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700562 * Called as the user performs touch-screen interaction with the
563 * window that is currently showing this wallpaper. Note that the
564 * events you receive here are driven by the actual application the
Marco Nelissenae87bd02009-09-17 09:44:43 -0700565 * user is interacting with, so if it is slow you will get fewer
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700566 * move events.
567 */
568 public void onTouchEvent(MotionEvent event) {
569 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700570
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700571 /**
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700572 * Called to inform you of the wallpaper's offsets changing
573 * within its contain, corresponding to the container's
574 * call to {@link WallpaperManager#setWallpaperOffsets(IBinder, float, float)
575 * WallpaperManager.setWallpaperOffsets()}.
576 */
577 public void onOffsetsChanged(float xOffset, float yOffset,
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800578 float xOffsetStep, float yOffsetStep,
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700579 int xPixelOffset, int yPixelOffset) {
580 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700581
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700582 /**
Dianne Hackborn75804932009-10-20 20:15:20 -0700583 * Process a command that was sent to the wallpaper with
Dianne Hackborn13bf82602009-11-05 21:45:51 -0800584 * {@link WallpaperManager#sendWallpaperCommand}.
Dianne Hackborn75804932009-10-20 20:15:20 -0700585 * The default implementation does nothing, and always returns null
586 * as the result.
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700587 *
Dianne Hackborn75804932009-10-20 20:15:20 -0700588 * @param action The name of the command to perform. This tells you
589 * what to do and how to interpret the rest of the arguments.
590 * @param x Generic integer parameter.
591 * @param y Generic integer parameter.
592 * @param z Generic integer parameter.
593 * @param extras Any additional parameters.
594 * @param resultRequested If true, the caller is requesting that
595 * a result, appropriate for the command, be returned back.
596 * @return If returning a result, create a Bundle and place the
597 * result data in to it. Otherwise return null.
598 */
599 public Bundle onCommand(String action, int x, int y, int z,
600 Bundle extras, boolean resultRequested) {
601 return null;
602 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700603
Dianne Hackborn75804932009-10-20 20:15:20 -0700604 /**
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700605 * Called when the device enters or exits ambient mode.
606 *
607 * @param inAmbientMode {@code true} if in ambient mode.
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800608 * @param animationDuration How long the transition animation to change the ambient state
609 * should run, in milliseconds. If 0 is passed as the argument
610 * here, the state should be switched immediately.
Lucas Dupin8f09a502018-07-27 16:47:45 +0800611 *
612 * @see #isInAmbientMode()
613 * @see WallpaperInfo#supportsAmbientMode()
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800614 * @hide
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700615 */
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800616 @SystemApi
617 public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700618 }
619
620 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700621 * Called when an application has changed the desired virtual size of
622 * the wallpaper.
623 */
624 public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
625 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700626
Dianne Hackborn284ac932009-08-28 10:34:25 -0700627 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700628 * Convenience for {@link SurfaceHolder.Callback#surfaceChanged
629 * SurfaceHolder.Callback.surfaceChanged()}.
630 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700631 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
632 }
633
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700634 /**
Dianne Hackborn1d28f9c2010-07-13 20:38:06 -0700635 * Convenience for {@link SurfaceHolder.Callback2#surfaceRedrawNeeded
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700636 * SurfaceHolder.Callback.surfaceRedrawNeeded()}.
637 */
638 public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
639 }
640
641 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700642 * Convenience for {@link SurfaceHolder.Callback#surfaceCreated
643 * SurfaceHolder.Callback.surfaceCreated()}.
644 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700645 public void onSurfaceCreated(SurfaceHolder holder) {
646 }
647
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700648 /**
649 * Convenience for {@link SurfaceHolder.Callback#surfaceDestroyed
650 * SurfaceHolder.Callback.surfaceDestroyed()}.
651 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700652 public void onSurfaceDestroyed(SurfaceHolder holder) {
653 }
Lucas Dupinc40608c2017-04-14 18:33:08 -0700654
655 /**
Santiago Etchebehere44a28312020-01-14 15:27:11 -0800656 * Called when the zoom level of the wallpaper changed.
657 * This method will be called with the initial zoom level when the surface is created.
658 *
659 * @param zoom the zoom level, between 0 indicating fully zoomed in and 1 indicating fully
660 * zoomed out.
661 */
662 public void onZoomChanged(@FloatRange(from = 0f, to = 1f) float zoom) {
663 }
664
665 /**
Lucas Dupinc40608c2017-04-14 18:33:08 -0700666 * Notifies the engine that wallpaper colors changed significantly.
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700667 * This will trigger a {@link #onComputeColors()} call.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700668 */
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700669 public void notifyColorsChanged() {
Lucas Dupin65b47652017-07-19 17:32:26 -0700670 final long now = mClockFunction.get();
Lucas Dupin65b47652017-07-19 17:32:26 -0700671 if (now - mLastColorInvalidation < NOTIFY_COLORS_RATE_LIMIT_MS) {
672 Log.w(TAG, "This call has been deferred. You should only call "
673 + "notifyColorsChanged() once every "
674 + (NOTIFY_COLORS_RATE_LIMIT_MS / 1000f) + " seconds.");
Lucas Dupin416fe952017-08-14 10:58:40 -0700675 if (!mHandler.hasCallbacks(mNotifyColorsChanged)) {
676 mHandler.postDelayed(mNotifyColorsChanged, NOTIFY_COLORS_RATE_LIMIT_MS);
Lucas Dupin65b47652017-07-19 17:32:26 -0700677 }
678 return;
679 }
680 mLastColorInvalidation = now;
Lucas Dupin416fe952017-08-14 10:58:40 -0700681 mHandler.removeCallbacks(mNotifyColorsChanged);
Lucas Dupin65b47652017-07-19 17:32:26 -0700682
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700683 try {
Lucas Dupin65b47652017-07-19 17:32:26 -0700684 final WallpaperColors newColors = onComputeColors();
685 if (mConnection != null) {
wilsonshih36597d42018-12-05 18:56:39 +0800686 mConnection.onWallpaperColorsChanged(newColors, mDisplay.getDisplayId());
Lucas Dupin65b47652017-07-19 17:32:26 -0700687 } else {
688 Log.w(TAG, "Can't notify system because wallpaper connection "
689 + "was not established.");
690 }
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700691 } catch (RemoteException e) {
Lucas Dupin65b47652017-07-19 17:32:26 -0700692 Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700693 }
Lucas Dupinc40608c2017-04-14 18:33:08 -0700694 }
695
696 /**
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700697 * Called by the system when it needs to know what colors the wallpaper is using.
Lucas Dupin65b47652017-07-19 17:32:26 -0700698 * You might return null if no color information is available at the moment.
699 * In that case you might want to call {@link #notifyColorsChanged()} when
700 * color information becomes available.
Lucas Dupin84b89d92017-05-09 12:16:19 -0700701 * <p>
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700702 * The simplest way of creating a {@link android.app.WallpaperColors} object is by using
Lucas Dupin84b89d92017-05-09 12:16:19 -0700703 * {@link android.app.WallpaperColors#fromBitmap(Bitmap)} or
704 * {@link android.app.WallpaperColors#fromDrawable(Drawable)}, but you can also specify
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700705 * your main colors by constructing a {@link android.app.WallpaperColors} object manually.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700706 *
Lucas Dupin84b89d92017-05-09 12:16:19 -0700707 * @return Wallpaper colors.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700708 */
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700709 public @Nullable WallpaperColors onComputeColors() {
Lucas Dupinc40608c2017-04-14 18:33:08 -0700710 return null;
711 }
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700712
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700713 /**
714 * Sets internal engine state. Only for testing.
715 * @param created {@code true} or {@code false}.
716 * @hide
717 */
718 @VisibleForTesting
719 public void setCreated(boolean created) {
720 mCreated = created;
721 }
722
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700723 protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
724 out.print(prefix); out.print("mInitializing="); out.print(mInitializing);
725 out.print(" mDestroyed="); out.println(mDestroyed);
726 out.print(prefix); out.print("mVisible="); out.print(mVisible);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700727 out.print(" mReportedVisible="); out.println(mReportedVisible);
Jeff Brown3d110b22014-11-21 19:01:13 -0800728 out.print(prefix); out.print("mDisplay="); out.println(mDisplay);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700729 out.print(prefix); out.print("mCreated="); out.print(mCreated);
730 out.print(" mSurfaceCreated="); out.print(mSurfaceCreated);
731 out.print(" mIsCreating="); out.print(mIsCreating);
732 out.print(" mDrawingAllowed="); out.println(mDrawingAllowed);
733 out.print(prefix); out.print("mWidth="); out.print(mWidth);
734 out.print(" mCurWidth="); out.print(mCurWidth);
735 out.print(" mHeight="); out.print(mHeight);
736 out.print(" mCurHeight="); out.println(mCurHeight);
737 out.print(prefix); out.print("mType="); out.print(mType);
738 out.print(" mWindowFlags="); out.print(mWindowFlags);
739 out.print(" mCurWindowFlags="); out.println(mCurWindowFlags);
Dianne Hackbornd052a942014-11-21 15:23:13 -0800740 out.print(prefix); out.print("mWindowPrivateFlags="); out.print(mWindowPrivateFlags);
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700741 out.print(" mCurWindowPrivateFlags="); out.println(mCurWindowPrivateFlags);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700742 out.print(prefix); out.print("mVisibleInsets=");
743 out.print(mVisibleInsets.toShortString());
744 out.print(" mWinFrame="); out.print(mWinFrame.toShortString());
745 out.print(" mContentInsets="); out.println(mContentInsets.toShortString());
Andrii Kulian44607962017-03-16 11:06:24 -0700746 out.print(prefix); out.print("mConfiguration=");
747 out.println(mMergedConfiguration.getMergedConfiguration());
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700748 out.print(prefix); out.print("mLayout="); out.println(mLayout);
Santiago Etchebehere44a28312020-01-14 15:27:11 -0800749 out.print(prefix); out.print("mZoom="); out.println(mZoom);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700750 synchronized (mLock) {
751 out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
752 out.print(" mPendingXOffset="); out.println(mPendingXOffset);
753 out.print(prefix); out.print("mPendingXOffsetStep=");
754 out.print(mPendingXOffsetStep);
755 out.print(" mPendingXOffsetStep="); out.println(mPendingXOffsetStep);
756 out.print(prefix); out.print("mOffsetMessageEnqueued=");
757 out.print(mOffsetMessageEnqueued);
758 out.print(" mPendingSync="); out.println(mPendingSync);
759 if (mPendingMove != null) {
760 out.print(prefix); out.print("mPendingMove="); out.println(mPendingMove);
761 }
762 }
763 }
764
Santiago Etchebehere44a28312020-01-14 15:27:11 -0800765 /**
766 * Set the wallpaper zoom to the given value. This value will be ignored when in ambient
767 * mode (and zoom will be reset to 0).
768 * @hide
769 * @param zoom between 0 and 1 (inclusive) indicating fully zoomed in to fully zoomed out
770 * respectively.
771 */
772 @VisibleForTesting
773 public void setZoom(float zoom) {
774 if (DEBUG) {
775 Log.v(TAG, "set zoom received: " + zoom);
776 }
777 boolean updated = false;
778 synchronized (mLock) {
779 if (DEBUG) {
780 Log.v(TAG, "mZoom: " + mZoom + " updated: " + zoom);
781 }
782 if (mIsInAmbientMode) {
783 mZoom = 0;
784 }
785 if (Float.compare(zoom, mZoom) != 0) {
786 mZoom = zoom;
787 updated = true;
788 }
789 }
790 if (DEBUG) Log.v(TAG, "setZoom updated? " + updated);
791 if (updated && !mDestroyed) {
792 onZoomChanged(mZoom);
793 }
794 }
795
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700796 private void dispatchPointer(MotionEvent event) {
Jeff Brown33bbfd22011-02-24 20:55:35 -0800797 if (event.isTouchEvent()) {
798 synchronized (mLock) {
799 if (event.getAction() == MotionEvent.ACTION_MOVE) {
800 mPendingMove = event;
801 } else {
802 mPendingMove = null;
803 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700804 }
Jeff Brown33bbfd22011-02-24 20:55:35 -0800805 Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
806 mCaller.sendMessage(msg);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700807 } else {
808 event.recycle();
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700809 }
810 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700811
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700812 void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700813 if (mDestroyed) {
814 Log.w(TAG, "Ignoring updateSurface: destroyed");
815 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700816
817 boolean fixedSize = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700818 int myWidth = mSurfaceHolder.getRequestedWidth();
Romain Guy980a9382010-01-08 15:06:28 -0800819 if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700820 else fixedSize = true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700821 int myHeight = mSurfaceHolder.getRequestedHeight();
Romain Guy980a9382010-01-08 15:06:28 -0800822 if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700823 else fixedSize = true;
824
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700825 final boolean creating = !mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700826 final boolean surfaceCreating = !mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700827 final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700828 boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700829 boolean insetsChanged = !mCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700830 final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700831 final boolean flagsChanged = mCurWindowFlags != mWindowFlags ||
832 mCurWindowPrivateFlags != mWindowPrivateFlags;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700833 if (forceRelayout || creating || surfaceCreating || formatChanged || sizeChanged
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -0700834 || typeChanged || flagsChanged || redrawNeeded
835 || !mIWallpaperEngine.mShownReported) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700836
Dianne Hackborn284ac932009-08-28 10:34:25 -0700837 if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700838 + " format=" + formatChanged + " size=" + sizeChanged);
839
840 try {
841 mWidth = myWidth;
842 mHeight = myHeight;
843 mFormat = mSurfaceHolder.getRequestedFormat();
844 mType = mSurfaceHolder.getRequestedType();
845
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700846 mLayout.x = 0;
847 mLayout.y = 0;
Valentin Iftime6239e532018-08-24 17:17:26 +0200848
Vadim Caenb46f9232020-02-14 17:54:39 +0100849 mLayout.width = myWidth;
850 mLayout.height = myHeight;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700851 mLayout.format = mFormat;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700852
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700853 mCurWindowFlags = mWindowFlags;
854 mLayout.flags = mWindowFlags
855 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
Jorim Jaggi526505d2016-05-24 00:29:19 -0700856 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700857 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
Lucas Dupin6155aa42018-09-05 11:15:52 -0700858 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700859 mCurWindowPrivateFlags = mWindowPrivateFlags;
860 mLayout.privateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700861
862 mLayout.memoryType = mType;
863 mLayout.token = mWindowToken;
864
865 if (!mCreated) {
Filip Gruszczynskid66ba062015-03-23 12:59:02 -0700866 // Retrieve watch round info
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700867 TypedArray windowStyle = obtainStyledAttributes(
868 com.android.internal.R.styleable.Window);
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700869 windowStyle.recycle();
870
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700871 // Add window
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700872 mLayout.type = mIWallpaperEngine.mWindowType;
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -0700873 mLayout.gravity = Gravity.START|Gravity.TOP;
Tiger Huang52724442020-01-20 21:38:42 +0800874 mLayout.setFitInsetsTypes(0 /* types */);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -0700875 mLayout.setTitle(WallpaperService.this.getClass().getName());
Dianne Hackborn284ac932009-08-28 10:34:25 -0700876 mLayout.windowAnimations =
877 com.android.internal.R.style.Animation_Wallpaper;
Arthur Hung12a06ce2019-07-22 15:35:17 +0800878 InputChannel inputChannel = new InputChannel();
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200879
Craig Mautner6881a102012-07-27 13:04:51 -0700880 if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE,
wilsonshihde93f492018-11-01 21:23:40 +0800881 mDisplay.getDisplayId(), mWinFrame, mContentInsets, mStableInsets,
Jorim Jaggif081f062019-10-24 16:24:54 +0200882 mDisplayCutout, inputChannel,
Tiger Huang0426a332020-03-29 01:17:08 +0800883 mInsetsState, mTempControls) < 0) {
Mattias Peterssond9463f52011-01-12 15:38:55 +0100884 Log.w(TAG, "Failed to add window while updating wallpaper surface.");
885 return;
886 }
Lucas Dupin13f4b8a2020-02-19 13:41:52 -0800887 mSession.setShouldZoomOutWallpaper(mWindow, shouldZoomOutWallpaper());
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700888 mCreated = true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700889
Jeff Brown32cbc38552011-12-01 14:01:49 -0800890 mInputEventReceiver = new WallpaperInputEventReceiver(
Arthur Hung12a06ce2019-07-22 15:35:17 +0800891 inputChannel, Looper.myLooper());
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700892 }
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700893
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700894 mSurfaceHolder.mSurfaceLock.lock();
895 mDrawingAllowed = true;
896
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700897 if (!fixedSize) {
898 mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
899 } else {
900 mLayout.surfaceInsets.set(0, 0, 0, 0);
901 }
Valerie Hau30360552020-01-14 16:12:01 -0800902
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700903 final int relayoutResult = mSession.relayout(
Dianne Hackborn9a230e02011-10-06 11:51:27 -0700904 mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
Jorim Jaggif081f062019-10-24 16:24:54 +0200905 View.VISIBLE, 0, -1, mWinFrame, mContentInsets,
906 mVisibleInsets, mStableInsets, mBackdropFrame,
Robert Carr5fea55b2018-12-10 13:05:52 -0800907 mDisplayCutout, mMergedConfiguration, mSurfaceControl,
Tiger Huang0426a332020-03-29 01:17:08 +0800908 mInsetsState, mTempControls, mSurfaceSize, mTmpSurfaceControl);
Robert Carr5fea55b2018-12-10 13:05:52 -0800909 if (mSurfaceControl.isValid()) {
910 mSurfaceHolder.mSurface.copyFrom(mSurfaceControl);
911 mSurfaceControl.release();
912 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700913
Dianne Hackborn284ac932009-08-28 10:34:25 -0700914 if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700915 + ", frame=" + mWinFrame);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700916
Adrian Roos2ae38052014-12-09 17:03:01 +0000917 int w = mWinFrame.width();
918 int h = mWinFrame.height();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700919
920 if (!fixedSize) {
921 final Rect padding = mIWallpaperEngine.mDisplayPadding;
Jorim Jaggif081f062019-10-24 16:24:54 +0200922 w += padding.left + padding.right;
923 h += padding.top + padding.bottom;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700924 mContentInsets.left += padding.left;
925 mContentInsets.top += padding.top;
926 mContentInsets.right += padding.right;
927 mContentInsets.bottom += padding.bottom;
928 mStableInsets.left += padding.left;
929 mStableInsets.top += padding.top;
930 mStableInsets.right += padding.right;
931 mStableInsets.bottom += padding.bottom;
Adrian Roos5c6b6222017-11-07 17:36:10 +0100932 mDisplayCutout.set(mDisplayCutout.get().inset(-padding.left, -padding.top,
933 -padding.right, -padding.bottom));
Valentin Iftime6239e532018-08-24 17:17:26 +0200934 } else {
935 w = myWidth;
936 h = myHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700937 }
938
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700939 if (mCurWidth != w) {
940 sizeChanged = true;
941 mCurWidth = w;
942 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700943 if (mCurHeight != h) {
944 sizeChanged = true;
945 mCurHeight = h;
946 }
Jeff Brown30bc34f2011-01-25 12:56:56 -0800947
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700948 if (DEBUG) {
949 Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight);
950 }
951
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700952 insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
953 insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
Adrian Roos5c6b6222017-11-07 17:36:10 +0100954 insetsChanged |= !mDispatchedDisplayCutout.equals(mDisplayCutout.get());
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700955
Jeff Brown30bc34f2011-01-25 12:56:56 -0800956 mSurfaceHolder.setSurfaceFrameSize(w, h);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700957 mSurfaceHolder.mSurfaceLock.unlock();
958
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700959 if (!mSurfaceHolder.mSurface.isValid()) {
960 reportSurfaceDestroyed();
961 if (DEBUG) Log.v(TAG, "Layout: Surface destroyed");
962 return;
963 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700964
965 boolean didSurface = false;
966
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700967 try {
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700968 mSurfaceHolder.ungetCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700969
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700970 if (surfaceCreating) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700971 mIsCreating = true;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700972 didSurface = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700973 if (DEBUG) Log.v(TAG, "onSurfaceCreated("
974 + mSurfaceHolder + "): " + this);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700975 onSurfaceCreated(mSurfaceHolder);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700976 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700977 if (callbacks != null) {
978 for (SurfaceHolder.Callback c : callbacks) {
979 c.surfaceCreated(mSurfaceHolder);
980 }
981 }
982 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700983
Jeff Brown98365d72012-08-19 20:30:52 -0700984 redrawNeeded |= creating || (relayoutResult
985 & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700986
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700987 if (forceReport || creating || surfaceCreating
988 || formatChanged || sizeChanged) {
Dianne Hackborncbf15042009-08-18 18:29:09 -0700989 if (DEBUG) {
990 RuntimeException e = new RuntimeException();
991 e.fillInStackTrace();
992 Log.w(TAG, "forceReport=" + forceReport + " creating=" + creating
993 + " formatChanged=" + formatChanged
994 + " sizeChanged=" + sizeChanged, e);
995 }
Dianne Hackborn284ac932009-08-28 10:34:25 -0700996 if (DEBUG) Log.v(TAG, "onSurfaceChanged("
997 + mSurfaceHolder + ", " + mFormat
998 + ", " + mCurWidth + ", " + mCurHeight
999 + "): " + this);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001000 didSurface = true;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001001 onSurfaceChanged(mSurfaceHolder, mFormat,
1002 mCurWidth, mCurHeight);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -07001003 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001004 if (callbacks != null) {
1005 for (SurfaceHolder.Callback c : callbacks) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001006 c.surfaceChanged(mSurfaceHolder, mFormat,
1007 mCurWidth, mCurHeight);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001008 }
1009 }
1010 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001011
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001012 if (insetsChanged) {
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001013 mDispatchedContentInsets.set(mContentInsets);
1014 mDispatchedStableInsets.set(mStableInsets);
Adrian Roos5c6b6222017-11-07 17:36:10 +01001015 mDispatchedDisplayCutout = mDisplayCutout.get();
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001016 mFinalStableInsets.set(mDispatchedStableInsets);
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001017 WindowInsets insets = new WindowInsets(mFinalSystemInsets,
Jorim Jaggi297985a2018-11-30 17:24:58 +01001018 mFinalStableInsets,
Adrian Roosd4970af2017-11-10 15:48:01 +01001019 getResources().getConfiguration().isScreenRound(), false,
Adrian Roos5c6b6222017-11-07 17:36:10 +01001020 mDispatchedDisplayCutout);
Filip Gruszczynski2217f612015-05-26 11:32:08 -07001021 if (DEBUG) {
1022 Log.v(TAG, "dispatching insets=" + insets);
1023 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001024 onApplyWindowInsets(insets);
1025 }
1026
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001027 if (redrawNeeded) {
1028 onSurfaceRedrawNeeded(mSurfaceHolder);
1029 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
1030 if (callbacks != null) {
1031 for (SurfaceHolder.Callback c : callbacks) {
1032 if (c instanceof SurfaceHolder.Callback2) {
1033 ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
1034 mSurfaceHolder);
1035 }
1036 }
1037 }
1038 }
1039
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001040 if (didSurface && !mReportedVisible) {
1041 // This wallpaper is currently invisible, but its
1042 // surface has changed. At this point let's tell it
1043 // again that it is invisible in case the report about
1044 // the surface caused it to start running. We really
1045 // don't want wallpapers running when not visible.
1046 if (mIsCreating) {
1047 // Some wallpapers will ignore this call if they
1048 // had previously been told they were invisble,
1049 // so if we are creating a new surface then toggle
1050 // the state to get them to notice.
1051 if (DEBUG) Log.v(TAG, "onVisibilityChanged(true) at surface: "
1052 + this);
1053 onVisibilityChanged(true);
1054 }
1055 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false) at surface: "
1056 + this);
1057 onVisibilityChanged(false);
1058 }
1059
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001060 } finally {
1061 mIsCreating = false;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001062 mSurfaceCreated = true;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001063 if (redrawNeeded) {
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001064 mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001065 }
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001066 mIWallpaperEngine.reportShown();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001067 }
1068 } catch (RemoteException ex) {
1069 }
1070 if (DEBUG) Log.v(
1071 TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
1072 " w=" + mLayout.width + " h=" + mLayout.height);
1073 }
1074 }
Lucas Dupin65b47652017-07-19 17:32:26 -07001075
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001076 void attach(IWallpaperEngineWrapper wrapper) {
Dianne Hackborncbf15042009-08-18 18:29:09 -07001077 if (DEBUG) Log.v(TAG, "attach: " + this + " wrapper=" + wrapper);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001078 if (mDestroyed) {
1079 return;
1080 }
wilsonshihde93f492018-11-01 21:23:40 +08001081
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001082 mIWallpaperEngine = wrapper;
1083 mCaller = wrapper.mCaller;
1084 mConnection = wrapper.mConnection;
1085 mWindowToken = wrapper.mWindowToken;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001086 mSurfaceHolder.setSizeFromLayout();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001087 mInitializing = true;
Jeff Brownf9e989d2013-04-04 23:04:03 -07001088 mSession = WindowManagerGlobal.getWindowSession();
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001089
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001090 mWindow.setSession(mSession);
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -07001091
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001092 mLayout.packageName = getPackageName();
wilsonshih81e10a72018-11-15 10:54:21 +08001093 mIWallpaperEngine.mDisplayManager.registerDisplayListener(mDisplayListener,
1094 mCaller.getHandler());
1095 mDisplay = mIWallpaperEngine.mDisplay;
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001096 mDisplayContext = createDisplayContext(mDisplay);
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001097 mDisplayState = mDisplay.getState();
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -07001098
Dianne Hackborn284ac932009-08-28 10:34:25 -07001099 if (DEBUG) Log.v(TAG, "onCreate(): " + this);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001100 onCreate(mSurfaceHolder);
wilsonshih81e10a72018-11-15 10:54:21 +08001101
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001102 mInitializing = false;
wilsonshih81e10a72018-11-15 10:54:21 +08001103
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001104 mReportedVisible = false;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001105 updateSurface(false, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001106 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001107
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001108 /**
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001109 * The {@link Context} with resources that match the current display the wallpaper is on.
1110 * For multiple display environment, multiple engines can be created to render on each
1111 * display, but these displays may have different densities. Use this context to get the
1112 * corresponding resources for currently display, avoiding the context of the service.
wilsonshihfd058f62019-02-13 15:57:06 +08001113 * <p>
1114 * The display context will never be {@code null} after
1115 * {@link Engine#onCreate(SurfaceHolder)} has been called.
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001116 *
1117 * @return A {@link Context} for current display.
1118 */
wilsonshihfd058f62019-02-13 15:57:06 +08001119 @Nullable
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001120 public Context getDisplayContext() {
1121 return mDisplayContext;
1122 }
1123
1124 /**
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001125 * Executes life cycle event and updates internal ambient mode state based on
1126 * message sent from handler.
1127 *
Lucas Dupin660d5732017-12-19 10:05:19 -08001128 * @param inAmbientMode {@code true} if in ambient mode.
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001129 * @param animationDuration For how long the transition will last, in ms.
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001130 * @hide
1131 */
1132 @VisibleForTesting
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001133 public void doAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001134 if (!mDestroyed) {
1135 if (DEBUG) {
Lucas Dupin660d5732017-12-19 10:05:19 -08001136 Log.v(TAG, "onAmbientModeChanged(" + inAmbientMode + ", "
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001137 + animationDuration + "): " + this);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001138 }
1139 mIsInAmbientMode = inAmbientMode;
1140 if (mCreated) {
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001141 onAmbientModeChanged(inAmbientMode, animationDuration);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001142 }
1143 }
1144 }
1145
Dianne Hackborn284ac932009-08-28 10:34:25 -07001146 void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
1147 if (!mDestroyed) {
1148 if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
1149 + desiredWidth + "," + desiredHeight + "): " + this);
Joe Onoratodcfae5c2010-10-28 18:03:23 -07001150 mIWallpaperEngine.mReqWidth = desiredWidth;
1151 mIWallpaperEngine.mReqHeight = desiredHeight;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001152 onDesiredSizeChanged(desiredWidth, desiredHeight);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001153 doOffsetsChanged(true);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001154 }
1155 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001156
1157 void doDisplayPaddingChanged(Rect padding) {
1158 if (!mDestroyed) {
1159 if (DEBUG) Log.v(TAG, "onDisplayPaddingChanged(" + padding + "): " + this);
1160 if (!mIWallpaperEngine.mDisplayPadding.equals(padding)) {
1161 mIWallpaperEngine.mDisplayPadding.set(padding);
1162 updateSurface(true, false, false);
1163 }
1164 }
1165 }
1166
Dianne Hackborn284ac932009-08-28 10:34:25 -07001167 void doVisibilityChanged(boolean visible) {
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001168 if (!mDestroyed) {
1169 mVisible = visible;
1170 reportVisibility();
1171 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001172 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001173
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001174 void reportVisibility() {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001175 if (!mDestroyed) {
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001176 mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState();
1177 boolean visible = mVisible && mDisplayState != Display.STATE_OFF;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001178 if (mReportedVisible != visible) {
1179 mReportedVisible = visible;
1180 if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
1181 + "): " + this);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001182 if (visible) {
1183 // If becoming visible, in preview mode the surface
1184 // may have been destroyed so now we need to make
1185 // sure it is re-created.
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001186 doOffsetsChanged(false);
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001187 updateSurface(false, false, false);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001188 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001189 onVisibilityChanged(visible);
1190 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001191 }
1192 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001193
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001194 void doOffsetsChanged(boolean always) {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001195 if (mDestroyed) {
1196 return;
1197 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001198
1199 if (!always && !mOffsetsChanged) {
1200 return;
1201 }
1202
Dianne Hackborn284ac932009-08-28 10:34:25 -07001203 float xOffset;
1204 float yOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001205 float xOffsetStep;
1206 float yOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001207 boolean sync;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001208 synchronized (mLock) {
1209 xOffset = mPendingXOffset;
1210 yOffset = mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001211 xOffsetStep = mPendingXOffsetStep;
1212 yOffsetStep = mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001213 sync = mPendingSync;
1214 mPendingSync = false;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001215 mOffsetMessageEnqueued = false;
1216 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001217
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001218 if (mSurfaceCreated) {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001219 if (mReportedVisible) {
1220 if (DEBUG) Log.v(TAG, "Offsets change in " + this
1221 + ": " + xOffset + "," + yOffset);
1222 final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
1223 final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
1224 final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
1225 final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
1226 onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
1227 } else {
1228 mOffsetsChanged = true;
1229 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001230 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001231
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001232 if (sync) {
1233 try {
1234 if (DEBUG) Log.v(TAG, "Reporting offsets change complete");
1235 mSession.wallpaperOffsetsComplete(mWindow.asBinder());
1236 } catch (RemoteException e) {
1237 }
1238 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001239 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001240
Dianne Hackborn75804932009-10-20 20:15:20 -07001241 void doCommand(WallpaperCommand cmd) {
1242 Bundle result;
1243 if (!mDestroyed) {
1244 result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
1245 cmd.extras, cmd.sync);
1246 } else {
1247 result = null;
1248 }
1249 if (cmd.sync) {
1250 try {
1251 if (DEBUG) Log.v(TAG, "Reporting command complete");
1252 mSession.wallpaperCommandComplete(mWindow.asBinder(), result);
1253 } catch (RemoteException e) {
1254 }
1255 }
1256 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001257
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001258 void reportSurfaceDestroyed() {
1259 if (mSurfaceCreated) {
1260 mSurfaceCreated = false;
Dianne Hackborndc8a7f62010-05-10 11:29:34 -07001261 mSurfaceHolder.ungetCallbacks();
1262 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
1263 if (callbacks != null) {
1264 for (SurfaceHolder.Callback c : callbacks) {
1265 c.surfaceDestroyed(mSurfaceHolder);
1266 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001267 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001268 if (DEBUG) Log.v(TAG, "onSurfaceDestroyed("
1269 + mSurfaceHolder + "): " + this);
1270 onSurfaceDestroyed(mSurfaceHolder);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001271 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001272 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001273
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001274 void detach() {
1275 if (mDestroyed) {
1276 return;
1277 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001278
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001279 mDestroyed = true;
Jeff Brown3d110b22014-11-21 19:01:13 -08001280
wilsonshih81e10a72018-11-15 10:54:21 +08001281 if (mIWallpaperEngine.mDisplayManager != null) {
1282 mIWallpaperEngine.mDisplayManager.unregisterDisplayListener(mDisplayListener);
Jeff Brown3d110b22014-11-21 19:01:13 -08001283 }
1284
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001285 if (mVisible) {
1286 mVisible = false;
1287 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
1288 onVisibilityChanged(false);
1289 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001290
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001291 reportSurfaceDestroyed();
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001292
Dianne Hackborn284ac932009-08-28 10:34:25 -07001293 if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
1294 onDestroy();
Jeff Brown3d110b22014-11-21 19:01:13 -08001295
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001296 if (mCreated) {
1297 try {
Dianne Hackbornba3e31d2010-04-22 18:59:03 -07001298 if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
1299 + mSurfaceHolder.getSurface() + " of: " + this);
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001300
Jeff Brown32cbc38552011-12-01 14:01:49 -08001301 if (mInputEventReceiver != null) {
1302 mInputEventReceiver.dispose();
1303 mInputEventReceiver = null;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001304 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001305
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001306 mSession.remove(mWindow);
1307 } catch (RemoteException e) {
1308 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001309 mSurfaceHolder.mSurface.release();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001310 mCreated = false;
1311 }
1312 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001313
1314 private final DisplayListener mDisplayListener = new DisplayListener() {
1315 @Override
1316 public void onDisplayChanged(int displayId) {
1317 if (mDisplay.getDisplayId() == displayId) {
1318 reportVisibility();
1319 }
1320 }
1321
1322 @Override
1323 public void onDisplayRemoved(int displayId) {
1324 }
1325
1326 @Override
1327 public void onDisplayAdded(int displayId) {
1328 }
1329 };
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001330 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001331
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001332 class IWallpaperEngineWrapper extends IWallpaperEngine.Stub
1333 implements HandlerCaller.Callback {
1334 private final HandlerCaller mCaller;
1335
1336 final IWallpaperConnection mConnection;
1337 final IBinder mWindowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001338 final int mWindowType;
1339 final boolean mIsPreview;
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001340 boolean mShownReported;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001341 int mReqWidth;
1342 int mReqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001343 final Rect mDisplayPadding = new Rect();
wilsonshih81e10a72018-11-15 10:54:21 +08001344 final int mDisplayId;
1345 final DisplayManager mDisplayManager;
1346 final Display mDisplay;
wilsonshihb72ff9c2019-03-21 17:27:02 +08001347 private final AtomicBoolean mDetached = new AtomicBoolean();
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001348
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001349 Engine mEngine;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001350
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001351 IWallpaperEngineWrapper(WallpaperService context,
1352 IWallpaperConnection conn, IBinder windowToken,
wilsonshihde93f492018-11-01 21:23:40 +08001353 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
1354 int displayId) {
Mita Yunaa8dc2e2012-12-10 18:32:03 -08001355 mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001356 mConnection = conn;
1357 mWindowToken = windowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001358 mWindowType = windowType;
1359 mIsPreview = isPreview;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001360 mReqWidth = reqWidth;
1361 mReqHeight = reqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001362 mDisplayPadding.set(padding);
wilsonshihde93f492018-11-01 21:23:40 +08001363 mDisplayId = displayId;
wilsonshih81e10a72018-11-15 10:54:21 +08001364
1365 // Create a display context before onCreateEngine.
1366 mDisplayManager = getSystemService(DisplayManager.class);
1367 mDisplay = mDisplayManager.getDisplay(mDisplayId);
1368
1369 if (mDisplay == null) {
1370 // Ignore this engine.
1371 throw new IllegalArgumentException("Cannot find display with id" + mDisplayId);
1372 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001373 Message msg = mCaller.obtainMessage(DO_ATTACH);
1374 mCaller.sendMessage(msg);
1375 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001376
Dianne Hackborn284ac932009-08-28 10:34:25 -07001377 public void setDesiredSize(int width, int height) {
1378 Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height);
1379 mCaller.sendMessage(msg);
1380 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001381
1382 public void setDisplayPadding(Rect padding) {
1383 Message msg = mCaller.obtainMessageO(DO_SET_DISPLAY_PADDING, padding);
1384 mCaller.sendMessage(msg);
1385 }
1386
Dianne Hackborn284ac932009-08-28 10:34:25 -07001387 public void setVisibility(boolean visible) {
1388 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
1389 visible ? 1 : 0);
1390 mCaller.sendMessage(msg);
1391 }
1392
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001393 @Override
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001394 public void setInAmbientMode(boolean inAmbientDisplay, long animationDuration)
Lucas Dupin660d5732017-12-19 10:05:19 -08001395 throws RemoteException {
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001396 Message msg = mCaller.obtainMessageIO(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0,
1397 animationDuration);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001398 mCaller.sendMessage(msg);
1399 }
1400
Dianne Hackborn6adba242009-11-10 11:10:09 -08001401 public void dispatchPointer(MotionEvent event) {
1402 if (mEngine != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001403 mEngine.dispatchPointer(event);
Jeff Brown32cbc38552011-12-01 14:01:49 -08001404 } else {
1405 event.recycle();
Dianne Hackborn6adba242009-11-10 11:10:09 -08001406 }
1407 }
Jeff Brown9f3bdfe2010-10-13 06:01:27 -07001408
1409 public void dispatchWallpaperCommand(String action, int x, int y,
1410 int z, Bundle extras) {
1411 if (mEngine != null) {
1412 mEngine.mWindow.dispatchWallpaperCommand(action, x, y, z, extras, false);
1413 }
1414 }
1415
Santiago Etchebehere44a28312020-01-14 15:27:11 -08001416 public void setZoomOut(float scale) {
1417 Message msg = mCaller.obtainMessageI(MSG_SCALE, Float.floatToIntBits(scale));
1418 mCaller.sendMessage(msg);
1419 }
1420
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001421 public void reportShown() {
1422 if (!mShownReported) {
1423 mShownReported = true;
1424 try {
1425 mConnection.engineShown(this);
1426 } catch (RemoteException e) {
1427 Log.w(TAG, "Wallpaper host disappeared", e);
1428 return;
1429 }
1430 }
1431 }
1432
Lucas Dupin50ba9912017-07-14 11:55:05 -07001433 public void requestWallpaperColors() {
1434 Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS);
1435 mCaller.sendMessage(msg);
1436 }
1437
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001438 public void destroy() {
1439 Message msg = mCaller.obtainMessage(DO_DETACH);
1440 mCaller.sendMessage(msg);
1441 }
1442
wilsonshihb72ff9c2019-03-21 17:27:02 +08001443 public void detach() {
1444 mDetached.set(true);
1445 }
1446
1447 private void doDetachEngine() {
1448 mActiveEngines.remove(mEngine);
1449 mEngine.detach();
1450 }
1451
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001452 @Override
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001453 public void executeMessage(Message message) {
wilsonshihb72ff9c2019-03-21 17:27:02 +08001454 if (mDetached.get()) {
1455 if (mActiveEngines.contains(mEngine)) {
1456 doDetachEngine();
1457 }
1458 return;
1459 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001460 switch (message.what) {
1461 case DO_ATTACH: {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001462 try {
wilsonshihde93f492018-11-01 21:23:40 +08001463 mConnection.attachEngine(this, mDisplayId);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001464 } catch (RemoteException e) {
1465 Log.w(TAG, "Wallpaper host disappeared", e);
1466 return;
1467 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001468 Engine engine = onCreateEngine();
1469 mEngine = engine;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001470 mActiveEngines.add(engine);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001471 engine.attach(this);
1472 return;
1473 }
1474 case DO_DETACH: {
wilsonshihb72ff9c2019-03-21 17:27:02 +08001475 doDetachEngine();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001476 return;
1477 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001478 case DO_SET_DESIRED_SIZE: {
1479 mEngine.doDesiredSizeChanged(message.arg1, message.arg2);
1480 return;
1481 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001482 case DO_SET_DISPLAY_PADDING: {
1483 mEngine.doDisplayPaddingChanged((Rect) message.obj);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001484 return;
1485 }
1486 case DO_IN_AMBIENT_MODE: {
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001487 mEngine.doAmbientModeChanged(message.arg1 != 0, (Long) message.obj);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001488 return;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001489 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001490 case MSG_UPDATE_SURFACE:
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001491 mEngine.updateSurface(true, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001492 break;
Santiago Etchebehere44a28312020-01-14 15:27:11 -08001493 case MSG_SCALE:
1494 mEngine.setZoom(Float.intBitsToFloat(message.arg1));
1495 break;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001496 case MSG_VISIBILITY_CHANGED:
1497 if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
1498 + ": " + message.arg1);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001499 mEngine.doVisibilityChanged(message.arg1 != 0);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001500 break;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001501 case MSG_WALLPAPER_OFFSETS: {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001502 mEngine.doOffsetsChanged(true);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001503 } break;
Dianne Hackborn75804932009-10-20 20:15:20 -07001504 case MSG_WALLPAPER_COMMAND: {
1505 WallpaperCommand cmd = (WallpaperCommand)message.obj;
1506 mEngine.doCommand(cmd);
1507 } break;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001508 case MSG_WINDOW_RESIZED: {
1509 final boolean reportDraw = message.arg1 != 0;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001510 mEngine.updateSurface(true, false, reportDraw);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001511 mEngine.doOffsetsChanged(true);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001512 } break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07001513 case MSG_WINDOW_MOVED: {
1514 // Do nothing. What does it mean for a Wallpaper to move?
1515 } break;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001516 case MSG_TOUCH_EVENT: {
Jeff Brown840db1f2010-10-21 17:36:54 -07001517 boolean skip = false;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001518 MotionEvent ev = (MotionEvent)message.obj;
Jeff Brown840db1f2010-10-21 17:36:54 -07001519 if (ev.getAction() == MotionEvent.ACTION_MOVE) {
1520 synchronized (mEngine.mLock) {
1521 if (mEngine.mPendingMove == ev) {
1522 mEngine.mPendingMove = null;
1523 } else {
1524 // this is not the motion event we are looking for....
1525 skip = true;
1526 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001527 }
1528 }
Jeff Brown840db1f2010-10-21 17:36:54 -07001529 if (!skip) {
1530 if (DEBUG) Log.v(TAG, "Delivering touch event: " + ev);
1531 mEngine.onTouchEvent(ev);
1532 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001533 ev.recycle();
1534 } break;
Lucas Dupin50ba9912017-07-14 11:55:05 -07001535 case MSG_REQUEST_WALLPAPER_COLORS: {
1536 if (mConnection == null) {
1537 break;
1538 }
1539 try {
wilsonshih36597d42018-12-05 18:56:39 +08001540 mConnection.onWallpaperColorsChanged(mEngine.onComputeColors(), mDisplayId);
Lucas Dupin50ba9912017-07-14 11:55:05 -07001541 } catch (RemoteException e) {
1542 // Connection went away, nothing to do in here.
1543 }
1544 } break;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001545 default :
1546 Log.w(TAG, "Unknown message type " + message.what);
1547 }
1548 }
1549 }
1550
1551 /**
1552 * Implements the internal {@link IWallpaperService} interface to convert
1553 * incoming calls to it back to calls on an {@link WallpaperService}.
1554 */
1555 class IWallpaperServiceWrapper extends IWallpaperService.Stub {
1556 private final WallpaperService mTarget;
wilsonshihb72ff9c2019-03-21 17:27:02 +08001557 private IWallpaperEngineWrapper mEngineWrapper;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001558
1559 public IWallpaperServiceWrapper(WallpaperService context) {
1560 mTarget = context;
1561 }
1562
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001563 @Override
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001564 public void attach(IWallpaperConnection conn, IBinder windowToken,
wilsonshihde93f492018-11-01 21:23:40 +08001565 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
1566 int displayId) {
wilsonshihb72ff9c2019-03-21 17:27:02 +08001567 mEngineWrapper = new IWallpaperEngineWrapper(mTarget, conn, windowToken,
wilsonshihde93f492018-11-01 21:23:40 +08001568 windowType, isPreview, reqWidth, reqHeight, padding, displayId);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001569 }
wilsonshihb72ff9c2019-03-21 17:27:02 +08001570
1571 @Override
1572 public void detach() {
1573 mEngineWrapper.detach();
1574 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001575 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001576
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001577 @Override
1578 public void onCreate() {
1579 super.onCreate();
1580 }
1581
1582 @Override
1583 public void onDestroy() {
1584 super.onDestroy();
1585 for (int i=0; i<mActiveEngines.size(); i++) {
1586 mActiveEngines.get(i).detach();
1587 }
1588 mActiveEngines.clear();
1589 }
1590
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001591 /**
1592 * Implement to return the implementation of the internal accessibility
1593 * service interface. Subclasses should not override.
1594 */
1595 @Override
1596 public final IBinder onBind(Intent intent) {
1597 return new IWallpaperServiceWrapper(this);
1598 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001599
Dianne Hackborn23ef7b42009-11-18 18:20:39 -08001600 /**
1601 * Must be implemented to return a new instance of the wallpaper's engine.
1602 * Note that multiple instances may be active at the same time, such as
1603 * when the wallpaper is currently set as the active wallpaper and the user
1604 * is in the wallpaper picker viewing a preview of it as well.
1605 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001606 public abstract Engine onCreateEngine();
Dianne Hackborn527de8e2011-08-22 16:10:36 -07001607
1608 @Override
1609 protected void dump(FileDescriptor fd, PrintWriter out, String[] args) {
1610 out.print("State of wallpaper "); out.print(this); out.println(":");
1611 for (int i=0; i<mActiveEngines.size(); i++) {
1612 Engine engine = mActiveEngines.get(i);
1613 out.print(" Engine "); out.print(engine); out.println(":");
1614 engine.dump(" ", fd, out, args);
1615 }
1616 }
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001617}