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

Commit 6484dcdd authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8656595 from 83dddfde to tm-qpr1-release

Change-Id: Iafb9027ed38a1a47105a0c42bb2a442959821925
parents 35775b52 83dddfde
Loading
Loading
Loading
Loading
+65 −52
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import com.android.internal.graphics.cam.Cam;
import com.android.internal.graphics.palette.CelebiQuantizer;
import com.android.internal.graphics.palette.Palette;
import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
import com.android.internal.util.ContrastColorUtil;

import java.io.FileOutputStream;
import java.lang.annotation.Retention;
@@ -94,18 +93,10 @@ public final class WallpaperColors implements Parcelable {
    // using the area instead. This way our comparisons are aspect ratio independent.
    private static final int MAX_WALLPAPER_EXTRACTION_AREA = MAX_BITMAP_SIZE * MAX_BITMAP_SIZE;

    // When extracting the main colors, only consider colors
    // present in at least MIN_COLOR_OCCURRENCE of the image
    private static final float MIN_COLOR_OCCURRENCE = 0.05f;

    // Decides when dark theme is optimal for this wallpaper
    private static final float DARK_THEME_MEAN_LUMINANCE = 0.3f;
    // Minimum mean luminosity that an image needs to have to support dark text
    private static final float BRIGHT_IMAGE_MEAN_LUMINANCE = 0.7f;
    // We also check if the image has dark pixels in it,
    // to avoid bright images with some dark spots.
    private static final float DARK_PIXEL_CONTRAST = 5.5f;
    private static final float MAX_DARK_AREA = 0.05f;
    // Decides when dark theme is optimal for this wallpaper.
    // The midpoint of perceptual luminance, 50, is 18.42 in relative luminance.
    // ColorUtils.calculateLuminance returns relative luminance on a scale from 0 to 1.
    private static final float DARK_THEME_MEAN_LUMINANCE = 0.1842f;

    private final List<Color> mMainColors;
    private final Map<Integer, Integer> mAllColors;
@@ -253,12 +244,9 @@ public final class WallpaperColors implements Parcelable {
        this(primaryColor, secondaryColor, tertiaryColor, 0);

        // Calculate dark theme support based on primary color.
        final float[] tmpHsl = new float[3];
        ColorUtils.colorToHSL(primaryColor.toArgb(), tmpHsl);
        final float luminance = tmpHsl[2];
        if (luminance < DARK_THEME_MEAN_LUMINANCE) {
            mColorHints |= HINT_SUPPORTS_DARK_THEME;
        }
        final double relativeLuminance = ColorUtils.calculateLuminance(primaryColor.toArgb());
        final boolean wallpaperIsDark = relativeLuminance < DARK_THEME_MEAN_LUMINANCE;
        mColorHints |= wallpaperIsDark ? HINT_SUPPORTS_DARK_THEME : HINT_SUPPORTS_DARK_TEXT;
    }

    /**
@@ -536,9 +524,6 @@ public final class WallpaperColors implements Parcelable {

        dimAmount = MathUtils.saturate(dimAmount);
        int[] pixels = new int[source.getWidth() * source.getHeight()];
        double totalLuminance = 0;
        final int maxDarkPixels = (int) (pixels.length * MAX_DARK_AREA);
        int darkPixels = 0;
        source.getPixels(pixels, 0 /* offset */, source.getWidth(), 0 /* x */, 0 /* y */,
                source.getWidth(), source.getHeight());

@@ -547,42 +532,70 @@ public final class WallpaperColors implements Parcelable {
        int dimmingLayerAlpha = (int) (255 * dimAmount);
        int blackTransparent = ColorUtils.setAlphaComponent(Color.BLACK, dimmingLayerAlpha);

        // This bitmap was already resized to fit the maximum allowed area.
        // Let's just loop through the pixels, no sweat!
        float[] tmpHsl = new float[3];
        // The median luminance in the wallpaper will be used to decide if it is light or dark.
        //
        // Calculating the luminances, adding them to a data structure, then selecting
        // the middle element would be expensive, the sort would be O(n), where n is the number
        // of pixels.
        //
        // Instead, we create an integer array with 101 elements initialized to zero.
        // Why 101? 0 through 100, inclusive, matching the range of luminance.
        // Then, for each pixel, the luminance is calculated, and the integer at the array index
        // equal to the rounded luminance is incremented.
        //
        // After processing the pixels, the median luminance is determined by iterating over the
        // array containing the count for each luminance. Starting from 0, we adding the count at
        // each index until pixels.length/2 is exceeded. When that occurs, it means the current
        // array index contains the pixel of median luminance, thus the current array index is the
        // median luminance.
        int[] luminanceCounts = new int[101];
        for (int i = 0; i < pixels.length; i++) {
            int pixelColor = pixels[i];
            ColorUtils.colorToHSL(pixelColor, tmpHsl);
            final int alpha = Color.alpha(pixelColor);

            // Apply composite colors where the foreground is a black layer with an alpha value of
            // the dim amount and the background is the wallpaper pixel color.
            int compositeColors = ColorUtils.compositeColors(blackTransparent, pixelColor);

            // Calculate the adjusted luminance of the dimmed wallpaper pixel color.
            double adjustedLuminance = ColorUtils.calculateLuminance(compositeColors);

            // Make sure we don't have a dark pixel mass that will
            // make text illegible.
            final boolean satisfiesTextContrast = ContrastColorUtil
                    .calculateContrast(pixelColor, Color.BLACK) > DARK_PIXEL_CONTRAST;
            if (!satisfiesTextContrast && alpha != 0) {
                darkPixels++;
                if (DEBUG_DARK_PIXELS) {
                    pixels[i] = Color.RED;
                }
            }
            totalLuminance += adjustedLuminance;
        }

            if (alpha == 0) {
                continue;
            }

            // If the wallpaper is dimmed, apply dimming before calculating luminance.
            int compositeColor = dimAmount <= 0 ? pixelColor :
                    ColorUtils.compositeColors(blackTransparent, pixelColor);

            // calculateLuminance will return relative luminance on a scale from 0 to 1. Intent
            // is normalize to 0 to 100, and that is done by defensively normalizing to
            // luminanceCounts.length, then flooring the result to defensively avoid any imprecision
            // in the result of calculateLuminance that could cause it to exceed 1 and thus the
            // array bounds.
            float relativeLuminance = (float) ColorUtils.calculateLuminance(compositeColor)
                    * luminanceCounts.length - 1;
            int intRelativeLuminance = (int) Math.floor(relativeLuminance);
            int clampedRelativeLuminance = (intRelativeLuminance < 0) ? 0 :
                    (intRelativeLuminance > luminanceCounts.length - 1) ? luminanceCounts.length - 1
                            : intRelativeLuminance;
            luminanceCounts[clampedRelativeLuminance] += 1;
        }

        int criticalRelativeLuminance = 0;
        int luminancesProcessed = 0;
        int criticalLuminanceIndex = (int) Math.floor(pixels.length * 0.5);
        for (int i = 0; i < 100; i++) {
            luminancesProcessed += luminanceCounts[i];
            if (luminancesProcessed > criticalLuminanceIndex) {
                criticalRelativeLuminance = i;
                break;
            }
        }

        // Wallpaper is dark if the median pixel is less than mid-gray.
        //
        // Relative luminance places mid-gray at 18.42, 19 is used since luminances were rounded to
        // ints to be stored in the array.
        //
        // Why not use perceptual luminance? It would require one more conversion step at each
        // pixel, or adding a function to convert relative luminance to perceptual luminance just
        // for this line.
        boolean wallpaperIsDark = criticalRelativeLuminance < 19;
        int hints = 0;
        double meanLuminance = totalLuminance / pixels.length;
        if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels < maxDarkPixels) {
            hints |= HINT_SUPPORTS_DARK_TEXT;
        }
        if (meanLuminance < DARK_THEME_MEAN_LUMINANCE) {
            hints |= HINT_SUPPORTS_DARK_THEME;
        }
        hints |= wallpaperIsDark ? HINT_SUPPORTS_DARK_THEME : HINT_SUPPORTS_DARK_TEXT;

        if (DEBUG_DARK_PIXELS) {
            try (FileOutputStream out = new FileOutputStream("/data/pixels.png")) {
@@ -592,8 +605,8 @@ public final class WallpaperColors implements Parcelable {
            } catch (Exception e) {
                e.printStackTrace();
            }
            Log.d("WallpaperColors", "l: " + meanLuminance + ", d: " + darkPixels +
                    " maxD: " + maxDarkPixels + " numPixels: " + pixels.length);
            Log.d("WallpaperColors", "median relative L: " + criticalRelativeLuminance
                    + ", numPixels: " + pixels.length);
        }

        return hints;
+1 −1
Original line number Diff line number Diff line
@@ -3670,7 +3670,7 @@ public abstract class Context {
     *  <li>caller has {@code android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}</li>
     *  <li>caller has {@code android.Manifest.permission.INTERACT_ACROSS_USERS} and is the same
     *      package as the {@code service} (determined by its component's package) and the Android
     *      version is at least {@link android.os.Build.VERSION_CODES#S}</li>
     *      version is at least {@link android.os.Build.VERSION_CODES#TIRAMISU}</li>
     *  <li>caller has {@code android.Manifest.permission.INTERACT_ACROSS_USERS} and is in same
     *      profile group as the given {@code user}</li>
     *  <li>caller has {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} and is in same
+3 −1
Original line number Diff line number Diff line
@@ -10000,9 +10000,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            // We reset any translation state as views may be re-used (e.g., as in ListView and
            // RecyclerView). We only need to do this for views important for content capture since
            // views unimportant for content capture won't be translated anyway.
            if (!isTemporarilyDetached()) {
                clearTranslationState();
            }
        }
    }
    private void setNotifiedContentCaptureAppeared() {
        mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
+5 −0
Original line number Diff line number Diff line
@@ -125,6 +125,11 @@ public abstract class DisplayWindowPolicyController {
    public abstract boolean keepActivityOnWindowFlagsChanged(
            ActivityInfo activityInfo, int windowFlags, int systemWindowFlags);

    /**
     * Returns {@code true} if the tasks which is on this virtual display can be showed on Recents.
     */
    public abstract boolean canShowTasksInRecents();

    /**
     * This is called when the top activity of the display is changed.
     */
+7 −0
Original line number Diff line number Diff line
@@ -386,6 +386,13 @@ public class Cam {
        // Yellows are very chromatic at L = 100, and blues are very chromatic at L = 0. All the
        // other hues are white at L = 100, and black at L = 0. To preserve consistency for users of
        // this system, it is better to simply return white at L* > 99, and black and L* < 0.
        if (frame == Frame.DEFAULT) {
            // If the viewing conditions are the same as the default sRGB-like viewing conditions,
            // skip to using HctSolver: it uses geometrical insights to find the closest in-gamut
            // match to hue/chroma/lstar.
            return HctSolver.solveToInt(hue, chroma, lstar);
        }

        if (chroma < 1.0 || Math.round(lstar) <= 0.0 || Math.round(lstar) >= 100.0) {
            return CamUtils.intFromLstar(lstar);
        }
Loading