Merge "Re-revert "Move wallpaper local color extraction to background"" into tm-qpr-dev am: 24ec31571b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21673561

Change-Id: Ib2123924312ce15efe191ee540e6e426842af436
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Aurélien Pomini
2023-03-02 19:14:34 +00:00
committed by Automerger Merge Worker

View File

@@ -61,7 +61,6 @@ import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
@@ -181,9 +180,6 @@ public abstract class WallpaperService extends Service {
private final ArrayList<Engine> mActiveEngines private final ArrayList<Engine> mActiveEngines
= new ArrayList<Engine>(); = new ArrayList<Engine>();
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
static final class WallpaperCommand { static final class WallpaperCommand {
String action; String action;
int x; int x;
@@ -202,6 +198,14 @@ public abstract class WallpaperService extends Service {
*/ */
public class Engine { public class Engine {
IWallpaperEngineWrapper mIWallpaperEngine; IWallpaperEngineWrapper mIWallpaperEngine;
final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
// 2D matrix [x][y] to represent a page of a portion of a window
EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
Bitmap mLastScreenshot;
int mLastWindowPage = -1;
private boolean mResetWindowPages;
// Copies from mIWallpaperEngine. // Copies from mIWallpaperEngine.
HandlerCaller mCaller; HandlerCaller mCaller;
@@ -263,27 +267,11 @@ public abstract class WallpaperService extends Service {
final Object mLock = new Object(); final Object mLock = new Object();
boolean mOffsetMessageEnqueued; boolean mOffsetMessageEnqueued;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
float mPendingXOffset; float mPendingXOffset;
float mPendingYOffset; float mPendingYOffset;
float mPendingXOffsetStep; float mPendingXOffsetStep;
float mPendingYOffsetStep; float mPendingYOffsetStep;
/**
* local color extraction related fields
* to be used by the background thread only (except the atomic boolean)
*/
final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
private long mLastProcessLocalColorsTimestamp;
private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
private int mPixelCopyCount = 0;
// 2D matrix [x][y] to represent a page of a portion of a window
EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
Bitmap mLastScreenshot;
private boolean mResetWindowPages;
boolean mPendingSync; boolean mPendingSync;
MotionEvent mPendingMove; MotionEvent mPendingMove;
boolean mIsInAmbientMode; boolean mIsInAmbientMode;
@@ -292,8 +280,12 @@ public abstract class WallpaperService extends Service {
private long mLastColorInvalidation; private long mLastColorInvalidation;
private final Runnable mNotifyColorsChanged = this::notifyColorsChanged; private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
// used to throttle processLocalColors
private long mLastProcessLocalColorsTimestamp;
private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
private final Supplier<Long> mClockFunction; private final Supplier<Long> mClockFunction;
private final Handler mHandler; private final Handler mHandler;
private Display mDisplay; private Display mDisplay;
private Context mDisplayContext; private Context mDisplayContext;
private int mDisplayState; private int mDisplayState;
@@ -833,7 +825,7 @@ public abstract class WallpaperService extends Service {
+ "was not established."); + "was not established.");
} }
mResetWindowPages = true; mResetWindowPages = true;
processLocalColors(); processLocalColors(mPendingXOffset, mPendingXOffsetStep);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e); Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
} }
@@ -1372,7 +1364,7 @@ public abstract class WallpaperService extends Service {
resetWindowPages(); resetWindowPages();
mSession.finishDrawing(mWindow, null /* postDrawTransaction */, mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
Integer.MAX_VALUE); Integer.MAX_VALUE);
processLocalColors(); processLocalColors(mPendingXOffset, mPendingXOffsetStep);
} }
reposition(); reposition();
reportEngineShown(shouldWaitForEngineShown()); reportEngineShown(shouldWaitForEngineShown());
@@ -1517,7 +1509,7 @@ public abstract class WallpaperService extends Service {
if (!mDestroyed) { if (!mDestroyed) {
mVisible = visible; mVisible = visible;
reportVisibility(); reportVisibility();
if (mReportedVisible) processLocalColors(); if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep);
} else { } else {
AnimationHandler.requestAnimatorsEnabled(visible, this); AnimationHandler.requestAnimatorsEnabled(visible, this);
} }
@@ -1601,41 +1593,31 @@ public abstract class WallpaperService extends Service {
} }
// setup local color extraction data // setup local color extraction data
processLocalColors(); processLocalColors(xOffset, xOffsetStep);
} }
/** /**
* Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of * Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of
* {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls. * {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls.
*/ */
private void processLocalColors() { private void processLocalColors(float xOffset, float xOffsetStep) {
if (mProcessLocalColorsPending.compareAndSet(false, true)) { if (mProcessLocalColorsPending.compareAndSet(false, true)) {
final long now = mClockFunction.get(); final long now = mClockFunction.get();
final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp; final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp;
final long timeToWait = Math.max(0, final long timeToWait = Math.max(0,
PROCESS_LOCAL_COLORS_INTERVAL_MS - timeSinceLastColorProcess); PROCESS_LOCAL_COLORS_INTERVAL_MS - timeSinceLastColorProcess);
mBackgroundHandler.postDelayed(() -> { mHandler.postDelayed(() -> {
mLastProcessLocalColorsTimestamp = now + timeToWait; mLastProcessLocalColorsTimestamp = now + timeToWait;
mProcessLocalColorsPending.set(false); mProcessLocalColorsPending.set(false);
processLocalColorsInternal(); processLocalColorsInternal(xOffset, xOffsetStep);
}, timeToWait); }, timeToWait);
} }
} }
private void processLocalColorsInternal() { private void processLocalColorsInternal(float xOffset, float xOffsetStep) {
// implemented by the wallpaper // implemented by the wallpaper
if (supportsLocalColorExtraction()) return; if (supportsLocalColorExtraction()) return;
assertBackgroundThread();
float xOffset;
float xOffsetStep;
float wallpaperDimAmount;
synchronized (mLock) {
xOffset = mPendingXOffset;
xOffsetStep = mPendingXOffsetStep;
wallpaperDimAmount = mWallpaperDimAmount;
}
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "processLocalColors " + xOffset + " of step " Log.d(TAG, "processLocalColors " + xOffset + " of step "
+ xOffsetStep); + xOffsetStep);
@@ -1698,7 +1680,7 @@ public abstract class WallpaperService extends Service {
xPage = mWindowPages.length - 1; xPage = mWindowPages.length - 1;
} }
current = mWindowPages[xPage]; current = mWindowPages[xPage];
updatePage(current, xPage, xPages, wallpaperDimAmount); updatePage(current, xPage, xPages, finalXOffsetStep);
Trace.endSection(); Trace.endSection();
} }
@@ -1718,23 +1700,16 @@ public abstract class WallpaperService extends Service {
} }
} }
/**
* Must be called with the surface lock held.
* Must not be called if the surface is not valid.
* Will unlock the surface when done using it.
*/
void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages, void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
float wallpaperDimAmount) { float xOffsetStep) {
assertBackgroundThread();
// in case the clock is zero, we start with negative time // in case the clock is zero, we start with negative time
long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION; long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION;
long lapsed = current - currentPage.getLastUpdateTime(); long lapsed = current - currentPage.getLastUpdateTime();
// Always update the page when the last update time is <= 0 // Always update the page when the last update time is <= 0
// This is important especially when the device first boots // This is important especially when the device first boots
if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) return; if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) {
return;
}
Surface surface = mSurfaceHolder.getSurface(); Surface surface = mSurfaceHolder.getSurface();
if (!surface.isValid()) return; if (!surface.isValid()) return;
boolean widthIsLarger = mSurfaceSize.x > mSurfaceSize.y; boolean widthIsLarger = mSurfaceSize.x > mSurfaceSize.y;
@@ -1750,42 +1725,33 @@ public abstract class WallpaperService extends Service {
Bitmap screenShot = Bitmap.createBitmap(width, height, Bitmap screenShot = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888); Bitmap.Config.ARGB_8888);
final Bitmap finalScreenShot = screenShot; final Bitmap finalScreenShot = screenShot;
final String pixelCopySectionName = "WallpaperService#pixelCopy"; Trace.beginSection("WallpaperService#pixelCopy");
final int pixelCopyCount = mPixelCopyCount++; PixelCopy.request(surface, screenShot, (res) -> {
Trace.beginAsyncSection(pixelCopySectionName, pixelCopyCount); Trace.endSection();
try { if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
PixelCopy.request(surface, screenShot, (res) -> { if (res != PixelCopy.SUCCESS) {
Trace.endAsyncSection(pixelCopySectionName, pixelCopyCount); Bitmap lastBitmap = currentPage.getBitmap();
if (DEBUG) Log.d(TAG, "result of pixel copy is " + res); // assign the last bitmap taken for now
if (res != PixelCopy.SUCCESS) { currentPage.setBitmap(mLastScreenshot);
Bitmap lastBitmap = currentPage.getBitmap(); Bitmap lastScreenshot = mLastScreenshot;
// assign the last bitmap taken for now if (lastScreenshot != null && !lastScreenshot.isRecycled()
currentPage.setBitmap(mLastScreenshot); && !Objects.equals(lastBitmap, lastScreenshot)) {
Bitmap lastScreenshot = mLastScreenshot; updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
if (lastScreenshot != null && !lastScreenshot.isRecycled()
&& !Objects.equals(lastBitmap, lastScreenshot)) {
updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
}
} else {
mLastScreenshot = finalScreenShot;
// going to hold this lock for a while
currentPage.setBitmap(finalScreenShot);
currentPage.setLastUpdateTime(current);
updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
} }
}, mBackgroundHandler); } else {
} catch (IllegalArgumentException e) { mLastScreenshot = finalScreenShot;
// this can potentially happen if the surface is invalidated right between the // going to hold this lock for a while
// surface.isValid() check and the PixelCopy operation. currentPage.setBitmap(finalScreenShot);
// in this case, stop: we'll compute colors on the next processLocalColors call. currentPage.setLastUpdateTime(current);
Log.i(TAG, "Cancelling processLocalColors: exception caught during PixelCopy"); updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
} }
}, mHandler);
} }
// locked by the passed page // locked by the passed page
private void updatePageColors( private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
EngineWindowPage page, int pageIndx, int numPages, float wallpaperDimAmount) { float xOffsetStep) {
if (page.getBitmap() == null) return; if (page.getBitmap() == null) return;
assertBackgroundThread();
Trace.beginSection("WallpaperService#updatePageColors"); Trace.beginSection("WallpaperService#updatePageColors");
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas " Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas "
@@ -1807,7 +1773,7 @@ public abstract class WallpaperService extends Service {
Log.e(TAG, "Error creating page local color bitmap", e); Log.e(TAG, "Error creating page local color bitmap", e);
continue; continue;
} }
WallpaperColors color = WallpaperColors.fromBitmap(target, wallpaperDimAmount); WallpaperColors color = WallpaperColors.fromBitmap(target, mWallpaperDimAmount);
target.recycle(); target.recycle();
WallpaperColors currentColor = page.getColors(area); WallpaperColors currentColor = page.getColors(area);
@@ -1824,26 +1790,17 @@ public abstract class WallpaperService extends Service {
+ " local color callback for area" + area + " for page " + pageIndx + " local color callback for area" + area + " for page " + pageIndx
+ " of " + numPages); + " of " + numPages);
} }
mHandler.post(() -> { try {
try { mConnection.onLocalWallpaperColorsChanged(area, color,
mConnection.onLocalWallpaperColorsChanged(area, color, mDisplayContext.getDisplayId());
mDisplayContext.getDisplayId()); } catch (RemoteException e) {
} catch (RemoteException e) { Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e); }
}
});
} }
} }
Trace.endSection(); Trace.endSection();
} }
private void assertBackgroundThread() {
if (!mBackgroundHandler.getLooper().isCurrentThread()) {
throw new IllegalStateException(
"ProcessLocalColors should be called from the background thread");
}
}
private RectF generateSubRect(RectF in, int pageInx, int numPages) { private RectF generateSubRect(RectF in, int pageInx, int numPages) {
float minLeft = (float) (pageInx) / (float) (numPages); float minLeft = (float) (pageInx) / (float) (numPages);
float maxRight = (float) (pageInx + 1) / (float) (numPages); float maxRight = (float) (pageInx + 1) / (float) (numPages);
@@ -1868,6 +1825,7 @@ public abstract class WallpaperService extends Service {
if (supportsLocalColorExtraction()) return; if (supportsLocalColorExtraction()) return;
if (!mResetWindowPages) return; if (!mResetWindowPages) return;
mResetWindowPages = false; mResetWindowPages = false;
mLastWindowPage = -1;
for (int i = 0; i < mWindowPages.length; i++) { for (int i = 0; i < mWindowPages.length; i++) {
mWindowPages[i].setLastUpdateTime(0L); mWindowPages[i].setLastUpdateTime(0L);
} }
@@ -1893,10 +1851,12 @@ public abstract class WallpaperService extends Service {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions); Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions);
} }
mBackgroundHandler.post(() -> { mHandler.post(() -> {
mLocalColorsToAdd.addAll(regions); mLocalColorsToAdd.addAll(regions);
processLocalColors(); processLocalColors(mPendingXOffset, mPendingYOffset);
}); });
} }
/** /**
@@ -1906,7 +1866,7 @@ public abstract class WallpaperService extends Service {
*/ */
public void removeLocalColorsAreas(@NonNull List<RectF> regions) { public void removeLocalColorsAreas(@NonNull List<RectF> regions) {
if (supportsLocalColorExtraction()) return; if (supportsLocalColorExtraction()) return;
mBackgroundHandler.post(() -> { mHandler.post(() -> {
float step = mPendingXOffsetStep; float step = mPendingXOffsetStep;
mLocalColorsToAdd.removeAll(regions); mLocalColorsToAdd.removeAll(regions);
mLocalColorAreas.removeAll(regions); mLocalColorAreas.removeAll(regions);
@@ -2537,9 +2497,6 @@ public abstract class WallpaperService extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
Trace.beginSection("WPMS.onCreate"); Trace.beginSection("WPMS.onCreate");
mBackgroundThread = new HandlerThread("DefaultWallpaperLocalColorExtractor");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
super.onCreate(); super.onCreate();
Trace.endSection(); Trace.endSection();
} }
@@ -2552,7 +2509,6 @@ public abstract class WallpaperService extends Service {
mActiveEngines.get(i).detach(); mActiveEngines.get(i).detach();
} }
mActiveEngines.clear(); mActiveEngines.clear();
mBackgroundThread.quitSafely();
Trace.endSection(); Trace.endSection();
} }