blob: d5c67668b88ea8ed5df6e7d057731c17e15e1d28 [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;
Lucas Dupin4c8c3272018-11-06 17:47:48 -080022import android.annotation.SystemApi;
Mathew Inwoode3807372018-08-10 09:51:03 +010023import android.annotation.UnsupportedAppUsage;
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;
wilsonshih8ccb9ce2018-12-04 11:44:31 +080028import android.content.Context;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070029import android.content.Intent;
Lucas Dupin84b89d92017-05-09 12:16:19 -070030import android.content.res.TypedArray;
31import android.graphics.Bitmap;
32import android.graphics.Canvas;
Mathias Agopian62bf4a02010-09-08 16:32:27 -070033import android.graphics.PixelFormat;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070034import android.graphics.Rect;
Lucas Dupin84b89d92017-05-09 12:16:19 -070035import android.graphics.drawable.Drawable;
Jeff Brown3d110b22014-11-21 19:01:13 -080036import android.hardware.display.DisplayManager;
37import android.hardware.display.DisplayManager.DisplayListener;
Mathew Inwood31755f92018-12-20 13:53:36 +000038import android.os.Build;
Dianne Hackborn75804932009-10-20 20:15:20 -070039import android.os.Bundle;
Lucas Dupin65b47652017-07-19 17:32:26 -070040import android.os.Handler;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070041import android.os.IBinder;
Dianne Hackborn19382ac2009-09-11 21:13:37 -070042import android.os.Looper;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070043import android.os.Message;
44import android.os.RemoteException;
Lucas Dupin65b47652017-07-19 17:32:26 -070045import android.os.SystemClock;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070046import android.util.Log;
Lucas Dupin84b89d92017-05-09 12:16:19 -070047import android.util.MergedConfiguration;
Craig Mautner6881a102012-07-27 13:04:51 -070048import android.view.Display;
Adrian Roos5c6b6222017-11-07 17:36:10 +010049import android.view.DisplayCutout;
Valentin Iftime6239e532018-08-24 17:17:26 +020050import android.view.DisplayInfo;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070051import android.view.Gravity;
52import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -070053import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -070054import android.view.InputDevice;
Jeff Brown4952dfd2011-11-30 19:23:22 -080055import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -080056import android.view.InputEventReceiver;
wilsonshih8ccb9ce2018-12-04 11:44:31 +080057import android.view.InsetsState;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -070058import android.view.MotionEvent;
Robert Carr5fea55b2018-12-10 13:05:52 -080059import android.view.SurfaceControl;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070060import android.view.SurfaceHolder;
61import android.view.View;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -070062import android.view.ViewGroup;
Lucas Dupin84b89d92017-05-09 12:16:19 -070063import android.view.WindowInsets;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070064import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -070065import android.view.WindowManagerGlobal;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070066
Lucas Dupin65b47652017-07-19 17:32:26 -070067import com.android.internal.annotations.VisibleForTesting;
Lucas Dupin84b89d92017-05-09 12:16:19 -070068import com.android.internal.os.HandlerCaller;
69import com.android.internal.view.BaseIWindow;
70import com.android.internal.view.BaseSurfaceHolder;
71
Dianne Hackborn527de8e2011-08-22 16:10:36 -070072import java.io.FileDescriptor;
73import java.io.PrintWriter;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -080074import java.util.ArrayList;
wilsonshihb72ff9c2019-03-21 17:27:02 +080075import java.util.concurrent.atomic.AtomicBoolean;
Lucas Dupin65b47652017-07-19 17:32:26 -070076import java.util.function.Supplier;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -080077
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070078/**
79 * A wallpaper service is responsible for showing a live wallpaper behind
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080080 * applications that would like to sit on top of it. This service object
81 * itself does very little -- its only purpose is to generate instances of
Dianne Hackborne4260f42009-11-18 21:15:59 -080082 * {@link Engine} as needed. Implementing a wallpaper thus
Dianne Hackborn23ef7b42009-11-18 18:20:39 -080083 * involves subclassing from this, subclassing an Engine implementation,
84 * and implementing {@link #onCreateEngine()} to return a new instance of
85 * your engine.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070086 */
87public abstract class WallpaperService extends Service {
88 /**
89 * The {@link Intent} that must be declared as handled by the service.
Dianne Hackbornd6847842010-01-12 18:14:19 -080090 * To be supported, the service must also require the
91 * {@link android.Manifest.permission#BIND_WALLPAPER} permission so
92 * that other applications can not abuse it.
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070093 */
Dianne Hackbornd6847842010-01-12 18:14:19 -080094 @SdkConstant(SdkConstantType.SERVICE_ACTION)
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070095 public static final String SERVICE_INTERFACE =
Dianne Hackbornd6847842010-01-12 18:14:19 -080096 "android.service.wallpaper.WallpaperService";
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070097
Dianne Hackborneb034652009-09-07 00:49:58 -070098 /**
99 * Name under which a WallpaperService component publishes information
100 * about itself. This meta-data must reference an XML resource containing
101 * a <code>&lt;{@link android.R.styleable#Wallpaper wallpaper}&gt;</code>
102 * tag.
103 */
104 public static final String SERVICE_META_DATA = "android.service.wallpaper";
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800105
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700106 static final String TAG = "WallpaperService";
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700107 static final boolean DEBUG = false;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700108
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700109 private static final int DO_ATTACH = 10;
110 private static final int DO_DETACH = 20;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700111 private static final int DO_SET_DESIRED_SIZE = 30;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700112 private static final int DO_SET_DISPLAY_PADDING = 40;
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700113 private static final int DO_IN_AMBIENT_MODE = 50;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700114
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700115 private static final int MSG_UPDATE_SURFACE = 10000;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700116 private static final int MSG_VISIBILITY_CHANGED = 10010;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700117 private static final int MSG_WALLPAPER_OFFSETS = 10020;
Dianne Hackborn75804932009-10-20 20:15:20 -0700118 private static final int MSG_WALLPAPER_COMMAND = 10025;
Mathew Inwoode3807372018-08-10 09:51:03 +0100119 @UnsupportedAppUsage
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700120 private static final int MSG_WINDOW_RESIZED = 10030;
Craig Mautner5702d4d2012-06-30 14:10:16 -0700121 private static final int MSG_WINDOW_MOVED = 10035;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700122 private static final int MSG_TOUCH_EVENT = 10040;
Lucas Dupin50ba9912017-07-14 11:55:05 -0700123 private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
Lucas Dupin65b47652017-07-19 17:32:26 -0700124
125 private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
126
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -0800127 private final ArrayList<Engine> mActiveEngines
128 = new ArrayList<Engine>();
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700129
Dianne Hackborn75804932009-10-20 20:15:20 -0700130 static final class WallpaperCommand {
131 String action;
132 int x;
133 int y;
134 int z;
135 Bundle extras;
136 boolean sync;
137 }
wilsonshih81e10a72018-11-15 10:54:21 +0800138
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700139 /**
140 * The actual implementation of a wallpaper. A wallpaper service may
141 * have multiple instances running (for example as a real wallpaper
142 * and as a preview), each of which is represented by its own Engine
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700143 * instance. You must implement {@link WallpaperService#onCreateEngine()}
144 * to return your concrete Engine implementation.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700145 */
146 public class Engine {
147 IWallpaperEngineWrapper mIWallpaperEngine;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700148
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700149 // Copies from mIWallpaperEngine.
150 HandlerCaller mCaller;
151 IWallpaperConnection mConnection;
152 IBinder mWindowToken;
wilsonshih81e10a72018-11-15 10:54:21 +0800153
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700154 boolean mInitializing = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700155 boolean mVisible;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700156 boolean mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700157 boolean mDestroyed;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700158
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700159 // Current window state.
160 boolean mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700161 boolean mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700162 boolean mIsCreating;
163 boolean mDrawingAllowed;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700164 boolean mOffsetsChanged;
Jeff Sharkey35be7562012-04-18 19:16:15 -0700165 boolean mFixedSizeAllowed;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700166 int mWidth;
167 int mHeight;
168 int mFormat;
169 int mType;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700170 int mCurWidth;
171 int mCurHeight;
Lucas Dupin6155aa42018-09-05 11:15:52 -0700172 int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700173 int mWindowPrivateFlags =
174 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700175 int mCurWindowFlags = mWindowFlags;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700176 int mCurWindowPrivateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700177 final Rect mVisibleInsets = new Rect();
178 final Rect mWinFrame = new Rect();
179 final Rect mContentInsets = new Rect();
Adrian Roosfa104232014-06-20 16:10:14 -0700180 final Rect mStableInsets = new Rect();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700181 final Rect mDispatchedContentInsets = new Rect();
182 final Rect mDispatchedStableInsets = new Rect();
183 final Rect mFinalSystemInsets = new Rect();
184 final Rect mFinalStableInsets = new Rect();
Jorim Jaggi2e95a482016-01-14 17:36:55 -0800185 final Rect mBackdropFrame = new Rect();
Adrian Roos5c6b6222017-11-07 17:36:10 +0100186 final DisplayCutout.ParcelableWrapper mDisplayCutout =
187 new DisplayCutout.ParcelableWrapper();
188 DisplayCutout mDispatchedDisplayCutout = DisplayCutout.NO_CUTOUT;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200189 final InsetsState mInsetsState = new InsetsState();
Andrii Kulian44607962017-03-16 11:06:24 -0700190 final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700191
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700192 final WindowManager.LayoutParams mLayout
193 = new WindowManager.LayoutParams();
194 IWindowSession mSession;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700195
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700196 final Object mLock = new Object();
197 boolean mOffsetMessageEnqueued;
Mathew Inwood31755f92018-12-20 13:53:36 +0000198 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700199 float mPendingXOffset;
200 float mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800201 float mPendingXOffsetStep;
202 float mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700203 boolean mPendingSync;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700204 MotionEvent mPendingMove;
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700205 boolean mIsInAmbientMode;
Jeff Brown3d110b22014-11-21 19:01:13 -0800206
Lucas Dupin65b47652017-07-19 17:32:26 -0700207 // Needed for throttling onComputeColors.
208 private long mLastColorInvalidation;
209 private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
Lucas Dupin416fe952017-08-14 10:58:40 -0700210 private final Supplier<Long> mClockFunction;
211 private final Handler mHandler;
Lucas Dupin65b47652017-07-19 17:32:26 -0700212
wilsonshih8ccb9ce2018-12-04 11:44:31 +0800213 private Display mDisplay;
214 private Context mDisplayContext;
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700215 private int mDisplayState;
Jeff Brown3d110b22014-11-21 19:01:13 -0800216
Robert Carr5fea55b2018-12-10 13:05:52 -0800217 SurfaceControl mSurfaceControl = new SurfaceControl();
218
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700219 final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700220 {
Jeff Brown24572372011-06-09 19:05:15 -0700221 mRequestedFormat = PixelFormat.RGBX_8888;
Mathias Agopian62bf4a02010-09-08 16:32:27 -0700222 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700223
224 @Override
225 public boolean onAllowLockCanvas() {
226 return mDrawingAllowed;
227 }
228
229 @Override
230 public void onRelayoutContainer() {
231 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
232 mCaller.sendMessage(msg);
233 }
234
235 @Override
236 public void onUpdateSurface() {
237 Message msg = mCaller.obtainMessage(MSG_UPDATE_SURFACE);
238 mCaller.sendMessage(msg);
239 }
240
241 public boolean isCreating() {
242 return mIsCreating;
243 }
244
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800245 @Override
246 public void setFixedSize(int width, int height) {
Jeff Sharkey35be7562012-04-18 19:16:15 -0700247 if (!mFixedSizeAllowed) {
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800248 // Regular apps can't do this. It can only work for
249 // certain designs of window animations, so you can't
250 // rely on it.
251 throw new UnsupportedOperationException(
252 "Wallpapers currently only support sizing from layout");
253 }
Michael Jurkab8f939f2011-02-01 20:50:30 -0800254 super.setFixedSize(width, height);
Dianne Hackborna48a37f2011-02-01 16:30:38 -0800255 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700256
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700257 public void setKeepScreenOn(boolean screenOn) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700258 throw new UnsupportedOperationException(
259 "Wallpapers do not support keep screen on");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700260 }
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700261
John Reck6bc70142016-10-26 16:49:17 -0700262 private void prepareToDraw() {
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700263 if (mDisplayState == Display.STATE_DOZE
264 || mDisplayState == Display.STATE_DOZE_SUSPEND) {
265 try {
266 mSession.pokeDrawLock(mWindow);
267 } catch (RemoteException e) {
268 // System server died, can be ignored.
269 }
270 }
John Reck6bc70142016-10-26 16:49:17 -0700271 }
272
273 @Override
274 public Canvas lockCanvas() {
275 prepareToDraw();
Filip Gruszczynski4544b922015-04-16 13:18:58 -0700276 return super.lockCanvas();
277 }
John Reck6bc70142016-10-26 16:49:17 -0700278
279 @Override
280 public Canvas lockCanvas(Rect dirty) {
281 prepareToDraw();
282 return super.lockCanvas(dirty);
283 }
284
285 @Override
286 public Canvas lockHardwareCanvas() {
287 prepareToDraw();
288 return super.lockHardwareCanvas();
289 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700290 };
Jeff Brown32cbc38552011-12-01 14:01:49 -0800291
292 final class WallpaperInputEventReceiver extends InputEventReceiver {
293 public WallpaperInputEventReceiver(InputChannel inputChannel, Looper looper) {
294 super(inputChannel, looper);
295 }
296
Jeff Brown46b9ac02010-04-22 18:58:52 -0700297 @Override
Siarhei Vishniakou85ddfff2018-01-31 16:49:36 -0800298 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700299 boolean handled = false;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700300 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800301 if (event instanceof MotionEvent
302 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800303 MotionEvent dup = MotionEvent.obtainNoHistory((MotionEvent)event);
304 dispatchPointer(dup);
Jeff Brown3915bb82010-11-05 15:02:16 -0700305 handled = true;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700306 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700307 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800308 finishInputEvent(event, handled);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700309 }
310 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800311 }
312 WallpaperInputEventReceiver mInputEventReceiver;
313
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700314 final BaseIWindow mWindow = new BaseIWindow() {
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700315 @Override
Jorim Jaggif081f062019-10-24 16:24:54 +0200316 public void resized(Rect frame, Rect contentInsets,
317 Rect visibleInsets, Rect stableInsets, boolean reportDraw,
Andrii Kulian44607962017-03-16 11:06:24 -0700318 MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout,
Brad Stenninge0573692019-03-11 13:52:46 -0700319 boolean alwaysConsumeSystemBars, int displayId,
Adrian Roos5c6b6222017-11-07 17:36:10 +0100320 DisplayCutout.ParcelableWrapper displayCutout) {
Jorim Jaggif081f062019-10-24 16:24:54 +0200321 Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
322 reportDraw ? 1 : 0);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700323 mCaller.sendMessage(msg);
324 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700325
326 @Override
327 public void moved(int newX, int newY) {
328 Message msg = mCaller.obtainMessageII(MSG_WINDOW_MOVED, newX, newY);
329 mCaller.sendMessage(msg);
330 }
331
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700332 @Override
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700333 public void dispatchAppVisibility(boolean visible) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700334 // We don't do this in preview mode; we'll let the preview
335 // activity tell us when to run.
336 if (!mIWallpaperEngine.mIsPreview) {
337 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
338 visible ? 1 : 0);
339 mCaller.sendMessage(msg);
340 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700341 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700342
343 @Override
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800344 public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
345 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700346 synchronized (mLock) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700347 if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700348 mPendingXOffset = x;
349 mPendingYOffset = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800350 mPendingXOffsetStep = xStep;
351 mPendingYOffsetStep = yStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700352 if (sync) {
353 mPendingSync = true;
354 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700355 if (!mOffsetMessageEnqueued) {
356 mOffsetMessageEnqueued = true;
357 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
358 mCaller.sendMessage(msg);
359 }
360 }
361 }
Craig Mautner5702d4d2012-06-30 14:10:16 -0700362
363 @Override
Dianne Hackborn75804932009-10-20 20:15:20 -0700364 public void dispatchWallpaperCommand(String action, int x, int y,
365 int z, Bundle extras, boolean sync) {
366 synchronized (mLock) {
367 if (DEBUG) Log.v(TAG, "Dispatch wallpaper command: " + x + ", " + y);
368 WallpaperCommand cmd = new WallpaperCommand();
369 cmd.action = action;
370 cmd.x = x;
371 cmd.y = y;
372 cmd.z = z;
373 cmd.extras = extras;
374 cmd.sync = sync;
375 Message msg = mCaller.obtainMessage(MSG_WALLPAPER_COMMAND);
376 msg.obj = cmd;
377 mCaller.sendMessage(msg);
378 }
379 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700380 };
Lucas Dupin416fe952017-08-14 10:58:40 -0700381
382 /**
383 * Default constructor
384 */
385 public Engine() {
386 this(SystemClock::elapsedRealtime, Handler.getMain());
387 }
388
389 /**
390 * Constructor used for test purposes.
391 *
392 * @param clockFunction Supplies current times in millis.
393 * @param handler Used for posting/deferring asynchronous calls.
394 * @hide
395 */
396 @VisibleForTesting
397 public Engine(Supplier<Long> clockFunction, Handler handler) {
398 mClockFunction = clockFunction;
399 mHandler = handler;
400 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700401
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700402 /**
403 * Provides access to the surface in which this wallpaper is drawn.
404 */
405 public SurfaceHolder getSurfaceHolder() {
406 return mSurfaceHolder;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700407 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700408
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700409 /**
410 * Convenience for {@link WallpaperManager#getDesiredMinimumWidth()
411 * WallpaperManager.getDesiredMinimumWidth()}, returning the width
412 * that the system would like this wallpaper to run in.
413 */
414 public int getDesiredMinimumWidth() {
415 return mIWallpaperEngine.mReqWidth;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700416 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700417
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700418 /**
419 * Convenience for {@link WallpaperManager#getDesiredMinimumHeight()
420 * WallpaperManager.getDesiredMinimumHeight()}, returning the height
421 * that the system would like this wallpaper to run in.
422 */
423 public int getDesiredMinimumHeight() {
424 return mIWallpaperEngine.mReqHeight;
425 }
wilsonshih81e10a72018-11-15 10:54:21 +0800426
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700427 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700428 * Return whether the wallpaper is currently visible to the user,
429 * this is the last value supplied to
430 * {@link #onVisibilityChanged(boolean)}.
431 */
432 public boolean isVisible() {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700433 return mReportedVisible;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700434 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700435
Dianne Hackborn284ac932009-08-28 10:34:25 -0700436 /**
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700437 * Returns true if this engine is running in preview mode -- that is,
438 * it is being shown to the user before they select it as the actual
439 * wallpaper.
440 */
441 public boolean isPreview() {
442 return mIWallpaperEngine.mIsPreview;
443 }
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700444
445 /**
446 * Returns true if this engine is running in ambient mode -- that is,
Lucas Dupin8f09a502018-07-27 16:47:45 +0800447 * it is being shown in low power mode, on always on display.
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800448 * @hide
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700449 */
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800450 @SystemApi
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700451 public boolean isInAmbientMode() {
452 return mIsInAmbientMode;
453 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700454
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700455 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700456 * Control whether this wallpaper will receive raw touch events
457 * from the window manager as the user interacts with the window
458 * that is currently displaying the wallpaper. By default they
459 * are turned off. If enabled, the events will be received in
460 * {@link #onTouchEvent(MotionEvent)}.
461 */
462 public void setTouchEventsEnabled(boolean enabled) {
463 mWindowFlags = enabled
464 ? (mWindowFlags&~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
465 : (mWindowFlags|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
466 if (mCreated) {
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700467 updateSurface(false, false, false);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700468 }
469 }
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700470
471 /**
472 * Control whether this wallpaper will receive notifications when the wallpaper
473 * has been scrolled. By default, wallpapers will receive notifications, although
474 * the default static image wallpapers do not. It is a performance optimization to
475 * set this to false.
476 *
477 * @param enabled whether the wallpaper wants to receive offset notifications
478 */
479 public void setOffsetNotificationsEnabled(boolean enabled) {
480 mWindowPrivateFlags = enabled
481 ? (mWindowPrivateFlags |
482 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS)
483 : (mWindowPrivateFlags &
484 ~WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS);
485 if (mCreated) {
486 updateSurface(false, false, false);
487 }
488 }
Jeff Sharkey35be7562012-04-18 19:16:15 -0700489
490 /** {@hide} */
Mathew Inwoode3807372018-08-10 09:51:03 +0100491 @UnsupportedAppUsage
Jeff Sharkey35be7562012-04-18 19:16:15 -0700492 public void setFixedSizeAllowed(boolean allowed) {
493 mFixedSizeAllowed = allowed;
494 }
495
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700496 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700497 * Called once to initialize the engine. After returning, the
498 * engine's surface will be created by the framework.
499 */
500 public void onCreate(SurfaceHolder surfaceHolder) {
501 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700502
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700503 /**
504 * Called right before the engine is going away. After this the
505 * surface will be destroyed and this Engine object is no longer
506 * valid.
507 */
508 public void onDestroy() {
509 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700510
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700511 /**
512 * Called to inform you of the wallpaper becoming visible or
513 * hidden. <em>It is very important that a wallpaper only use
514 * CPU while it is visible.</em>.
515 */
516 public void onVisibilityChanged(boolean visible) {
517 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700518
519 /**
520 * Called with the current insets that are in effect for the wallpaper.
521 * This gives you the part of the overall wallpaper surface that will
522 * generally be visible to the user (ignoring position offsets applied to it).
523 *
524 * @param insets Insets to apply.
525 */
526 public void onApplyWindowInsets(WindowInsets insets) {
527 }
528
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700529 /**
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700530 * Called as the user performs touch-screen interaction with the
531 * window that is currently showing this wallpaper. Note that the
532 * events you receive here are driven by the actual application the
Marco Nelissenae87bd02009-09-17 09:44:43 -0700533 * user is interacting with, so if it is slow you will get fewer
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700534 * move events.
535 */
536 public void onTouchEvent(MotionEvent event) {
537 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700538
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700539 /**
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700540 * Called to inform you of the wallpaper's offsets changing
541 * within its contain, corresponding to the container's
542 * call to {@link WallpaperManager#setWallpaperOffsets(IBinder, float, float)
543 * WallpaperManager.setWallpaperOffsets()}.
544 */
545 public void onOffsetsChanged(float xOffset, float yOffset,
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800546 float xOffsetStep, float yOffsetStep,
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700547 int xPixelOffset, int yPixelOffset) {
548 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700549
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700550 /**
Dianne Hackborn75804932009-10-20 20:15:20 -0700551 * Process a command that was sent to the wallpaper with
Dianne Hackborn13bf82602009-11-05 21:45:51 -0800552 * {@link WallpaperManager#sendWallpaperCommand}.
Dianne Hackborn75804932009-10-20 20:15:20 -0700553 * The default implementation does nothing, and always returns null
554 * as the result.
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700555 *
Dianne Hackborn75804932009-10-20 20:15:20 -0700556 * @param action The name of the command to perform. This tells you
557 * what to do and how to interpret the rest of the arguments.
558 * @param x Generic integer parameter.
559 * @param y Generic integer parameter.
560 * @param z Generic integer parameter.
561 * @param extras Any additional parameters.
562 * @param resultRequested If true, the caller is requesting that
563 * a result, appropriate for the command, be returned back.
564 * @return If returning a result, create a Bundle and place the
565 * result data in to it. Otherwise return null.
566 */
567 public Bundle onCommand(String action, int x, int y, int z,
568 Bundle extras, boolean resultRequested) {
569 return null;
570 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700571
Dianne Hackborn75804932009-10-20 20:15:20 -0700572 /**
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700573 * Called when the device enters or exits ambient mode.
574 *
575 * @param inAmbientMode {@code true} if in ambient mode.
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800576 * @param animationDuration How long the transition animation to change the ambient state
577 * should run, in milliseconds. If 0 is passed as the argument
578 * here, the state should be switched immediately.
Lucas Dupin8f09a502018-07-27 16:47:45 +0800579 *
580 * @see #isInAmbientMode()
581 * @see WallpaperInfo#supportsAmbientMode()
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800582 * @hide
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700583 */
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800584 @SystemApi
585 public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700586 }
587
588 /**
Dianne Hackborn284ac932009-08-28 10:34:25 -0700589 * Called when an application has changed the desired virtual size of
590 * the wallpaper.
591 */
592 public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
593 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700594
Dianne Hackborn284ac932009-08-28 10:34:25 -0700595 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700596 * Convenience for {@link SurfaceHolder.Callback#surfaceChanged
597 * SurfaceHolder.Callback.surfaceChanged()}.
598 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700599 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
600 }
601
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700602 /**
Dianne Hackborn1d28f9c2010-07-13 20:38:06 -0700603 * Convenience for {@link SurfaceHolder.Callback2#surfaceRedrawNeeded
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700604 * SurfaceHolder.Callback.surfaceRedrawNeeded()}.
605 */
606 public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
607 }
608
609 /**
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700610 * Convenience for {@link SurfaceHolder.Callback#surfaceCreated
611 * SurfaceHolder.Callback.surfaceCreated()}.
612 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700613 public void onSurfaceCreated(SurfaceHolder holder) {
614 }
615
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700616 /**
617 * Convenience for {@link SurfaceHolder.Callback#surfaceDestroyed
618 * SurfaceHolder.Callback.surfaceDestroyed()}.
619 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700620 public void onSurfaceDestroyed(SurfaceHolder holder) {
621 }
Lucas Dupinc40608c2017-04-14 18:33:08 -0700622
623 /**
624 * Notifies the engine that wallpaper colors changed significantly.
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700625 * This will trigger a {@link #onComputeColors()} call.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700626 */
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700627 public void notifyColorsChanged() {
Lucas Dupin65b47652017-07-19 17:32:26 -0700628 final long now = mClockFunction.get();
Lucas Dupin65b47652017-07-19 17:32:26 -0700629 if (now - mLastColorInvalidation < NOTIFY_COLORS_RATE_LIMIT_MS) {
630 Log.w(TAG, "This call has been deferred. You should only call "
631 + "notifyColorsChanged() once every "
632 + (NOTIFY_COLORS_RATE_LIMIT_MS / 1000f) + " seconds.");
Lucas Dupin416fe952017-08-14 10:58:40 -0700633 if (!mHandler.hasCallbacks(mNotifyColorsChanged)) {
634 mHandler.postDelayed(mNotifyColorsChanged, NOTIFY_COLORS_RATE_LIMIT_MS);
Lucas Dupin65b47652017-07-19 17:32:26 -0700635 }
636 return;
637 }
638 mLastColorInvalidation = now;
Lucas Dupin416fe952017-08-14 10:58:40 -0700639 mHandler.removeCallbacks(mNotifyColorsChanged);
Lucas Dupin65b47652017-07-19 17:32:26 -0700640
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700641 try {
Lucas Dupin65b47652017-07-19 17:32:26 -0700642 final WallpaperColors newColors = onComputeColors();
643 if (mConnection != null) {
wilsonshih36597d42018-12-05 18:56:39 +0800644 mConnection.onWallpaperColorsChanged(newColors, mDisplay.getDisplayId());
Lucas Dupin65b47652017-07-19 17:32:26 -0700645 } else {
646 Log.w(TAG, "Can't notify system because wallpaper connection "
647 + "was not established.");
648 }
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700649 } catch (RemoteException e) {
Lucas Dupin65b47652017-07-19 17:32:26 -0700650 Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700651 }
Lucas Dupinc40608c2017-04-14 18:33:08 -0700652 }
653
654 /**
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700655 * Called by the system when it needs to know what colors the wallpaper is using.
Lucas Dupin65b47652017-07-19 17:32:26 -0700656 * You might return null if no color information is available at the moment.
657 * In that case you might want to call {@link #notifyColorsChanged()} when
658 * color information becomes available.
Lucas Dupin84b89d92017-05-09 12:16:19 -0700659 * <p>
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700660 * The simplest way of creating a {@link android.app.WallpaperColors} object is by using
Lucas Dupin84b89d92017-05-09 12:16:19 -0700661 * {@link android.app.WallpaperColors#fromBitmap(Bitmap)} or
662 * {@link android.app.WallpaperColors#fromDrawable(Drawable)}, but you can also specify
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700663 * your main colors by constructing a {@link android.app.WallpaperColors} object manually.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700664 *
Lucas Dupin84b89d92017-05-09 12:16:19 -0700665 * @return Wallpaper colors.
Lucas Dupinc40608c2017-04-14 18:33:08 -0700666 */
Lucas Dupin98eabbd2017-07-19 17:32:26 -0700667 public @Nullable WallpaperColors onComputeColors() {
Lucas Dupinc40608c2017-04-14 18:33:08 -0700668 return null;
669 }
Lucas Dupinea1fb1e2017-04-05 17:39:44 -0700670
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700671 /**
672 * Sets internal engine state. Only for testing.
673 * @param created {@code true} or {@code false}.
674 * @hide
675 */
676 @VisibleForTesting
677 public void setCreated(boolean created) {
678 mCreated = created;
679 }
680
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700681 protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
682 out.print(prefix); out.print("mInitializing="); out.print(mInitializing);
683 out.print(" mDestroyed="); out.println(mDestroyed);
684 out.print(prefix); out.print("mVisible="); out.print(mVisible);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700685 out.print(" mReportedVisible="); out.println(mReportedVisible);
Jeff Brown3d110b22014-11-21 19:01:13 -0800686 out.print(prefix); out.print("mDisplay="); out.println(mDisplay);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700687 out.print(prefix); out.print("mCreated="); out.print(mCreated);
688 out.print(" mSurfaceCreated="); out.print(mSurfaceCreated);
689 out.print(" mIsCreating="); out.print(mIsCreating);
690 out.print(" mDrawingAllowed="); out.println(mDrawingAllowed);
691 out.print(prefix); out.print("mWidth="); out.print(mWidth);
692 out.print(" mCurWidth="); out.print(mCurWidth);
693 out.print(" mHeight="); out.print(mHeight);
694 out.print(" mCurHeight="); out.println(mCurHeight);
695 out.print(prefix); out.print("mType="); out.print(mType);
696 out.print(" mWindowFlags="); out.print(mWindowFlags);
697 out.print(" mCurWindowFlags="); out.println(mCurWindowFlags);
Dianne Hackbornd052a942014-11-21 15:23:13 -0800698 out.print(prefix); out.print("mWindowPrivateFlags="); out.print(mWindowPrivateFlags);
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700699 out.print(" mCurWindowPrivateFlags="); out.println(mCurWindowPrivateFlags);
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700700 out.print(prefix); out.print("mVisibleInsets=");
701 out.print(mVisibleInsets.toShortString());
702 out.print(" mWinFrame="); out.print(mWinFrame.toShortString());
703 out.print(" mContentInsets="); out.println(mContentInsets.toShortString());
Andrii Kulian44607962017-03-16 11:06:24 -0700704 out.print(prefix); out.print("mConfiguration=");
705 out.println(mMergedConfiguration.getMergedConfiguration());
Dianne Hackborn527de8e2011-08-22 16:10:36 -0700706 out.print(prefix); out.print("mLayout="); out.println(mLayout);
707 synchronized (mLock) {
708 out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
709 out.print(" mPendingXOffset="); out.println(mPendingXOffset);
710 out.print(prefix); out.print("mPendingXOffsetStep=");
711 out.print(mPendingXOffsetStep);
712 out.print(" mPendingXOffsetStep="); out.println(mPendingXOffsetStep);
713 out.print(prefix); out.print("mOffsetMessageEnqueued=");
714 out.print(mOffsetMessageEnqueued);
715 out.print(" mPendingSync="); out.println(mPendingSync);
716 if (mPendingMove != null) {
717 out.print(prefix); out.print("mPendingMove="); out.println(mPendingMove);
718 }
719 }
720 }
721
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700722 private void dispatchPointer(MotionEvent event) {
Jeff Brown33bbfd22011-02-24 20:55:35 -0800723 if (event.isTouchEvent()) {
724 synchronized (mLock) {
725 if (event.getAction() == MotionEvent.ACTION_MOVE) {
726 mPendingMove = event;
727 } else {
728 mPendingMove = null;
729 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700730 }
Jeff Brown33bbfd22011-02-24 20:55:35 -0800731 Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
732 mCaller.sendMessage(msg);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700733 } else {
734 event.recycle();
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700735 }
736 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700737
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700738 void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700739 if (mDestroyed) {
740 Log.w(TAG, "Ignoring updateSurface: destroyed");
741 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700742
743 boolean fixedSize = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700744 int myWidth = mSurfaceHolder.getRequestedWidth();
Romain Guy980a9382010-01-08 15:06:28 -0800745 if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700746 else fixedSize = true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700747 int myHeight = mSurfaceHolder.getRequestedHeight();
Romain Guy980a9382010-01-08 15:06:28 -0800748 if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700749 else fixedSize = true;
750
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700751 final boolean creating = !mCreated;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700752 final boolean surfaceCreating = !mSurfaceCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700753 final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700754 boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700755 boolean insetsChanged = !mCreated;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700756 final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700757 final boolean flagsChanged = mCurWindowFlags != mWindowFlags ||
758 mCurWindowPrivateFlags != mWindowPrivateFlags;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700759 if (forceRelayout || creating || surfaceCreating || formatChanged || sizeChanged
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -0700760 || typeChanged || flagsChanged || redrawNeeded
761 || !mIWallpaperEngine.mShownReported) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700762
Dianne Hackborn284ac932009-08-28 10:34:25 -0700763 if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700764 + " format=" + formatChanged + " size=" + sizeChanged);
765
766 try {
767 mWidth = myWidth;
768 mHeight = myHeight;
769 mFormat = mSurfaceHolder.getRequestedFormat();
770 mType = mSurfaceHolder.getRequestedType();
771
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700772 mLayout.x = 0;
773 mLayout.y = 0;
Valentin Iftime6239e532018-08-24 17:17:26 +0200774
775 if (!fixedSize) {
776 mLayout.width = myWidth;
777 mLayout.height = myHeight;
778 } else {
779 // Force the wallpaper to cover the screen in both dimensions
780 // only internal implementations like ImageWallpaper
781 DisplayInfo displayInfo = new DisplayInfo();
782 mDisplay.getDisplayInfo(displayInfo);
wilsonshih3b2683a2019-01-19 17:01:19 +0800783 final float layoutScale = Math.max(
784 (float) displayInfo.logicalHeight / (float) myHeight,
785 (float) displayInfo.logicalWidth / (float) myWidth);
786 mLayout.height = (int) (myHeight * layoutScale);
787 mLayout.width = (int) (myWidth * layoutScale);
Lucas Dupin6155aa42018-09-05 11:15:52 -0700788 mWindowFlags |= WindowManager.LayoutParams.FLAG_SCALED;
Valentin Iftime6239e532018-08-24 17:17:26 +0200789 }
790
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700791 mLayout.format = mFormat;
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700792
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700793 mCurWindowFlags = mWindowFlags;
794 mLayout.flags = mWindowFlags
795 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
Jorim Jaggi526505d2016-05-24 00:29:19 -0700796 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700797 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
Lucas Dupin6155aa42018-09-05 11:15:52 -0700798 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700799 mCurWindowPrivateFlags = mWindowPrivateFlags;
800 mLayout.privateFlags = mWindowPrivateFlags;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700801
802 mLayout.memoryType = mType;
803 mLayout.token = mWindowToken;
804
805 if (!mCreated) {
Filip Gruszczynskid66ba062015-03-23 12:59:02 -0700806 // Retrieve watch round info
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700807 TypedArray windowStyle = obtainStyledAttributes(
808 com.android.internal.R.styleable.Window);
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700809 windowStyle.recycle();
810
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700811 // Add window
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700812 mLayout.type = mIWallpaperEngine.mWindowType;
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -0700813 mLayout.gravity = Gravity.START|Gravity.TOP;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -0700814 mLayout.setTitle(WallpaperService.this.getClass().getName());
Dianne Hackborn284ac932009-08-28 10:34:25 -0700815 mLayout.windowAnimations =
816 com.android.internal.R.style.Animation_Wallpaper;
Arthur Hung12a06ce2019-07-22 15:35:17 +0800817 InputChannel inputChannel = new InputChannel();
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200818
Craig Mautner6881a102012-07-27 13:04:51 -0700819 if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE,
wilsonshihde93f492018-11-01 21:23:40 +0800820 mDisplay.getDisplayId(), mWinFrame, mContentInsets, mStableInsets,
Jorim Jaggif081f062019-10-24 16:24:54 +0200821 mDisplayCutout, inputChannel,
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200822 mInsetsState) < 0) {
Mattias Peterssond9463f52011-01-12 15:38:55 +0100823 Log.w(TAG, "Failed to add window while updating wallpaper surface.");
824 return;
825 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700826 mCreated = true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700827
Jeff Brown32cbc38552011-12-01 14:01:49 -0800828 mInputEventReceiver = new WallpaperInputEventReceiver(
Arthur Hung12a06ce2019-07-22 15:35:17 +0800829 inputChannel, Looper.myLooper());
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700830 }
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700831
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700832 mSurfaceHolder.mSurfaceLock.lock();
833 mDrawingAllowed = true;
834
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700835 if (!fixedSize) {
836 mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
837 } else {
838 mLayout.surfaceInsets.set(0, 0, 0, 0);
839 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700840 final int relayoutResult = mSession.relayout(
Dianne Hackborn9a230e02011-10-06 11:51:27 -0700841 mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
Jorim Jaggif081f062019-10-24 16:24:54 +0200842 View.VISIBLE, 0, -1, mWinFrame, mContentInsets,
843 mVisibleInsets, mStableInsets, mBackdropFrame,
Robert Carr5fea55b2018-12-10 13:05:52 -0800844 mDisplayCutout, mMergedConfiguration, mSurfaceControl,
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200845 mInsetsState);
Robert Carr5fea55b2018-12-10 13:05:52 -0800846 if (mSurfaceControl.isValid()) {
847 mSurfaceHolder.mSurface.copyFrom(mSurfaceControl);
848 mSurfaceControl.release();
849 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700850
Dianne Hackborn284ac932009-08-28 10:34:25 -0700851 if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700852 + ", frame=" + mWinFrame);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700853
Adrian Roos2ae38052014-12-09 17:03:01 +0000854 int w = mWinFrame.width();
855 int h = mWinFrame.height();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700856
857 if (!fixedSize) {
858 final Rect padding = mIWallpaperEngine.mDisplayPadding;
Jorim Jaggif081f062019-10-24 16:24:54 +0200859 w += padding.left + padding.right;
860 h += padding.top + padding.bottom;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700861 mContentInsets.left += padding.left;
862 mContentInsets.top += padding.top;
863 mContentInsets.right += padding.right;
864 mContentInsets.bottom += padding.bottom;
865 mStableInsets.left += padding.left;
866 mStableInsets.top += padding.top;
867 mStableInsets.right += padding.right;
868 mStableInsets.bottom += padding.bottom;
Adrian Roos5c6b6222017-11-07 17:36:10 +0100869 mDisplayCutout.set(mDisplayCutout.get().inset(-padding.left, -padding.top,
870 -padding.right, -padding.bottom));
Valentin Iftime6239e532018-08-24 17:17:26 +0200871 } else {
872 w = myWidth;
873 h = myHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700874 }
875
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700876 if (mCurWidth != w) {
877 sizeChanged = true;
878 mCurWidth = w;
879 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700880 if (mCurHeight != h) {
881 sizeChanged = true;
882 mCurHeight = h;
883 }
Jeff Brown30bc34f2011-01-25 12:56:56 -0800884
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700885 if (DEBUG) {
886 Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight);
887 }
888
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700889 insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
890 insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
Adrian Roos5c6b6222017-11-07 17:36:10 +0100891 insetsChanged |= !mDispatchedDisplayCutout.equals(mDisplayCutout.get());
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700892
Jeff Brown30bc34f2011-01-25 12:56:56 -0800893 mSurfaceHolder.setSurfaceFrameSize(w, h);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700894 mSurfaceHolder.mSurfaceLock.unlock();
895
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700896 if (!mSurfaceHolder.mSurface.isValid()) {
897 reportSurfaceDestroyed();
898 if (DEBUG) Log.v(TAG, "Layout: Surface destroyed");
899 return;
900 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700901
902 boolean didSurface = false;
903
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700904 try {
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700905 mSurfaceHolder.ungetCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700906
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700907 if (surfaceCreating) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700908 mIsCreating = true;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700909 didSurface = true;
Dianne Hackborn284ac932009-08-28 10:34:25 -0700910 if (DEBUG) Log.v(TAG, "onSurfaceCreated("
911 + mSurfaceHolder + "): " + this);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700912 onSurfaceCreated(mSurfaceHolder);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700913 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700914 if (callbacks != null) {
915 for (SurfaceHolder.Callback c : callbacks) {
916 c.surfaceCreated(mSurfaceHolder);
917 }
918 }
919 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700920
Jeff Brown98365d72012-08-19 20:30:52 -0700921 redrawNeeded |= creating || (relayoutResult
922 & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700923
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700924 if (forceReport || creating || surfaceCreating
925 || formatChanged || sizeChanged) {
Dianne Hackborncbf15042009-08-18 18:29:09 -0700926 if (DEBUG) {
927 RuntimeException e = new RuntimeException();
928 e.fillInStackTrace();
929 Log.w(TAG, "forceReport=" + forceReport + " creating=" + creating
930 + " formatChanged=" + formatChanged
931 + " sizeChanged=" + sizeChanged, e);
932 }
Dianne Hackborn284ac932009-08-28 10:34:25 -0700933 if (DEBUG) Log.v(TAG, "onSurfaceChanged("
934 + mSurfaceHolder + ", " + mFormat
935 + ", " + mCurWidth + ", " + mCurHeight
936 + "): " + this);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700937 didSurface = true;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700938 onSurfaceChanged(mSurfaceHolder, mFormat,
939 mCurWidth, mCurHeight);
Dianne Hackborndc8a7f62010-05-10 11:29:34 -0700940 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700941 if (callbacks != null) {
942 for (SurfaceHolder.Callback c : callbacks) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700943 c.surfaceChanged(mSurfaceHolder, mFormat,
944 mCurWidth, mCurHeight);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700945 }
946 }
947 }
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700948
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700949 if (insetsChanged) {
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700950 mDispatchedContentInsets.set(mContentInsets);
951 mDispatchedStableInsets.set(mStableInsets);
Adrian Roos5c6b6222017-11-07 17:36:10 +0100952 mDispatchedDisplayCutout = mDisplayCutout.get();
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700953 mFinalStableInsets.set(mDispatchedStableInsets);
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700954 WindowInsets insets = new WindowInsets(mFinalSystemInsets,
Jorim Jaggi297985a2018-11-30 17:24:58 +0100955 mFinalStableInsets,
Adrian Roosd4970af2017-11-10 15:48:01 +0100956 getResources().getConfiguration().isScreenRound(), false,
Adrian Roos5c6b6222017-11-07 17:36:10 +0100957 mDispatchedDisplayCutout);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700958 if (DEBUG) {
959 Log.v(TAG, "dispatching insets=" + insets);
960 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700961 onApplyWindowInsets(insets);
962 }
963
Dianne Hackbornd76b67c2010-07-13 17:48:30 -0700964 if (redrawNeeded) {
965 onSurfaceRedrawNeeded(mSurfaceHolder);
966 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
967 if (callbacks != null) {
968 for (SurfaceHolder.Callback c : callbacks) {
969 if (c instanceof SurfaceHolder.Callback2) {
970 ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
971 mSurfaceHolder);
972 }
973 }
974 }
975 }
976
Dianne Hackborn9e4e7272011-08-30 14:06:51 -0700977 if (didSurface && !mReportedVisible) {
978 // This wallpaper is currently invisible, but its
979 // surface has changed. At this point let's tell it
980 // again that it is invisible in case the report about
981 // the surface caused it to start running. We really
982 // don't want wallpapers running when not visible.
983 if (mIsCreating) {
984 // Some wallpapers will ignore this call if they
985 // had previously been told they were invisble,
986 // so if we are creating a new surface then toggle
987 // the state to get them to notice.
988 if (DEBUG) Log.v(TAG, "onVisibilityChanged(true) at surface: "
989 + this);
990 onVisibilityChanged(true);
991 }
992 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false) at surface: "
993 + this);
994 onVisibilityChanged(false);
995 }
996
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700997 } finally {
998 mIsCreating = false;
Dianne Hackborn18ee31e2010-04-27 15:54:02 -0700999 mSurfaceCreated = true;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001000 if (redrawNeeded) {
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001001 mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001002 }
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001003 mIWallpaperEngine.reportShown();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001004 }
1005 } catch (RemoteException ex) {
1006 }
1007 if (DEBUG) Log.v(
1008 TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
1009 " w=" + mLayout.width + " h=" + mLayout.height);
1010 }
1011 }
Lucas Dupin65b47652017-07-19 17:32:26 -07001012
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001013 void attach(IWallpaperEngineWrapper wrapper) {
Dianne Hackborncbf15042009-08-18 18:29:09 -07001014 if (DEBUG) Log.v(TAG, "attach: " + this + " wrapper=" + wrapper);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001015 if (mDestroyed) {
1016 return;
1017 }
wilsonshihde93f492018-11-01 21:23:40 +08001018
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001019 mIWallpaperEngine = wrapper;
1020 mCaller = wrapper.mCaller;
1021 mConnection = wrapper.mConnection;
1022 mWindowToken = wrapper.mWindowToken;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001023 mSurfaceHolder.setSizeFromLayout();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001024 mInitializing = true;
Jeff Brownf9e989d2013-04-04 23:04:03 -07001025 mSession = WindowManagerGlobal.getWindowSession();
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001026
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001027 mWindow.setSession(mSession);
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -07001028
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001029 mLayout.packageName = getPackageName();
wilsonshih81e10a72018-11-15 10:54:21 +08001030 mIWallpaperEngine.mDisplayManager.registerDisplayListener(mDisplayListener,
1031 mCaller.getHandler());
1032 mDisplay = mIWallpaperEngine.mDisplay;
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001033 mDisplayContext = createDisplayContext(mDisplay);
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001034 mDisplayState = mDisplay.getState();
Dianne Hackborn9fe6cb52011-09-09 13:02:43 -07001035
Dianne Hackborn284ac932009-08-28 10:34:25 -07001036 if (DEBUG) Log.v(TAG, "onCreate(): " + this);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001037 onCreate(mSurfaceHolder);
wilsonshih81e10a72018-11-15 10:54:21 +08001038
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001039 mInitializing = false;
wilsonshih81e10a72018-11-15 10:54:21 +08001040
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001041 mReportedVisible = false;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001042 updateSurface(false, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001043 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001044
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001045 /**
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001046 * The {@link Context} with resources that match the current display the wallpaper is on.
1047 * For multiple display environment, multiple engines can be created to render on each
1048 * display, but these displays may have different densities. Use this context to get the
1049 * corresponding resources for currently display, avoiding the context of the service.
wilsonshihfd058f62019-02-13 15:57:06 +08001050 * <p>
1051 * The display context will never be {@code null} after
1052 * {@link Engine#onCreate(SurfaceHolder)} has been called.
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001053 *
1054 * @return A {@link Context} for current display.
1055 */
wilsonshihfd058f62019-02-13 15:57:06 +08001056 @Nullable
wilsonshih8ccb9ce2018-12-04 11:44:31 +08001057 public Context getDisplayContext() {
1058 return mDisplayContext;
1059 }
1060
1061 /**
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001062 * Executes life cycle event and updates internal ambient mode state based on
1063 * message sent from handler.
1064 *
Lucas Dupin660d5732017-12-19 10:05:19 -08001065 * @param inAmbientMode {@code true} if in ambient mode.
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001066 * @param animationDuration For how long the transition will last, in ms.
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001067 * @hide
1068 */
1069 @VisibleForTesting
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001070 public void doAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001071 if (!mDestroyed) {
1072 if (DEBUG) {
Lucas Dupin660d5732017-12-19 10:05:19 -08001073 Log.v(TAG, "onAmbientModeChanged(" + inAmbientMode + ", "
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001074 + animationDuration + "): " + this);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001075 }
1076 mIsInAmbientMode = inAmbientMode;
1077 if (mCreated) {
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001078 onAmbientModeChanged(inAmbientMode, animationDuration);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001079 }
1080 }
1081 }
1082
Dianne Hackborn284ac932009-08-28 10:34:25 -07001083 void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
1084 if (!mDestroyed) {
1085 if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
1086 + desiredWidth + "," + desiredHeight + "): " + this);
Joe Onoratodcfae5c2010-10-28 18:03:23 -07001087 mIWallpaperEngine.mReqWidth = desiredWidth;
1088 mIWallpaperEngine.mReqHeight = desiredHeight;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001089 onDesiredSizeChanged(desiredWidth, desiredHeight);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001090 doOffsetsChanged(true);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001091 }
1092 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001093
1094 void doDisplayPaddingChanged(Rect padding) {
1095 if (!mDestroyed) {
1096 if (DEBUG) Log.v(TAG, "onDisplayPaddingChanged(" + padding + "): " + this);
1097 if (!mIWallpaperEngine.mDisplayPadding.equals(padding)) {
1098 mIWallpaperEngine.mDisplayPadding.set(padding);
1099 updateSurface(true, false, false);
1100 }
1101 }
1102 }
1103
Dianne Hackborn284ac932009-08-28 10:34:25 -07001104 void doVisibilityChanged(boolean visible) {
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001105 if (!mDestroyed) {
1106 mVisible = visible;
1107 reportVisibility();
1108 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001109 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001110
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001111 void reportVisibility() {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001112 if (!mDestroyed) {
Filip Gruszczynski4544b922015-04-16 13:18:58 -07001113 mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState();
1114 boolean visible = mVisible && mDisplayState != Display.STATE_OFF;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001115 if (mReportedVisible != visible) {
1116 mReportedVisible = visible;
1117 if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
1118 + "): " + this);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001119 if (visible) {
1120 // If becoming visible, in preview mode the surface
1121 // may have been destroyed so now we need to make
1122 // sure it is re-created.
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001123 doOffsetsChanged(false);
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001124 updateSurface(false, false, false);
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001125 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07001126 onVisibilityChanged(visible);
1127 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001128 }
1129 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001130
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001131 void doOffsetsChanged(boolean always) {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001132 if (mDestroyed) {
1133 return;
1134 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001135
1136 if (!always && !mOffsetsChanged) {
1137 return;
1138 }
1139
Dianne Hackborn284ac932009-08-28 10:34:25 -07001140 float xOffset;
1141 float yOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001142 float xOffsetStep;
1143 float yOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001144 boolean sync;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001145 synchronized (mLock) {
1146 xOffset = mPendingXOffset;
1147 yOffset = mPendingYOffset;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001148 xOffsetStep = mPendingXOffsetStep;
1149 yOffsetStep = mPendingYOffsetStep;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001150 sync = mPendingSync;
1151 mPendingSync = false;
Dianne Hackborn284ac932009-08-28 10:34:25 -07001152 mOffsetMessageEnqueued = false;
1153 }
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001154
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001155 if (mSurfaceCreated) {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001156 if (mReportedVisible) {
1157 if (DEBUG) Log.v(TAG, "Offsets change in " + this
1158 + ": " + xOffset + "," + yOffset);
1159 final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
1160 final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
1161 final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
1162 final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
1163 onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
1164 } else {
1165 mOffsetsChanged = true;
1166 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001167 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001168
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001169 if (sync) {
1170 try {
1171 if (DEBUG) Log.v(TAG, "Reporting offsets change complete");
1172 mSession.wallpaperOffsetsComplete(mWindow.asBinder());
1173 } catch (RemoteException e) {
1174 }
1175 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001176 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001177
Dianne Hackborn75804932009-10-20 20:15:20 -07001178 void doCommand(WallpaperCommand cmd) {
1179 Bundle result;
1180 if (!mDestroyed) {
1181 result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
1182 cmd.extras, cmd.sync);
1183 } else {
1184 result = null;
1185 }
1186 if (cmd.sync) {
1187 try {
1188 if (DEBUG) Log.v(TAG, "Reporting command complete");
1189 mSession.wallpaperCommandComplete(mWindow.asBinder(), result);
1190 } catch (RemoteException e) {
1191 }
1192 }
1193 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001194
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001195 void reportSurfaceDestroyed() {
1196 if (mSurfaceCreated) {
1197 mSurfaceCreated = false;
Dianne Hackborndc8a7f62010-05-10 11:29:34 -07001198 mSurfaceHolder.ungetCallbacks();
1199 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
1200 if (callbacks != null) {
1201 for (SurfaceHolder.Callback c : callbacks) {
1202 c.surfaceDestroyed(mSurfaceHolder);
1203 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001204 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001205 if (DEBUG) Log.v(TAG, "onSurfaceDestroyed("
1206 + mSurfaceHolder + "): " + this);
1207 onSurfaceDestroyed(mSurfaceHolder);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001208 }
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001209 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001210
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001211 void detach() {
1212 if (mDestroyed) {
1213 return;
1214 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001215
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001216 mDestroyed = true;
Jeff Brown3d110b22014-11-21 19:01:13 -08001217
wilsonshih81e10a72018-11-15 10:54:21 +08001218 if (mIWallpaperEngine.mDisplayManager != null) {
1219 mIWallpaperEngine.mDisplayManager.unregisterDisplayListener(mDisplayListener);
Jeff Brown3d110b22014-11-21 19:01:13 -08001220 }
1221
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001222 if (mVisible) {
1223 mVisible = false;
1224 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
1225 onVisibilityChanged(false);
1226 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001227
Dianne Hackborn18ee31e2010-04-27 15:54:02 -07001228 reportSurfaceDestroyed();
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001229
Dianne Hackborn284ac932009-08-28 10:34:25 -07001230 if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
1231 onDestroy();
Jeff Brown3d110b22014-11-21 19:01:13 -08001232
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001233 if (mCreated) {
1234 try {
Dianne Hackbornba3e31d2010-04-22 18:59:03 -07001235 if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
1236 + mSurfaceHolder.getSurface() + " of: " + this);
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001237
Jeff Brown32cbc38552011-12-01 14:01:49 -08001238 if (mInputEventReceiver != null) {
1239 mInputEventReceiver.dispose();
1240 mInputEventReceiver = null;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001241 }
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001242
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001243 mSession.remove(mWindow);
1244 } catch (RemoteException e) {
1245 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001246 mSurfaceHolder.mSurface.release();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001247 mCreated = false;
1248 }
1249 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001250
1251 private final DisplayListener mDisplayListener = new DisplayListener() {
1252 @Override
1253 public void onDisplayChanged(int displayId) {
1254 if (mDisplay.getDisplayId() == displayId) {
1255 reportVisibility();
1256 }
1257 }
1258
1259 @Override
1260 public void onDisplayRemoved(int displayId) {
1261 }
1262
1263 @Override
1264 public void onDisplayAdded(int displayId) {
1265 }
1266 };
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001267 }
Jeff Brown3d110b22014-11-21 19:01:13 -08001268
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001269 class IWallpaperEngineWrapper extends IWallpaperEngine.Stub
1270 implements HandlerCaller.Callback {
1271 private final HandlerCaller mCaller;
1272
1273 final IWallpaperConnection mConnection;
1274 final IBinder mWindowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001275 final int mWindowType;
1276 final boolean mIsPreview;
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001277 boolean mShownReported;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001278 int mReqWidth;
1279 int mReqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001280 final Rect mDisplayPadding = new Rect();
wilsonshih81e10a72018-11-15 10:54:21 +08001281 final int mDisplayId;
1282 final DisplayManager mDisplayManager;
1283 final Display mDisplay;
wilsonshihb72ff9c2019-03-21 17:27:02 +08001284 private final AtomicBoolean mDetached = new AtomicBoolean();
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001285
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001286 Engine mEngine;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001287
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001288 IWallpaperEngineWrapper(WallpaperService context,
1289 IWallpaperConnection conn, IBinder windowToken,
wilsonshihde93f492018-11-01 21:23:40 +08001290 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
1291 int displayId) {
Mita Yunaa8dc2e2012-12-10 18:32:03 -08001292 mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001293 mConnection = conn;
1294 mWindowToken = windowToken;
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001295 mWindowType = windowType;
1296 mIsPreview = isPreview;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001297 mReqWidth = reqWidth;
1298 mReqHeight = reqHeight;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001299 mDisplayPadding.set(padding);
wilsonshihde93f492018-11-01 21:23:40 +08001300 mDisplayId = displayId;
wilsonshih81e10a72018-11-15 10:54:21 +08001301
1302 // Create a display context before onCreateEngine.
1303 mDisplayManager = getSystemService(DisplayManager.class);
1304 mDisplay = mDisplayManager.getDisplay(mDisplayId);
1305
1306 if (mDisplay == null) {
1307 // Ignore this engine.
1308 throw new IllegalArgumentException("Cannot find display with id" + mDisplayId);
1309 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001310 Message msg = mCaller.obtainMessage(DO_ATTACH);
1311 mCaller.sendMessage(msg);
1312 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001313
Dianne Hackborn284ac932009-08-28 10:34:25 -07001314 public void setDesiredSize(int width, int height) {
1315 Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height);
1316 mCaller.sendMessage(msg);
1317 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001318
1319 public void setDisplayPadding(Rect padding) {
1320 Message msg = mCaller.obtainMessageO(DO_SET_DISPLAY_PADDING, padding);
1321 mCaller.sendMessage(msg);
1322 }
1323
Dianne Hackborn284ac932009-08-28 10:34:25 -07001324 public void setVisibility(boolean visible) {
1325 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
1326 visible ? 1 : 0);
1327 mCaller.sendMessage(msg);
1328 }
1329
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001330 @Override
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001331 public void setInAmbientMode(boolean inAmbientDisplay, long animationDuration)
Lucas Dupin660d5732017-12-19 10:05:19 -08001332 throws RemoteException {
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001333 Message msg = mCaller.obtainMessageIO(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0,
1334 animationDuration);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001335 mCaller.sendMessage(msg);
1336 }
1337
Dianne Hackborn6adba242009-11-10 11:10:09 -08001338 public void dispatchPointer(MotionEvent event) {
1339 if (mEngine != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001340 mEngine.dispatchPointer(event);
Jeff Brown32cbc38552011-12-01 14:01:49 -08001341 } else {
1342 event.recycle();
Dianne Hackborn6adba242009-11-10 11:10:09 -08001343 }
1344 }
Jeff Brown9f3bdfe2010-10-13 06:01:27 -07001345
1346 public void dispatchWallpaperCommand(String action, int x, int y,
1347 int z, Bundle extras) {
1348 if (mEngine != null) {
1349 mEngine.mWindow.dispatchWallpaperCommand(action, x, y, z, extras, false);
1350 }
1351 }
1352
Dianne Hackbornbce0cbb2012-10-05 11:06:53 -07001353 public void reportShown() {
1354 if (!mShownReported) {
1355 mShownReported = true;
1356 try {
1357 mConnection.engineShown(this);
1358 } catch (RemoteException e) {
1359 Log.w(TAG, "Wallpaper host disappeared", e);
1360 return;
1361 }
1362 }
1363 }
1364
Lucas Dupin50ba9912017-07-14 11:55:05 -07001365 public void requestWallpaperColors() {
1366 Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS);
1367 mCaller.sendMessage(msg);
1368 }
1369
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001370 public void destroy() {
1371 Message msg = mCaller.obtainMessage(DO_DETACH);
1372 mCaller.sendMessage(msg);
1373 }
1374
wilsonshihb72ff9c2019-03-21 17:27:02 +08001375 public void detach() {
1376 mDetached.set(true);
1377 }
1378
1379 private void doDetachEngine() {
1380 mActiveEngines.remove(mEngine);
1381 mEngine.detach();
1382 }
1383
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001384 @Override
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001385 public void executeMessage(Message message) {
wilsonshihb72ff9c2019-03-21 17:27:02 +08001386 if (mDetached.get()) {
1387 if (mActiveEngines.contains(mEngine)) {
1388 doDetachEngine();
1389 }
1390 return;
1391 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001392 switch (message.what) {
1393 case DO_ATTACH: {
Dianne Hackborn284ac932009-08-28 10:34:25 -07001394 try {
wilsonshihde93f492018-11-01 21:23:40 +08001395 mConnection.attachEngine(this, mDisplayId);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001396 } catch (RemoteException e) {
1397 Log.w(TAG, "Wallpaper host disappeared", e);
1398 return;
1399 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001400 Engine engine = onCreateEngine();
1401 mEngine = engine;
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001402 mActiveEngines.add(engine);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001403 engine.attach(this);
1404 return;
1405 }
1406 case DO_DETACH: {
wilsonshihb72ff9c2019-03-21 17:27:02 +08001407 doDetachEngine();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001408 return;
1409 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001410 case DO_SET_DESIRED_SIZE: {
1411 mEngine.doDesiredSizeChanged(message.arg1, message.arg2);
1412 return;
1413 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001414 case DO_SET_DISPLAY_PADDING: {
1415 mEngine.doDisplayPaddingChanged((Rect) message.obj);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001416 return;
1417 }
1418 case DO_IN_AMBIENT_MODE: {
Lucas Dupin4c8c3272018-11-06 17:47:48 -08001419 mEngine.doAmbientModeChanged(message.arg1 != 0, (Long) message.obj);
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001420 return;
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001421 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001422 case MSG_UPDATE_SURFACE:
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001423 mEngine.updateSurface(true, false, false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001424 break;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001425 case MSG_VISIBILITY_CHANGED:
1426 if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
1427 + ": " + message.arg1);
Dianne Hackborn284ac932009-08-28 10:34:25 -07001428 mEngine.doVisibilityChanged(message.arg1 != 0);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001429 break;
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001430 case MSG_WALLPAPER_OFFSETS: {
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001431 mEngine.doOffsetsChanged(true);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001432 } break;
Dianne Hackborn75804932009-10-20 20:15:20 -07001433 case MSG_WALLPAPER_COMMAND: {
1434 WallpaperCommand cmd = (WallpaperCommand)message.obj;
1435 mEngine.doCommand(cmd);
1436 } break;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001437 case MSG_WINDOW_RESIZED: {
1438 final boolean reportDraw = message.arg1 != 0;
Dianne Hackbornd76b67c2010-07-13 17:48:30 -07001439 mEngine.updateSurface(true, false, reportDraw);
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07001440 mEngine.doOffsetsChanged(true);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001441 } break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07001442 case MSG_WINDOW_MOVED: {
1443 // Do nothing. What does it mean for a Wallpaper to move?
1444 } break;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001445 case MSG_TOUCH_EVENT: {
Jeff Brown840db1f2010-10-21 17:36:54 -07001446 boolean skip = false;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001447 MotionEvent ev = (MotionEvent)message.obj;
Jeff Brown840db1f2010-10-21 17:36:54 -07001448 if (ev.getAction() == MotionEvent.ACTION_MOVE) {
1449 synchronized (mEngine.mLock) {
1450 if (mEngine.mPendingMove == ev) {
1451 mEngine.mPendingMove = null;
1452 } else {
1453 // this is not the motion event we are looking for....
1454 skip = true;
1455 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001456 }
1457 }
Jeff Brown840db1f2010-10-21 17:36:54 -07001458 if (!skip) {
1459 if (DEBUG) Log.v(TAG, "Delivering touch event: " + ev);
1460 mEngine.onTouchEvent(ev);
1461 }
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -07001462 ev.recycle();
1463 } break;
Lucas Dupin50ba9912017-07-14 11:55:05 -07001464 case MSG_REQUEST_WALLPAPER_COLORS: {
1465 if (mConnection == null) {
1466 break;
1467 }
1468 try {
wilsonshih36597d42018-12-05 18:56:39 +08001469 mConnection.onWallpaperColorsChanged(mEngine.onComputeColors(), mDisplayId);
Lucas Dupin50ba9912017-07-14 11:55:05 -07001470 } catch (RemoteException e) {
1471 // Connection went away, nothing to do in here.
1472 }
1473 } break;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001474 default :
1475 Log.w(TAG, "Unknown message type " + message.what);
1476 }
1477 }
1478 }
1479
1480 /**
1481 * Implements the internal {@link IWallpaperService} interface to convert
1482 * incoming calls to it back to calls on an {@link WallpaperService}.
1483 */
1484 class IWallpaperServiceWrapper extends IWallpaperService.Stub {
1485 private final WallpaperService mTarget;
wilsonshihb72ff9c2019-03-21 17:27:02 +08001486 private IWallpaperEngineWrapper mEngineWrapper;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001487
1488 public IWallpaperServiceWrapper(WallpaperService context) {
1489 mTarget = context;
1490 }
1491
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001492 @Override
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001493 public void attach(IWallpaperConnection conn, IBinder windowToken,
wilsonshihde93f492018-11-01 21:23:40 +08001494 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
1495 int displayId) {
wilsonshihb72ff9c2019-03-21 17:27:02 +08001496 mEngineWrapper = new IWallpaperEngineWrapper(mTarget, conn, windowToken,
wilsonshihde93f492018-11-01 21:23:40 +08001497 windowType, isPreview, reqWidth, reqHeight, padding, displayId);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001498 }
wilsonshihb72ff9c2019-03-21 17:27:02 +08001499
1500 @Override
1501 public void detach() {
1502 mEngineWrapper.detach();
1503 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001504 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001505
Dianne Hackbornaf1f42b2009-11-20 16:27:27 -08001506 @Override
1507 public void onCreate() {
1508 super.onCreate();
1509 }
1510
1511 @Override
1512 public void onDestroy() {
1513 super.onDestroy();
1514 for (int i=0; i<mActiveEngines.size(); i++) {
1515 mActiveEngines.get(i).detach();
1516 }
1517 mActiveEngines.clear();
1518 }
1519
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001520 /**
1521 * Implement to return the implementation of the internal accessibility
1522 * service interface. Subclasses should not override.
1523 */
1524 @Override
1525 public final IBinder onBind(Intent intent) {
1526 return new IWallpaperServiceWrapper(this);
1527 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -08001528
Dianne Hackborn23ef7b42009-11-18 18:20:39 -08001529 /**
1530 * Must be implemented to return a new instance of the wallpaper's engine.
1531 * Note that multiple instances may be active at the same time, such as
1532 * when the wallpaper is currently set as the active wallpaper and the user
1533 * is in the wallpaper picker viewing a preview of it as well.
1534 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001535 public abstract Engine onCreateEngine();
Dianne Hackborn527de8e2011-08-22 16:10:36 -07001536
1537 @Override
1538 protected void dump(FileDescriptor fd, PrintWriter out, String[] args) {
1539 out.print("State of wallpaper "); out.print(this); out.println(":");
1540 for (int i=0; i<mActiveEngines.size(); i++) {
1541 Engine engine = mActiveEngines.get(i);
1542 out.print(" Engine "); out.print(engine); out.println(":");
1543 engine.dump(" ", fd, out, args);
1544 }
1545 }
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001546}