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

Commit b37eb3e4 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Android (Google) Code Review
Browse files

Merge "Add support for custom keyboard backlight levels via IDC file" into udc-qpr-dev

parents 0e40cea7 3becba6b
Loading
Loading
Loading
Loading
+29 −1
Original line number Diff line number Diff line
@@ -110,6 +110,8 @@ public final class Light implements Parcelable {
    private final int mOrdinal;
    private final int mType;
    private final int mCapabilities;
    @Nullable
    private final int[] mPreferredBrightnessLevels;

    /**
     * Creates a new light with the given data.
@@ -117,7 +119,7 @@ public final class Light implements Parcelable {
     * @hide
     */
    public Light(int id, int ordinal, int type) {
        this(id, "Light", ordinal, type, 0);
        this(id, "Light", ordinal, type, 0, null);
    }

    /**
@@ -126,11 +128,22 @@ public final class Light implements Parcelable {
     * @hide
     */
    public Light(int id, String name, int ordinal, int type, int capabilities) {
        this(id, name, ordinal, type, capabilities, null);
    }

    /**
     * Creates a new light with the given data.
     *
     * @hide
     */
    public Light(int id, String name, int ordinal, int type, int capabilities,
            @Nullable int[] preferredBrightnessLevels) {
        mId = id;
        mName = name;
        mOrdinal = ordinal;
        mType = type;
        mCapabilities = capabilities;
        mPreferredBrightnessLevels = preferredBrightnessLevels;
    }

    private Light(@NonNull Parcel in) {
@@ -139,6 +152,7 @@ public final class Light implements Parcelable {
        mOrdinal = in.readInt();
        mType = in.readInt();
        mCapabilities = in.readInt();
        mPreferredBrightnessLevels = in.createIntArray();
    }

    /** Implement the Parcelable interface */
@@ -149,6 +163,7 @@ public final class Light implements Parcelable {
        dest.writeInt(mOrdinal);
        dest.writeInt(mType);
        dest.writeInt(mCapabilities);
        dest.writeIntArray(mPreferredBrightnessLevels);
    }

    /** Implement the Parcelable interface */
@@ -252,4 +267,17 @@ public final class Light implements Parcelable {
        return (mCapabilities & LIGHT_CAPABILITY_COLOR_RGB) == LIGHT_CAPABILITY_COLOR_RGB;
    }

    /**
     * Returns preferred brightness levels for the light which will be used when user
     * increase/decrease brightness levels for the light (currently only used for Keyboard
     * backlight control using backlight up/down keys).
     *
     * The values in the preferred brightness level array are in the range [0, 255].
     *
     * @hide
     */
    @Nullable
    public int[] getPreferredBrightnessLevels() {
        return mPreferredBrightnessLevels;
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -38,8 +38,15 @@ public final class InputFeatureFlagProvider {
    private static final boolean KEYBOARD_BACKLIGHT_ANIMATION_ENABLED =
            InputProperties.enable_keyboard_backlight_animation().orElse(false);

    // To disable Custom keyboard backlight levels support via IDC files run:
    // adb shell setprop persist.input.keyboard_backlight_custom_levels.enabled false (requires
    // restart)
    private static final boolean KEYBOARD_BACKLIGHT_CUSTOM_LEVELS_ENABLED =
            InputProperties.enable_keyboard_backlight_custom_levels().orElse(true);

    private static Optional<Boolean> sKeyboardBacklightControlOverride = Optional.empty();
    private static Optional<Boolean> sKeyboardBacklightAnimationOverride = Optional.empty();
    private static Optional<Boolean> sKeyboardBacklightCustomLevelsOverride = Optional.empty();

    public static boolean isKeyboardBacklightControlEnabled() {
        return sKeyboardBacklightControlOverride.orElse(KEYBOARD_BACKLIGHT_CONTROL_ENABLED);
@@ -49,6 +56,11 @@ public final class InputFeatureFlagProvider {
        return sKeyboardBacklightAnimationOverride.orElse(KEYBOARD_BACKLIGHT_ANIMATION_ENABLED);
    }

    public static boolean isKeyboardBacklightCustomLevelsEnabled() {
        return sKeyboardBacklightCustomLevelsOverride.orElse(
                KEYBOARD_BACKLIGHT_CUSTOM_LEVELS_ENABLED);
    }

    public static void setKeyboardBacklightControlEnabled(boolean enabled) {
        sKeyboardBacklightControlOverride = Optional.of(enabled);
    }
@@ -57,11 +69,16 @@ public final class InputFeatureFlagProvider {
        sKeyboardBacklightAnimationOverride = Optional.of(enabled);
    }

    public static void setKeyboardBacklightCustomLevelsEnabled(boolean enabled) {
        sKeyboardBacklightCustomLevelsOverride = Optional.of(enabled);
    }

    /**
     * Clears all input feature flag overrides.
     */
    public static void clearOverrides() {
        sKeyboardBacklightControlOverride = Optional.empty();
        sKeyboardBacklightAnimationOverride = Optional.empty();
        sKeyboardBacklightCustomLevelsOverride = Optional.empty();
    }
}
+54 −18
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import java.time.Duration;
import java.util.Arrays;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.TreeSet;

/**
 * A thread-safe component of {@link InputManagerService} responsible for managing the keyboard
@@ -70,7 +71,9 @@ final class KeyboardBacklightController implements
    private static final int MSG_NOTIFY_USER_INACTIVITY = 5;
    private static final int MSG_INTERACTIVE_STATE_CHANGED = 6;
    private static final int MAX_BRIGHTNESS = 255;
    private static final int NUM_BRIGHTNESS_CHANGE_STEPS = 10;
    private static final int DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS = 10;
    @VisibleForTesting
    static final int MAX_BRIGHTNESS_CHANGE_STEPS = 10;
    private static final long TRANSITION_ANIMATION_DURATION_MILLIS =
            Duration.ofSeconds(1).toMillis();

@@ -80,7 +83,8 @@ final class KeyboardBacklightController implements
    static final long USER_INACTIVITY_THRESHOLD_MILLIS = Duration.ofSeconds(30).toMillis();

    @VisibleForTesting
    static final int[] BRIGHTNESS_VALUE_FOR_LEVEL = new int[NUM_BRIGHTNESS_CHANGE_STEPS + 1];
    static final int[] DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL =
            new int[DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS + 1];

    private final Context mContext;
    private final NativeInputManagerService mNative;
@@ -104,10 +108,10 @@ final class KeyboardBacklightController implements
    static {
        // Fixed brightness levels to avoid issues when converting back and forth from the
        // device brightness range to [0-255]
        // Levels are: 0, 25, 51, ..., 255
        for (int i = 0; i <= NUM_BRIGHTNESS_CHANGE_STEPS; i++) {
            BRIGHTNESS_VALUE_FOR_LEVEL[i] = (int) Math.floor(
                    ((float) i * MAX_BRIGHTNESS) / NUM_BRIGHTNESS_CHANGE_STEPS);
        // Levels are: 0, 51, ..., 255
        for (int i = 0; i <= DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS; i++) {
            DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[i] = (int) Math.floor(
                    ((float) i * MAX_BRIGHTNESS) / DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS);
        }
    }

@@ -184,7 +188,8 @@ final class KeyboardBacklightController implements
        final int currBrightnessLevel = state.mBrightnessLevel;
        final int newBrightnessLevel;
        if (direction == Direction.DIRECTION_UP) {
            newBrightnessLevel = Math.min(currBrightnessLevel + 1, NUM_BRIGHTNESS_CHANGE_STEPS);
            newBrightnessLevel = Math.min(currBrightnessLevel + 1,
                    state.getNumBrightnessChangeSteps());
        } else {
            newBrightnessLevel = Math.max(currBrightnessLevel - 1, 0);
        }
@@ -194,7 +199,7 @@ final class KeyboardBacklightController implements
            try {
                mDataStore.setKeyboardBacklightBrightness(inputDevice.getDescriptor(),
                        keyboardBacklight.getId(),
                        BRIGHTNESS_VALUE_FOR_LEVEL[newBrightnessLevel]);
                        state.mBrightnessValueForLevel[newBrightnessLevel]);
            } finally {
                mDataStore.saveIfNeeded();
            }
@@ -202,6 +207,7 @@ final class KeyboardBacklightController implements
    }

    private void restoreBacklightBrightness(InputDevice inputDevice, Light keyboardBacklight) {
        KeyboardBacklightState state = mKeyboardBacklights.get(inputDevice.getId());
        OptionalInt brightness;
        synchronized (mDataStore) {
            brightness = mDataStore.getKeyboardBacklightBrightness(
@@ -209,9 +215,9 @@ final class KeyboardBacklightController implements
        }
        if (brightness.isPresent()) {
            int brightnessValue = Math.max(0, Math.min(MAX_BRIGHTNESS, brightness.getAsInt()));
            int index = Arrays.binarySearch(BRIGHTNESS_VALUE_FOR_LEVEL, brightnessValue);
            int index = Arrays.binarySearch(state.mBrightnessValueForLevel, brightnessValue);
            if (index < 0) {
                index = Math.min(NUM_BRIGHTNESS_CHANGE_STEPS, -(index + 1));
                index = Math.min(state.getNumBrightnessChangeSteps(), -(index + 1));
            }
            updateBacklightState(inputDevice.getId(), index, false /* isTriggeredByKeyPress */);
            if (DEBUG) {
@@ -386,7 +392,7 @@ final class KeyboardBacklightController implements
            for (int i = 0; i < mKeyboardBacklightListenerRecords.size(); i++) {
                IKeyboardBacklightState callbackState = new IKeyboardBacklightState();
                callbackState.brightnessLevel = brightnessLevel;
                callbackState.maxBrightnessLevel = NUM_BRIGHTNESS_CHANGE_STEPS;
                callbackState.maxBrightnessLevel = state.getNumBrightnessChangeSteps();
                mKeyboardBacklightListenerRecords.valueAt(i).notifyKeyboardBacklightChanged(
                        deviceId, callbackState, isTriggeredByKeyPress);
            }
@@ -443,10 +449,6 @@ final class KeyboardBacklightController implements
        ipw.decreaseIndent();
    }

    private static boolean isAnimationEnabled() {
        return InputFeatureFlagProvider.isKeyboardBacklightAnimationEnabled();
    }

    // A record of a registered Keyboard backlight listener from one process.
    private class KeyboardBacklightListenerRecord implements IBinder.DeathRecipient {
        public final int mPid;
@@ -482,18 +484,52 @@ final class KeyboardBacklightController implements
        private final Light mLight;
        private int mBrightnessLevel;
        private ValueAnimator mAnimator;
        private final int[] mBrightnessValueForLevel;

        KeyboardBacklightState(int deviceId, Light light) {
            mDeviceId = deviceId;
            mLight = light;
            mBrightnessValueForLevel = setupBrightnessLevels();
        }

        private int[] setupBrightnessLevels() {
            if (!InputFeatureFlagProvider.isKeyboardBacklightCustomLevelsEnabled()) {
                return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL;
            }
            int[] customLevels = mLight.getPreferredBrightnessLevels();
            if (customLevels == null || customLevels.length == 0) {
                return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL;
            }
            TreeSet<Integer> brightnessLevels = new TreeSet<>();
            brightnessLevels.add(0);
            for (int level : customLevels) {
                if (level > 0 && level < MAX_BRIGHTNESS) {
                    brightnessLevels.add(level);
                }
            }
            brightnessLevels.add(MAX_BRIGHTNESS);
            int brightnessChangeSteps = brightnessLevels.size() - 1;
            if (brightnessChangeSteps > MAX_BRIGHTNESS_CHANGE_STEPS) {
                return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL;
            }
            int[] result = new int[brightnessLevels.size()];
            int index = 0;
            for (int val : brightnessLevels) {
                result[index++] = val;
            }
            return result;
        }

        private int getNumBrightnessChangeSteps() {
            return mBrightnessValueForLevel.length - 1;
        }

        private void onBacklightStateChanged() {
            setBacklightValue(mIsBacklightOn ? BRIGHTNESS_VALUE_FOR_LEVEL[mBrightnessLevel] : 0);
            setBacklightValue(mIsBacklightOn ? mBrightnessValueForLevel[mBrightnessLevel] : 0);
        }
        private void setBrightnessLevel(int brightnessLevel) {
            if (mIsBacklightOn) {
                setBacklightValue(BRIGHTNESS_VALUE_FOR_LEVEL[brightnessLevel]);
                setBacklightValue(mBrightnessValueForLevel[brightnessLevel]);
            }
            mBrightnessLevel = brightnessLevel;
        }
@@ -509,7 +545,7 @@ final class KeyboardBacklightController implements
            if (fromValue == toValue) {
                return;
            }
            if (isAnimationEnabled()) {
            if (InputFeatureFlagProvider.isKeyboardBacklightAnimationEnabled()) {
                startAnimation(fromValue, toValue);
            } else {
                mNative.setLightColor(mDeviceId, mLight.getId(), Color.argb(toValue, 0, 0, 0));
+14 −2
Original line number Diff line number Diff line
@@ -2214,13 +2214,25 @@ static jobject nativeGetLights(JNIEnv* env, jobject nativeImplObj, jint deviceId
            jCapability |= env->GetStaticIntField(gLightClassInfo.clazz,
                                                  gLightClassInfo.lightCapabilityColorRgb);
        }

        ScopedLocalRef<jintArray> jPreferredBrightnessLevels{env};
        if (!lightInfo.preferredBrightnessLevels.empty()) {
            std::vector<int32_t> vec;
            for (auto it : lightInfo.preferredBrightnessLevels) {
              vec.push_back(ftl::to_underlying(it));
            }
            jPreferredBrightnessLevels.reset(env->NewIntArray(vec.size()));
            env->SetIntArrayRegion(jPreferredBrightnessLevels.get(), 0, vec.size(), vec.data());
        }

        ScopedLocalRef<jobject> lightObj(env,
                                         env->NewObject(gLightClassInfo.clazz,
                                                        gLightClassInfo.constructor,
                                                        static_cast<jint>(lightInfo.id),
                                                        env->NewStringUTF(lightInfo.name.c_str()),
                                                        static_cast<jint>(lightInfo.ordinal),
                                                        jTypeId, jCapability));
                                                        jTypeId, jCapability,
                                                        jPreferredBrightnessLevels.get()));
        // Add light object to list
        env->CallBooleanMethod(jLights, gArrayListClassInfo.add, lightObj.get());
    }
@@ -2846,7 +2858,7 @@ int register_android_server_InputManager(JNIEnv* env) {
    FIND_CLASS(gLightClassInfo.clazz, "android/hardware/lights/Light");
    gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
    GET_METHOD_ID(gLightClassInfo.constructor, gLightClassInfo.clazz, "<init>",
                  "(ILjava/lang/String;III)V");
                  "(ILjava/lang/String;III[I)V");

    gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
    gLightClassInfo.lightTypeInput =
+165 −87

File changed.

Preview size limit exceeded, changes collapsed.