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

Commit c95a9a45 authored by Christine Franks's avatar Christine Franks Committed by Automerger Merge Worker
Browse files

Merge "Differentiate per-layer saturation levels" into rvc-dev am: be3b2304

Change-Id: I668d2021e09cf03006cdea9a2dc949289541d37e
parents a3557cad be3b2304
Loading
Loading
Loading
Loading
+29 −12
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.display.color;

import android.annotation.UserIdInt;
import android.util.ArrayMap;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
@@ -61,11 +62,12 @@ class AppSaturationController {
     * Set the saturation level ({@code ColorDisplayManager#SaturationLevel} constant for a given
     * package name and userId.
     */
    public boolean setSaturationLevel(String packageName, @UserIdInt int userId,
    public boolean setSaturationLevel(String callingPackageName, String affectedPackageName,
            @UserIdInt int userId,
            int saturationLevel) {
        synchronized (mLock) {
            return getSaturationControllerLocked(packageName, userId)
                    .setSaturationLevel(saturationLevel);
            return getSaturationControllerLocked(affectedPackageName, userId)
                    .setSaturationLevel(callingPackageName, saturationLevel);
        }
    }

@@ -148,13 +150,19 @@ class AppSaturationController {

    private static class SaturationController {

        private static final int FULL_SATURATION = 100;

        private final List<WeakReference<ColorTransformController>> mControllerRefs =
                new ArrayList<>();
        private int mSaturationLevel = 100;
        private final ArrayMap<String, Integer> mSaturationLevels = new ArrayMap<>();
        private float[] mTransformMatrix = new float[9];

        private boolean setSaturationLevel(int saturationLevel) {
            mSaturationLevel = saturationLevel;
        private boolean setSaturationLevel(String callingPackageName, int saturationLevel) {
            if (saturationLevel == FULL_SATURATION) {
                mSaturationLevels.remove(callingPackageName);
            } else {
                mSaturationLevels.put(callingPackageName, saturationLevel);
            }
            if (!mControllerRefs.isEmpty()) {
                return updateState();
            }
@@ -163,17 +171,27 @@ class AppSaturationController {

        private boolean addColorTransformController(
                WeakReference<ColorTransformController> controller) {
            clearExpiredReferences();
            mControllerRefs.add(controller);
            if (mSaturationLevel != 100) {
            if (!mSaturationLevels.isEmpty()) {
                return updateState();
            } else {
                clearExpiredReferences();
            }
            return false;
        }

        private int calculateSaturationLevel() {
            int saturationLevel = FULL_SATURATION;
            for (int i = 0; i < mSaturationLevels.size(); i++) {
                final int level = mSaturationLevels.valueAt(i);
                if (level < saturationLevel) {
                    saturationLevel = level;
                }
            }
            return saturationLevel;
        }

        private boolean updateState() {
            computeGrayscaleTransformMatrix(mSaturationLevel / 100f, mTransformMatrix);
            computeGrayscaleTransformMatrix(calculateSaturationLevel() / 100f, mTransformMatrix);

            boolean updated = false;
            final Iterator<WeakReference<ColorTransformController>> iterator = mControllerRefs
@@ -190,7 +208,6 @@ class AppSaturationController {
                }
            }
            return updated;

        }

        private void clearExpiredReferences() {
@@ -206,7 +223,7 @@ class AppSaturationController {
        }

        private void dump(PrintWriter pw) {
            pw.println("            mSaturationLevel: " + mSaturationLevel);
            pw.println("            mSaturationLevels: " + mSaturationLevels);
            pw.println("            mControllerRefs count: " + mControllerRefs.size());
        }
    }
+9 −3
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.display.ColorDisplayManager;
@@ -73,6 +74,7 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
@@ -817,9 +819,11 @@ public final class ColorDisplayService extends SystemService {
        return LocalDateTime.MIN;
    }

    private boolean setAppSaturationLevelInternal(String packageName, int saturationLevel) {
    private boolean setAppSaturationLevelInternal(String callingPackageName,
            String affectedPackageName, int saturationLevel) {
        return mAppSaturationController
                .setSaturationLevel(packageName, mCurrentUser, saturationLevel);
                .setSaturationLevel(callingPackageName, affectedPackageName, mCurrentUser,
                        saturationLevel);
    }

    private void setColorModeInternal(@ColorMode int colorMode) {
@@ -1533,9 +1537,11 @@ public final class ColorDisplayService extends SystemService {
            getContext().enforceCallingPermission(
                    Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
                    "Permission required to set display saturation level");
            final String callingPackageName = LocalServices.getService(PackageManagerInternal.class)
                    .getNameForUid(Binder.getCallingUid());
            final long token = Binder.clearCallingIdentity();
            try {
                return setAppSaturationLevelInternal(packageName, level);
                return setAppSaturationLevelInternal(callingPackageName, packageName, level);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
+77 −10
Original line number Diff line number Diff line
@@ -43,7 +43,9 @@ import java.lang.ref.WeakReference;
@RunWith(AndroidJUnit4.class)
public class AppSaturationControllerTest {

    private static final String TEST_PACKAGE_NAME = "com.android.test";
    private static final String TEST_CALLER_PACKAGE_NAME = "com.android.test.caller";
    private static final String TEST_CALLER_PACKAGE_NAME_TWO = "com.android.test.caller.two";
    private static final String TEST_AFFECTED_PACKAGE_NAME = "com.android.test.affected";

    private int mUserId;
    private AppSaturationController mAppSaturationController;
@@ -70,8 +72,11 @@ public class AppSaturationControllerTest {
    public void addColorTransformController_appliesExistingSaturation() {
        final WeakReference<ColorTransformController> ref = new WeakReference<>(
                mColorTransformController);
        mAppSaturationController.setSaturationLevel(TEST_PACKAGE_NAME, mUserId, 30);
        mAppSaturationController.addColorTransformController(TEST_PACKAGE_NAME, mUserId, ref);
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        30);
        mAppSaturationController
                .addColorTransformController(TEST_AFFECTED_PACKAGE_NAME, mUserId, ref);
        AppSaturationController.computeGrayscaleTransformMatrix(.3f, mMatrix);
        verify(mColorTransformController).applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
    }
@@ -80,14 +85,19 @@ public class AppSaturationControllerTest {
    public void setSaturationLevel_resetToDefault() {
        final WeakReference<ColorTransformController> ref = new WeakReference<>(
                mColorTransformController);
        mAppSaturationController.addColorTransformController(TEST_PACKAGE_NAME, mUserId, ref);
        mAppSaturationController
                .addColorTransformController(TEST_AFFECTED_PACKAGE_NAME, mUserId, ref);
        verify(mColorTransformController, never())
                .applyAppSaturation(any(), eq(TRANSLATION_VECTOR));
        mAppSaturationController.setSaturationLevel(TEST_PACKAGE_NAME, mUserId, 30);
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        30);
        AppSaturationController.computeGrayscaleTransformMatrix(.3f, mMatrix);
        verify(mColorTransformController, times(1))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
        mAppSaturationController.setSaturationLevel(TEST_PACKAGE_NAME, mUserId, 100);
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        100);
        AppSaturationController.computeGrayscaleTransformMatrix(1.0f, mMatrix);
        verify(mColorTransformController, times(2))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
@@ -97,19 +107,76 @@ public class AppSaturationControllerTest {
    public void setSaturationLevel_updateLevel() {
        final WeakReference<ColorTransformController> ref = new WeakReference<>(
                mColorTransformController);
        mAppSaturationController.addColorTransformController(TEST_PACKAGE_NAME, mUserId, ref);
        mAppSaturationController
                .addColorTransformController(TEST_AFFECTED_PACKAGE_NAME, mUserId, ref);
        verify(mColorTransformController, never())
                .applyAppSaturation(any(), eq(TRANSLATION_VECTOR));
        mAppSaturationController.setSaturationLevel(TEST_PACKAGE_NAME, mUserId, 30);
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        30);
        AppSaturationController.computeGrayscaleTransformMatrix(.3f, mMatrix);
        verify(mColorTransformController).applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
        mAppSaturationController.setSaturationLevel(TEST_PACKAGE_NAME, mUserId, 70);
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        70);
        AppSaturationController.computeGrayscaleTransformMatrix(.7f, mMatrix);
        verify(mColorTransformController, times(2))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
        mAppSaturationController.setSaturationLevel(TEST_PACKAGE_NAME, mUserId, 100);
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        100);
        AppSaturationController.computeGrayscaleTransformMatrix(1.0f, mMatrix);
        verify(mColorTransformController, times(3))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
    }

    @Test
    public void setSaturationLevel_multipleCallers_appliesStrongest() {
        final WeakReference<ColorTransformController> ref = new WeakReference<>(
                mColorTransformController);
        mAppSaturationController
                .addColorTransformController(TEST_AFFECTED_PACKAGE_NAME, mUserId, ref);
        verify(mColorTransformController, never())
                .applyAppSaturation(any(), eq(TRANSLATION_VECTOR));
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        30);
        AppSaturationController.computeGrayscaleTransformMatrix(0.3f, mMatrix);
        verify(mColorTransformController, times(1))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME_TWO, TEST_AFFECTED_PACKAGE_NAME,
                        mUserId,
                        70);
        verify(mColorTransformController, times(2))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
    }

    @Test
    public void setSaturationLevel_multipleCallers_removingOneDoesNotAffectTheOther() {
        final WeakReference<ColorTransformController> ref = new WeakReference<>(
                mColorTransformController);
        mAppSaturationController
                .addColorTransformController(TEST_AFFECTED_PACKAGE_NAME, mUserId, ref);
        verify(mColorTransformController, never())
                .applyAppSaturation(any(), eq(TRANSLATION_VECTOR));
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME, TEST_AFFECTED_PACKAGE_NAME, mUserId,
                        70);
        AppSaturationController.computeGrayscaleTransformMatrix(0.7f, mMatrix);
        verify(mColorTransformController, times(1))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME_TWO, TEST_AFFECTED_PACKAGE_NAME,
                        mUserId,
                        30);
        AppSaturationController.computeGrayscaleTransformMatrix(0.3f, mMatrix);
        verify(mColorTransformController, times(2))
                .applyAppSaturation(eq(mMatrix), eq(TRANSLATION_VECTOR));
        mAppSaturationController
                .setSaturationLevel(TEST_CALLER_PACKAGE_NAME_TWO, TEST_AFFECTED_PACKAGE_NAME,
                        mUserId,
                        100);
        AppSaturationController.computeGrayscaleTransformMatrix(0.7f, mMatrix);
    }
}