Merge "Partially move wallpaper local color extraction to background" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c59bcce7ec
@@ -61,6 +61,7 @@ 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;
|
||||||
@@ -96,6 +97,7 @@ import android.view.WindowManager;
|
|||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
import android.window.ClientWindowFrames;
|
import android.window.ClientWindowFrames;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.os.HandlerCaller;
|
import com.android.internal.os.HandlerCaller;
|
||||||
import com.android.internal.view.BaseIWindow;
|
import com.android.internal.view.BaseIWindow;
|
||||||
@@ -104,9 +106,10 @@ import com.android.internal.view.BaseSurfaceHolder;
|
|||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@@ -166,11 +169,12 @@ public abstract class WallpaperService extends Service {
|
|||||||
private static final int MSG_RESIZE_PREVIEW = 10110;
|
private static final int MSG_RESIZE_PREVIEW = 10110;
|
||||||
private static final int MSG_REPORT_SHOWN = 10150;
|
private static final int MSG_REPORT_SHOWN = 10150;
|
||||||
private static final int MSG_UPDATE_DIMMING = 10200;
|
private static final int MSG_UPDATE_DIMMING = 10200;
|
||||||
private static final List<Float> PROHIBITED_STEPS = Arrays.asList(0f, Float.POSITIVE_INFINITY,
|
|
||||||
Float.NEGATIVE_INFINITY);
|
|
||||||
|
|
||||||
|
/** limit calls to {@link Engine#onComputeColors} to at most once per second */
|
||||||
private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
|
private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
|
||||||
private static final int PROCESS_LOCAL_COLORS_INTERVAL_MS = 1000;
|
|
||||||
|
/** limit calls to {@link Engine#processLocalColorsInternal} to at most once per 2 seconds */
|
||||||
|
private static final int PROCESS_LOCAL_COLORS_INTERVAL_MS = 2000;
|
||||||
|
|
||||||
private static final boolean ENABLE_WALLPAPER_DIMMING =
|
private static final boolean ENABLE_WALLPAPER_DIMMING =
|
||||||
SystemProperties.getBoolean("persist.debug.enable_wallpaper_dimming", true);
|
SystemProperties.getBoolean("persist.debug.enable_wallpaper_dimming", true);
|
||||||
@@ -180,6 +184,9 @@ 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;
|
||||||
@@ -198,14 +205,6 @@ 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;
|
||||||
@@ -267,11 +266,34 @@ 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;
|
@GuardedBy("mLock")
|
||||||
float mPendingYOffset;
|
private float mPendingXOffset;
|
||||||
float mPendingXOffsetStep;
|
@GuardedBy("mLock")
|
||||||
float mPendingYOffsetStep;
|
private float mPendingYOffset;
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private float mPendingXOffsetStep;
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private float mPendingYOffsetStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* local color extraction related fields. When a user calls `addLocalColorAreas`
|
||||||
|
*/
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private 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
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
|
||||||
|
private Bitmap mLastScreenshot;
|
||||||
|
private boolean mResetWindowPages;
|
||||||
|
|
||||||
boolean mPendingSync;
|
boolean mPendingSync;
|
||||||
MotionEvent mPendingMove;
|
MotionEvent mPendingMove;
|
||||||
boolean mIsInAmbientMode;
|
boolean mIsInAmbientMode;
|
||||||
@@ -280,12 +302,8 @@ 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;
|
||||||
@@ -825,7 +843,7 @@ public abstract class WallpaperService extends Service {
|
|||||||
+ "was not established.");
|
+ "was not established.");
|
||||||
}
|
}
|
||||||
mResetWindowPages = true;
|
mResetWindowPages = true;
|
||||||
processLocalColors(mPendingXOffset, mPendingXOffsetStep);
|
processLocalColors();
|
||||||
} 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);
|
||||||
}
|
}
|
||||||
@@ -1361,10 +1379,9 @@ public abstract class WallpaperService extends Service {
|
|||||||
mIsCreating = false;
|
mIsCreating = false;
|
||||||
mSurfaceCreated = true;
|
mSurfaceCreated = true;
|
||||||
if (redrawNeeded) {
|
if (redrawNeeded) {
|
||||||
resetWindowPages();
|
|
||||||
mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
|
mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
|
||||||
Integer.MAX_VALUE);
|
Integer.MAX_VALUE);
|
||||||
processLocalColors(mPendingXOffset, mPendingXOffsetStep);
|
processLocalColors();
|
||||||
}
|
}
|
||||||
reposition();
|
reposition();
|
||||||
reportEngineShown(shouldWaitForEngineShown());
|
reportEngineShown(shouldWaitForEngineShown());
|
||||||
@@ -1509,7 +1526,7 @@ public abstract class WallpaperService extends Service {
|
|||||||
if (!mDestroyed) {
|
if (!mDestroyed) {
|
||||||
mVisible = visible;
|
mVisible = visible;
|
||||||
reportVisibility();
|
reportVisibility();
|
||||||
if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep);
|
if (mReportedVisible) processLocalColors();
|
||||||
} else {
|
} else {
|
||||||
AnimationHandler.requestAnimatorsEnabled(visible, this);
|
AnimationHandler.requestAnimatorsEnabled(visible, this);
|
||||||
}
|
}
|
||||||
@@ -1594,14 +1611,14 @@ public abstract class WallpaperService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup local color extraction data
|
// setup local color extraction data
|
||||||
processLocalColors(xOffset, xOffsetStep);
|
processLocalColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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(float xOffset, float xOffsetStep) {
|
private void processLocalColors() {
|
||||||
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;
|
||||||
@@ -1611,80 +1628,98 @@ public abstract class WallpaperService extends Service {
|
|||||||
mHandler.postDelayed(() -> {
|
mHandler.postDelayed(() -> {
|
||||||
mLastProcessLocalColorsTimestamp = now + timeToWait;
|
mLastProcessLocalColorsTimestamp = now + timeToWait;
|
||||||
mProcessLocalColorsPending.set(false);
|
mProcessLocalColorsPending.set(false);
|
||||||
processLocalColorsInternal(xOffset, xOffsetStep);
|
processLocalColorsInternal();
|
||||||
}, timeToWait);
|
}, timeToWait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processLocalColorsInternal(float xOffset, float xOffsetStep) {
|
/**
|
||||||
// implemented by the wallpaper
|
* Default implementation of the local color extraction.
|
||||||
|
* This will take a screenshot of the whole wallpaper on the main thread.
|
||||||
|
* Then, in a background thread, for each launcher page, for each area that needs color
|
||||||
|
* extraction in this page, creates a sub-bitmap and call {@link WallpaperColors#fromBitmap}
|
||||||
|
* to extract the colors. Every time a launcher page has been processed, call
|
||||||
|
* {@link #notifyLocalColorsChanged} with the color and areas of this page.
|
||||||
|
*/
|
||||||
|
private void processLocalColorsInternal() {
|
||||||
if (supportsLocalColorExtraction()) return;
|
if (supportsLocalColorExtraction()) return;
|
||||||
if (DEBUG) {
|
float xOffset;
|
||||||
Log.d(TAG, "processLocalColors " + xOffset + " of step "
|
float xOffsetStep;
|
||||||
+ xOffsetStep);
|
float wallpaperDimAmount;
|
||||||
}
|
int xPage;
|
||||||
//below is the default implementation
|
|
||||||
if (xOffset % xOffsetStep > MIN_PAGE_ALLOWED_MARGIN
|
|
||||||
|| !mSurfaceHolder.getSurface().isValid()) return;
|
|
||||||
int xCurrentPage;
|
|
||||||
int xPages;
|
int xPages;
|
||||||
if (!validStep(xOffsetStep)) {
|
Set<RectF> areas;
|
||||||
if (DEBUG) {
|
|
||||||
Log.w(TAG, "invalid offset step " + xOffsetStep);
|
|
||||||
}
|
|
||||||
xOffset = 0;
|
|
||||||
xOffsetStep = 1;
|
|
||||||
xCurrentPage = 0;
|
|
||||||
xPages = 1;
|
|
||||||
} else {
|
|
||||||
xPages = Math.round(1 / xOffsetStep) + 1;
|
|
||||||
xOffsetStep = (float) 1 / (float) xPages;
|
|
||||||
float shrink = (float) (xPages - 1) / (float) xPages;
|
|
||||||
xOffset *= shrink;
|
|
||||||
xCurrentPage = Math.round(xOffset / xOffsetStep);
|
|
||||||
}
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "xPages " + xPages + " xPage " + xCurrentPage);
|
|
||||||
Log.d(TAG, "xOffsetStep " + xOffsetStep + " xOffset " + xOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
float finalXOffsetStep = xOffsetStep;
|
|
||||||
float finalXOffset = xOffset;
|
|
||||||
|
|
||||||
Trace.beginSection("WallpaperService#processLocalColors");
|
|
||||||
resetWindowPages();
|
|
||||||
int xPage = xCurrentPage;
|
|
||||||
EngineWindowPage current;
|
EngineWindowPage current;
|
||||||
if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) {
|
|
||||||
mWindowPages = new EngineWindowPage[xPages];
|
synchronized (mLock) {
|
||||||
initWindowPages(mWindowPages, finalXOffsetStep);
|
xOffset = mPendingXOffset;
|
||||||
}
|
xOffsetStep = mPendingXOffsetStep;
|
||||||
if (mLocalColorsToAdd.size() != 0) {
|
wallpaperDimAmount = mWallpaperDimAmount;
|
||||||
for (RectF colorArea : mLocalColorsToAdd) {
|
|
||||||
if (!isValid(colorArea)) continue;
|
|
||||||
mLocalColorAreas.add(colorArea);
|
|
||||||
int colorPage = getRectFPage(colorArea, finalXOffsetStep);
|
|
||||||
EngineWindowPage currentPage = mWindowPages[colorPage];
|
|
||||||
currentPage.setLastUpdateTime(0);
|
|
||||||
currentPage.removeColor(colorArea);
|
|
||||||
}
|
|
||||||
mLocalColorsToAdd.clear();
|
|
||||||
}
|
|
||||||
if (xPage >= mWindowPages.length) {
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.e(TAG, "error xPage >= mWindowPages.length page: " + xPage);
|
Log.d(TAG, "processLocalColors " + xOffset + " of step "
|
||||||
Log.e(TAG, "error on page " + xPage + " out of " + xPages);
|
+ xOffsetStep);
|
||||||
Log.e(TAG,
|
|
||||||
"error on xOffsetStep " + finalXOffsetStep
|
|
||||||
+ " xOffset " + finalXOffset);
|
|
||||||
}
|
}
|
||||||
xPage = mWindowPages.length - 1;
|
if (xOffset % xOffsetStep > MIN_PAGE_ALLOWED_MARGIN
|
||||||
|
|| !mSurfaceHolder.getSurface().isValid()) return;
|
||||||
|
int xCurrentPage;
|
||||||
|
if (!validStep(xOffsetStep)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.w(TAG, "invalid offset step " + xOffsetStep);
|
||||||
|
}
|
||||||
|
xOffset = 0;
|
||||||
|
xOffsetStep = 1;
|
||||||
|
xCurrentPage = 0;
|
||||||
|
xPages = 1;
|
||||||
|
} else {
|
||||||
|
xPages = Math.round(1 / xOffsetStep) + 1;
|
||||||
|
xOffsetStep = (float) 1 / (float) xPages;
|
||||||
|
float shrink = (float) (xPages - 1) / (float) xPages;
|
||||||
|
xOffset *= shrink;
|
||||||
|
xCurrentPage = Math.round(xOffset / xOffsetStep);
|
||||||
|
}
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "xPages " + xPages + " xPage " + xCurrentPage);
|
||||||
|
Log.d(TAG, "xOffsetStep " + xOffsetStep + " xOffset " + xOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
float finalXOffsetStep = xOffsetStep;
|
||||||
|
float finalXOffset = xOffset;
|
||||||
|
|
||||||
|
resetWindowPages();
|
||||||
|
xPage = xCurrentPage;
|
||||||
|
if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) {
|
||||||
|
mWindowPages = new EngineWindowPage[xPages];
|
||||||
|
initWindowPages(mWindowPages, finalXOffsetStep);
|
||||||
|
}
|
||||||
|
if (mLocalColorsToAdd.size() != 0) {
|
||||||
|
for (RectF colorArea : mLocalColorsToAdd) {
|
||||||
|
if (!isValid(colorArea)) continue;
|
||||||
|
mLocalColorAreas.add(colorArea);
|
||||||
|
int colorPage = getRectFPage(colorArea, finalXOffsetStep);
|
||||||
|
EngineWindowPage currentPage = mWindowPages[colorPage];
|
||||||
|
currentPage.setLastUpdateTime(0);
|
||||||
|
currentPage.removeColor(colorArea);
|
||||||
|
}
|
||||||
|
mLocalColorsToAdd.clear();
|
||||||
|
}
|
||||||
|
if (xPage >= mWindowPages.length) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.e(TAG, "error xPage >= mWindowPages.length page: " + xPage);
|
||||||
|
Log.e(TAG, "error on page " + xPage + " out of " + xPages);
|
||||||
|
Log.e(TAG,
|
||||||
|
"error on xOffsetStep " + finalXOffsetStep
|
||||||
|
+ " xOffset " + finalXOffset);
|
||||||
|
}
|
||||||
|
xPage = mWindowPages.length - 1;
|
||||||
|
}
|
||||||
|
current = mWindowPages[xPage];
|
||||||
|
areas = new HashSet<>(current.getAreas());
|
||||||
}
|
}
|
||||||
current = mWindowPages[xPage];
|
updatePage(current, areas, xPage, xPages, wallpaperDimAmount);
|
||||||
updatePage(current, xPage, xPages, finalXOffsetStep);
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
private void initWindowPages(EngineWindowPage[] windowPages, float step) {
|
private void initWindowPages(EngineWindowPage[] windowPages, float step) {
|
||||||
for (int i = 0; i < windowPages.length; i++) {
|
for (int i = 0; i < windowPages.length; i++) {
|
||||||
windowPages[i] = new EngineWindowPage();
|
windowPages[i] = new EngineWindowPage();
|
||||||
@@ -1701,16 +1736,16 @@ public abstract class WallpaperService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
|
void updatePage(EngineWindowPage currentPage, Set<RectF> areas, int pageIndx, int numPages,
|
||||||
float xOffsetStep) {
|
float wallpaperDimAmount) {
|
||||||
|
|
||||||
// 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) {
|
if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) return;
|
||||||
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;
|
||||||
@@ -1723,43 +1758,59 @@ public abstract class WallpaperService extends Service {
|
|||||||
Log.e(TAG, "wrong width and height values of bitmap " + width + " " + height);
|
Log.e(TAG, "wrong width and height values of bitmap " + width + " " + height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final String pixelCopySectionName = "WallpaperService#pixelCopy";
|
||||||
|
final int pixelCopyCount = mPixelCopyCount++;
|
||||||
|
Trace.beginAsyncSection(pixelCopySectionName, pixelCopyCount);
|
||||||
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;
|
||||||
Trace.beginSection("WallpaperService#pixelCopy");
|
try {
|
||||||
PixelCopy.request(surface, screenShot, (res) -> {
|
// TODO(b/274427458) check if this can be done in the background.
|
||||||
Trace.endSection();
|
PixelCopy.request(surface, screenShot, (res) -> {
|
||||||
if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
|
Trace.endAsyncSection(pixelCopySectionName, pixelCopyCount);
|
||||||
if (res != PixelCopy.SUCCESS) {
|
if (DEBUG) {
|
||||||
Bitmap lastBitmap = currentPage.getBitmap();
|
Log.d(TAG, "result of pixel copy is: "
|
||||||
// assign the last bitmap taken for now
|
+ (res == PixelCopy.SUCCESS ? "SUCCESS" : "FAILURE"));
|
||||||
currentPage.setBitmap(mLastScreenshot);
|
|
||||||
Bitmap lastScreenshot = mLastScreenshot;
|
|
||||||
if (lastScreenshot != null && !lastScreenshot.isRecycled()
|
|
||||||
&& !Objects.equals(lastBitmap, lastScreenshot)) {
|
|
||||||
updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
|
|
||||||
}
|
}
|
||||||
} else {
|
if (res != PixelCopy.SUCCESS) {
|
||||||
mLastScreenshot = finalScreenShot;
|
Bitmap lastBitmap = currentPage.getBitmap();
|
||||||
// going to hold this lock for a while
|
// assign the last bitmap taken for now
|
||||||
currentPage.setBitmap(finalScreenShot);
|
currentPage.setBitmap(mLastScreenshot);
|
||||||
currentPage.setLastUpdateTime(current);
|
Bitmap lastScreenshot = mLastScreenshot;
|
||||||
updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
|
if (lastScreenshot != null && !Objects.equals(lastBitmap, lastScreenshot)) {
|
||||||
}
|
updatePageColors(
|
||||||
}, mHandler);
|
currentPage, areas, pageIndx, numPages, wallpaperDimAmount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mLastScreenshot = finalScreenShot;
|
||||||
|
currentPage.setBitmap(finalScreenShot);
|
||||||
|
currentPage.setLastUpdateTime(current);
|
||||||
|
updatePageColors(
|
||||||
|
currentPage, areas, pageIndx, numPages, wallpaperDimAmount);
|
||||||
|
}
|
||||||
|
}, mBackgroundHandler);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// this can potentially happen if the surface is invalidated right between the
|
||||||
|
// surface.isValid() check and the PixelCopy operation.
|
||||||
|
// in this case, stop: we'll compute colors on the next processLocalColors call.
|
||||||
|
Log.w(TAG, "Cancelling processLocalColors: exception caught during PixelCopy");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// locked by the passed page
|
// locked by the passed page
|
||||||
private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
|
private void updatePageColors(EngineWindowPage page, Set<RectF> areas,
|
||||||
float xOffsetStep) {
|
int pageIndx, int numPages, float wallpaperDimAmount) {
|
||||||
if (page.getBitmap() == null) return;
|
if (page.getBitmap() == null) return;
|
||||||
|
if (!mBackgroundHandler.getLooper().isCurrentThread()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"ProcessLocalColors should be called from the background thread");
|
||||||
|
}
|
||||||
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 "
|
||||||
+ page.getAreas().size() + " and bitmap size of "
|
+ page.getAreas().size() + " and bitmap size of "
|
||||||
+ page.getBitmap().getWidth() + " x " + page.getBitmap().getHeight());
|
+ page.getBitmap().getWidth() + " x " + page.getBitmap().getHeight());
|
||||||
}
|
}
|
||||||
for (RectF area: page.getAreas()) {
|
for (RectF area: areas) {
|
||||||
if (area == null) continue;
|
if (area == null) continue;
|
||||||
RectF subArea = generateSubRect(area, pageIndx, numPages);
|
RectF subArea = generateSubRect(area, pageIndx, numPages);
|
||||||
Bitmap b = page.getBitmap();
|
Bitmap b = page.getBitmap();
|
||||||
@@ -1769,12 +1820,12 @@ public abstract class WallpaperService extends Service {
|
|||||||
int height = Math.round(b.getHeight() * subArea.height());
|
int height = Math.round(b.getHeight() * subArea.height());
|
||||||
Bitmap target;
|
Bitmap target;
|
||||||
try {
|
try {
|
||||||
target = Bitmap.createBitmap(page.getBitmap(), x, y, width, height);
|
target = Bitmap.createBitmap(b, x, y, width, height);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
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, mWallpaperDimAmount);
|
WallpaperColors color = WallpaperColors.fromBitmap(target, wallpaperDimAmount);
|
||||||
target.recycle();
|
target.recycle();
|
||||||
WallpaperColors currentColor = page.getColors(area);
|
WallpaperColors currentColor = page.getColors(area);
|
||||||
|
|
||||||
@@ -1791,12 +1842,14 @@ 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);
|
||||||
}
|
}
|
||||||
try {
|
mHandler.post(() -> {
|
||||||
mConnection.onLocalWallpaperColorsChanged(area, color,
|
try {
|
||||||
mDisplayContext.getDisplayId());
|
mConnection.onLocalWallpaperColorsChanged(area, color,
|
||||||
} catch (RemoteException e) {
|
mDisplayContext.getDisplayId());
|
||||||
Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
|
} catch (RemoteException e) {
|
||||||
}
|
Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
@@ -1822,16 +1875,17 @@ public abstract class WallpaperService extends Service {
|
|||||||
return new RectF(left, in.top, right, in.bottom);
|
return new RectF(left, in.top, right, in.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
private void resetWindowPages() {
|
private void resetWindowPages() {
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
private int getRectFPage(RectF area, float step) {
|
private int getRectFPage(RectF area, float step) {
|
||||||
if (!isValid(area)) return 0;
|
if (!isValid(area)) return 0;
|
||||||
if (!validStep(step)) return 0;
|
if (!validStep(step)) return 0;
|
||||||
@@ -1852,12 +1906,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);
|
||||||
}
|
}
|
||||||
mHandler.post(() -> {
|
mBackgroundHandler.post(() -> {
|
||||||
mLocalColorsToAdd.addAll(regions);
|
synchronized (mLock) {
|
||||||
processLocalColors(mPendingXOffset, mPendingYOffset);
|
mLocalColorsToAdd.addAll(regions);
|
||||||
|
}
|
||||||
|
processLocalColors();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1867,16 +1921,18 @@ 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;
|
||||||
mHandler.post(() -> {
|
mBackgroundHandler.post(() -> {
|
||||||
float step = mPendingXOffsetStep;
|
synchronized (mLock) {
|
||||||
mLocalColorsToAdd.removeAll(regions);
|
float step = mPendingXOffsetStep;
|
||||||
mLocalColorAreas.removeAll(regions);
|
mLocalColorsToAdd.removeAll(regions);
|
||||||
if (!validStep(step)) {
|
mLocalColorAreas.removeAll(regions);
|
||||||
return;
|
if (!validStep(step)) {
|
||||||
}
|
return;
|
||||||
for (int i = 0; i < mWindowPages.length; i++) {
|
}
|
||||||
for (int j = 0; j < regions.size(); j++) {
|
for (int i = 0; i < mWindowPages.length; i++) {
|
||||||
mWindowPages[i].removeArea(regions.get(j));
|
for (int j = 0; j < regions.size(); j++) {
|
||||||
|
mWindowPages[i].removeArea(regions.get(j));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1894,7 +1950,7 @@ public abstract class WallpaperService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean validStep(float step) {
|
private boolean validStep(float step) {
|
||||||
return !PROHIBITED_STEPS.contains(step) && step > 0. && step <= 1.;
|
return !Float.isNaN(step) && step > 0f && step <= 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doCommand(WallpaperCommand cmd) {
|
void doCommand(WallpaperCommand cmd) {
|
||||||
@@ -2498,6 +2554,9 @@ 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();
|
||||||
}
|
}
|
||||||
@@ -2510,6 +2569,7 @@ public abstract class WallpaperService extends Service {
|
|||||||
mActiveEngines.get(i).detach();
|
mActiveEngines.get(i).detach();
|
||||||
}
|
}
|
||||||
mActiveEngines.clear();
|
mActiveEngines.clear();
|
||||||
|
mBackgroundThread.quitSafely();
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user