Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ad1fe24 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9794482 from a8971c24 to tm-qpr3-release

Change-Id: I23e3bfa8aab76ff6a9043aff928c80d6bcde2715
parents 85aa92cb a8971c24
Loading
Loading
Loading
Loading
+199 −139
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -96,6 +97,7 @@ import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.window.ClientWindowFrames;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.HandlerCaller;
import com.android.internal.view.BaseIWindow;
@@ -104,9 +106,10 @@ import com.android.internal.view.BaseSurfaceHolder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
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_REPORT_SHOWN = 10150;
    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 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 =
            SystemProperties.getBoolean("persist.debug.enable_wallpaper_dimming", true);
@@ -180,6 +184,9 @@ public abstract class WallpaperService extends Service {
    private final ArrayList<Engine> mActiveEngines
            = new ArrayList<Engine>();

    private Handler mBackgroundHandler;
    private HandlerThread mBackgroundThread;

    static final class WallpaperCommand {
        String action;
        int x;
@@ -198,14 +205,6 @@ public abstract class WallpaperService extends Service {
     */
    public class Engine {
        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.
        HandlerCaller mCaller;
@@ -267,11 +266,34 @@ public abstract class WallpaperService extends Service {

        final Object mLock = new Object();
        boolean mOffsetMessageEnqueued;

        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        float mPendingXOffset;
        float mPendingYOffset;
        float mPendingXOffsetStep;
        float mPendingYOffsetStep;
        @GuardedBy("mLock")
        private float mPendingXOffset;
        @GuardedBy("mLock")
        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;
        MotionEvent mPendingMove;
        boolean mIsInAmbientMode;
@@ -280,12 +302,8 @@ public abstract class WallpaperService extends Service {
        private long mLastColorInvalidation;
        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 Handler mHandler;

        private Display mDisplay;
        private Context mDisplayContext;
        private int mDisplayState;
@@ -825,7 +843,7 @@ public abstract class WallpaperService extends Service {
                            + "was not established.");
                }
                mResetWindowPages = true;
                processLocalColors(mPendingXOffset, mPendingXOffsetStep);
                processLocalColors();
            } catch (RemoteException 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;
                        mSurfaceCreated = true;
                        if (redrawNeeded) {
                            resetWindowPages();
                            mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
                                                   Integer.MAX_VALUE);
                            processLocalColors(mPendingXOffset, mPendingXOffsetStep);
                            processLocalColors();
                        }
                        reposition();
                        reportEngineShown(shouldWaitForEngineShown());
@@ -1509,7 +1526,7 @@ public abstract class WallpaperService extends Service {
            if (!mDestroyed) {
                mVisible = visible;
                reportVisibility();
                if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep);
                if (mReportedVisible) processLocalColors();
            } else {
                AnimationHandler.requestAnimatorsEnabled(visible, this);
            }
@@ -1594,14 +1611,14 @@ public abstract class WallpaperService extends Service {
            }

            // setup local color extraction data
            processLocalColors(xOffset, xOffsetStep);
            processLocalColors();
        }

        /**
         * Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of
         * {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls.
         */
        private void processLocalColors(float xOffset, float xOffsetStep) {
        private void processLocalColors() {
            if (mProcessLocalColorsPending.compareAndSet(false, true)) {
                final long now = mClockFunction.get();
                final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp;
@@ -1611,23 +1628,41 @@ public abstract class WallpaperService extends Service {
                mHandler.postDelayed(() -> {
                    mLastProcessLocalColorsTimestamp = now + timeToWait;
                    mProcessLocalColorsPending.set(false);
                    processLocalColorsInternal(xOffset, xOffsetStep);
                    processLocalColorsInternal();
                }, 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;
            float xOffset;
            float xOffsetStep;
            float wallpaperDimAmount;
            int xPage;
            int xPages;
            Set<RectF> areas;
            EngineWindowPage current;

            synchronized (mLock) {
                xOffset = mPendingXOffset;
                xOffsetStep = mPendingXOffsetStep;
                wallpaperDimAmount = mWallpaperDimAmount;

                if (DEBUG) {
                    Log.d(TAG, "processLocalColors " + xOffset + " of step "
                            + xOffsetStep);
                }
            //below is the default implementation
                if (xOffset % xOffsetStep > MIN_PAGE_ALLOWED_MARGIN
                        || !mSurfaceHolder.getSurface().isValid()) return;
                int xCurrentPage;
            int xPages;
                if (!validStep(xOffsetStep)) {
                    if (DEBUG) {
                        Log.w(TAG, "invalid offset step " + xOffsetStep);
@@ -1651,10 +1686,8 @@ public abstract class WallpaperService extends Service {
                float finalXOffsetStep = xOffsetStep;
                float finalXOffset = xOffset;

            Trace.beginSection("WallpaperService#processLocalColors");
                resetWindowPages();
            int xPage = xCurrentPage;
            EngineWindowPage current;
                xPage = xCurrentPage;
                if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) {
                    mWindowPages = new EngineWindowPage[xPages];
                    initWindowPages(mWindowPages, finalXOffsetStep);
@@ -1681,10 +1714,12 @@ public abstract class WallpaperService extends Service {
                    xPage = mWindowPages.length - 1;
                }
                current = mWindowPages[xPage];
            updatePage(current, xPage, xPages, finalXOffsetStep);
            Trace.endSection();
                areas = new HashSet<>(current.getAreas());
            }
            updatePage(current, areas, xPage, xPages, wallpaperDimAmount);
        }

        @GuardedBy("mLock")
        private void initWindowPages(EngineWindowPage[] windowPages, float step) {
            for (int i = 0; i < windowPages.length; i++) {
                windowPages[i] = new EngineWindowPage();
@@ -1701,16 +1736,16 @@ public abstract class WallpaperService extends Service {
            }
        }

        void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
                float xOffsetStep) {
        void updatePage(EngineWindowPage currentPage, Set<RectF> areas, int pageIndx, int numPages,
                float wallpaperDimAmount) {

            // in case the clock is zero, we start with negative time
            long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION;
            long lapsed = current - currentPage.getLastUpdateTime();
            // Always update the page when the last update time is <= 0
            // 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();
            if (!surface.isValid()) return;
            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);
                return;
            }
            final String pixelCopySectionName = "WallpaperService#pixelCopy";
            final int pixelCopyCount = mPixelCopyCount++;
            Trace.beginAsyncSection(pixelCopySectionName, pixelCopyCount);
            Bitmap screenShot = Bitmap.createBitmap(width, height,
                    Bitmap.Config.ARGB_8888);
            final Bitmap finalScreenShot = screenShot;
            Trace.beginSection("WallpaperService#pixelCopy");
            try {
                // TODO(b/274427458) check if this can be done in the background.
                PixelCopy.request(surface, screenShot, (res) -> {
                Trace.endSection();
                if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
                    Trace.endAsyncSection(pixelCopySectionName, pixelCopyCount);
                    if (DEBUG) {
                        Log.d(TAG, "result of pixel copy is: "
                                + (res == PixelCopy.SUCCESS ? "SUCCESS" : "FAILURE"));
                    }
                    if (res != PixelCopy.SUCCESS) {
                        Bitmap lastBitmap = currentPage.getBitmap();
                        // assign the last bitmap taken for now
                        currentPage.setBitmap(mLastScreenshot);
                        Bitmap lastScreenshot = mLastScreenshot;
                    if (lastScreenshot != null && !lastScreenshot.isRecycled()
                            && !Objects.equals(lastBitmap, lastScreenshot)) {
                        updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
                        if (lastScreenshot != null && !Objects.equals(lastBitmap, lastScreenshot)) {
                            updatePageColors(
                                    currentPage, areas, pageIndx, numPages, wallpaperDimAmount);
                        }
                    } else {
                        mLastScreenshot = finalScreenShot;
                    // going to hold this lock for a while
                        currentPage.setBitmap(finalScreenShot);
                        currentPage.setLastUpdateTime(current);
                    updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
                        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");
            }
            }, mHandler);

        }
        // locked by the passed page
        private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
                float xOffsetStep) {
        private void updatePageColors(EngineWindowPage page, Set<RectF> areas,
                int pageIndx, int numPages, float wallpaperDimAmount) {
            if (page.getBitmap() == null) return;
            if (!mBackgroundHandler.getLooper().isCurrentThread()) {
                throw new IllegalStateException(
                        "ProcessLocalColors should be called from the background thread");
            }
            Trace.beginSection("WallpaperService#updatePageColors");
            if (DEBUG) {
                Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas "
                        + page.getAreas().size() + " and bitmap size of "
                        + page.getBitmap().getWidth() + " x " + page.getBitmap().getHeight());
            }
            for (RectF area: page.getAreas()) {
            for (RectF area: areas) {
                if (area == null) continue;
                RectF subArea = generateSubRect(area, pageIndx, numPages);
                Bitmap b = page.getBitmap();
@@ -1769,12 +1820,12 @@ public abstract class WallpaperService extends Service {
                int height = Math.round(b.getHeight() * subArea.height());
                Bitmap target;
                try {
                    target = Bitmap.createBitmap(page.getBitmap(), x, y, width, height);
                    target = Bitmap.createBitmap(b, x, y, width, height);
                } catch (Exception e) {
                    Log.e(TAG, "Error creating page local color bitmap", e);
                    continue;
                }
                WallpaperColors color = WallpaperColors.fromBitmap(target, mWallpaperDimAmount);
                WallpaperColors color = WallpaperColors.fromBitmap(target, wallpaperDimAmount);
                target.recycle();
                WallpaperColors currentColor = page.getColors(area);

@@ -1791,12 +1842,14 @@ public abstract class WallpaperService extends Service {
                                + " local color callback for area" + area + " for page " + pageIndx
                                + " of " + numPages);
                    }
                    mHandler.post(() -> {
                        try {
                            mConnection.onLocalWallpaperColorsChanged(area, color,
                                    mDisplayContext.getDisplayId());
                        } catch (RemoteException e) {
                            Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
                        }
                    });
                }
            }
            Trace.endSection();
@@ -1822,16 +1875,17 @@ public abstract class WallpaperService extends Service {
            return new RectF(left, in.top, right, in.bottom);
        }

        @GuardedBy("mLock")
        private void resetWindowPages() {
            if (supportsLocalColorExtraction()) return;
            if (!mResetWindowPages) return;
            mResetWindowPages = false;
            mLastWindowPage = -1;
            for (int i = 0; i < mWindowPages.length; i++) {
                mWindowPages[i].setLastUpdateTime(0L);
            }
        }

        @GuardedBy("mLock")
        private int getRectFPage(RectF area, float step) {
            if (!isValid(area)) return 0;
            if (!validStep(step)) return 0;
@@ -1852,12 +1906,12 @@ public abstract class WallpaperService extends Service {
            if (DEBUG) {
                Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions);
            }
            mHandler.post(() -> {
            mBackgroundHandler.post(() -> {
                synchronized (mLock) {
                    mLocalColorsToAdd.addAll(regions);
                processLocalColors(mPendingXOffset, mPendingYOffset);
                }
                processLocalColors();
            });


        }

        /**
@@ -1867,7 +1921,8 @@ public abstract class WallpaperService extends Service {
         */
        public void removeLocalColorsAreas(@NonNull List<RectF> regions) {
            if (supportsLocalColorExtraction()) return;
            mHandler.post(() -> {
            mBackgroundHandler.post(() -> {
                synchronized (mLock) {
                    float step = mPendingXOffsetStep;
                    mLocalColorsToAdd.removeAll(regions);
                    mLocalColorAreas.removeAll(regions);
@@ -1879,6 +1934,7 @@ public abstract class WallpaperService extends Service {
                            mWindowPages[i].removeArea(regions.get(j));
                        }
                    }
                }
            });
        }

@@ -1894,7 +1950,7 @@ public abstract class WallpaperService extends Service {
        }

        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) {
@@ -2498,6 +2554,9 @@ public abstract class WallpaperService extends Service {
    @Override
    public void onCreate() {
        Trace.beginSection("WPMS.onCreate");
        mBackgroundThread = new HandlerThread("DefaultWallpaperLocalColorExtractor");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
        super.onCreate();
        Trace.endSection();
    }
@@ -2510,6 +2569,7 @@ public abstract class WallpaperService extends Service {
            mActiveEngines.get(i).detach();
        }
        mActiveEngines.clear();
        mBackgroundThread.quitSafely();
        Trace.endSection();
    }

+1 −0
Original line number Diff line number Diff line
@@ -150,6 +150,7 @@ public final class UidState {
    public void resetSafely(long now) {
        mDurations.resetTable();
        mStartTime = now;
        mProcesses.removeIf(p -> !p.isInUse());
    }

    /**
+34 −10
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.internal.jank;

import static android.Manifest.permission.READ_DEVICE_CONFIG;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.provider.DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR;

import static com.android.internal.jank.FrameTracker.REASON_CANCEL_NORMAL;
import static com.android.internal.jank.FrameTracker.REASON_CANCEL_TIMEOUT;
import static com.android.internal.jank.FrameTracker.REASON_END_NORMAL;
@@ -94,6 +98,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.UiThread;
import android.annotation.WorkerThread;
import android.app.ActivityThread;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
@@ -436,18 +441,37 @@ public class InteractionJankMonitor {
        mWorker = worker;
        mWorker.start();
        mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
        mEnabled = DEFAULT_ENABLED;

        // Post initialization to the background in case we're running on the main
        // thread.
        final Context context = ActivityThread.currentApplication();
        if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PERMISSION_GRANTED) {
            if (DEBUG) {
                Log.d(TAG, "Initialized the InteractionJankMonitor."
                        + " (No READ_DEVICE_CONFIG permission to change configs)"
                        + " enabled=" + mEnabled + ", interval=" + mSamplingInterval
                        + ", missedFrameThreshold=" + mTraceThresholdMissedFrames
                        + ", frameTimeThreshold=" + mTraceThresholdFrameTimeMillis
                        + ", package=" + context.getPackageName());
            }
            return;
        }

        // Post initialization to the background in case we're running on the main thread.
        mWorker.getThreadHandler().post(
                () -> mPropertiesChangedListener.onPropertiesChanged(
                        DeviceConfig.getProperties(
                                DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR)));
                () -> {
                    try {
                        mPropertiesChangedListener.onPropertiesChanged(
                                DeviceConfig.getProperties(NAMESPACE_INTERACTION_JANK_MONITOR));
                        DeviceConfig.addOnPropertiesChangedListener(
                DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
                                NAMESPACE_INTERACTION_JANK_MONITOR,
                                new HandlerExecutor(mWorker.getThreadHandler()),
                                mPropertiesChangedListener);
        mEnabled = DEFAULT_ENABLED;
                    } catch (SecurityException ex) {
                        Log.d(TAG, "Can't get properties: READ_DEVICE_CONFIG granted="
                                + context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
                                + ", package=" + context.getPackageName());
                    }
                });
    }

    /**
+4 −0
Original line number Diff line number Diff line
@@ -5333,6 +5333,10 @@
    <!-- Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps. -->
    <bool name="config_letterboxIsVerticalReachabilityEnabled">false</bool>

    <!-- Whether book mode automatic horizontal reachability positioning is allowed for letterboxed
        fullscreen apps -->
    <bool name="config_letterboxIsAutomaticReachabilityInBookModeEnabled">false</bool>

    <!-- Default horizontal position of the letterboxed app window when reachability is
        enabled and an app is fullscreen in landscape device orientation. When reachability is
        enabled, the position can change between left, center and right. This config defines the
+1 −0
Original line number Diff line number Diff line
@@ -4475,6 +4475,7 @@
  <java-symbol type="dimen" name="config_letterboxTabletopModePositionMultiplier" />
  <java-symbol type="bool" name="config_letterboxIsHorizontalReachabilityEnabled" />
  <java-symbol type="bool" name="config_letterboxIsVerticalReachabilityEnabled" />
  <java-symbol type="bool" name="config_letterboxIsAutomaticReachabilityInBookModeEnabled" />
  <java-symbol type="integer" name="config_letterboxDefaultPositionForHorizontalReachability" />
  <java-symbol type="integer" name="config_letterboxDefaultPositionForVerticalReachability" />
  <java-symbol type="integer" name="config_letterboxDefaultPositionForBookModeReachability" />
Loading