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

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

Merge "Add KeyboardBacklightListener APIs to listen to backlight changes"

parents 600003cb 47c92077
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.hardware.input.KeyboardLayout;
import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.IInputDeviceBatteryListener;
import android.hardware.input.IInputDeviceBatteryState;
import android.hardware.input.IKeyboardBacklightListener;
import android.hardware.input.IKeyboardBacklightState;
import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.TouchCalibration;
import android.os.CombinedVibration;
@@ -221,4 +223,14 @@ interface IInputManager {
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
            + "android.Manifest.permission.MONITOR_INPUT)")
    void pilferPointers(IBinder inputChannelToken);

    @EnforcePermission("MONITOR_KEYBOARD_BACKLIGHT")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
            + "android.Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT)")
    void registerKeyboardBacklightListener(IKeyboardBacklightListener listener);

    @EnforcePermission("MONITOR_KEYBOARD_BACKLIGHT")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
            + "android.Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT)")
    void unregisterKeyboardBacklightListener(IKeyboardBacklightListener listener);
}
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.input;

import android.hardware.input.IKeyboardBacklightState;

/** @hide */
oneway interface IKeyboardBacklightListener {

    /**
     * Called when the keyboard backlight brightness is changed.
     */
    void onBrightnessChanged(int deviceId, in IKeyboardBacklightState state, boolean isTriggeredByKeyPress);
}
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.input;

/** @hide */
@JavaDerive(equals=true)
parcelable IKeyboardBacklightState {
    /** Current brightness level of the keyboard backlight in the range [0, maxBrightnessLevel]*/
    int brightnessLevel;

    /** Maximum brightness level of keyboard backlight */
    int maxBrightnessLevel;
}
 No newline at end of file
+150 −0
Original line number Diff line number Diff line
@@ -119,6 +119,12 @@ public final class InputManager {
    @GuardedBy("mBatteryListenersLock")
    private IInputDeviceBatteryListener mInputDeviceBatteryListener;

    private final Object mKeyboardBacklightListenerLock = new Object();
    @GuardedBy("mKeyboardBacklightListenerLock")
    private List<KeyboardBacklightListenerDelegate> mKeyboardBacklightListeners;
    @GuardedBy("mKeyboardBacklightListenerLock")
    private IKeyboardBacklightListener mKeyboardBacklightListener;

    private InputDeviceSensorManager mInputDeviceSensorManager;
    /**
     * Broadcast Action: Query available keyboard layouts.
@@ -2280,6 +2286,74 @@ public final class InputManager {
        // TODO: set the right setting
    }

    /**
     * Registers a Keyboard backlight change listener to be notified about {@link
     * KeyboardBacklightState} changes for connected keyboard devices.
     *
     * @param executor an executor on which the callback will be called
     * @param listener the {@link KeyboardBacklightListener}
     * @hide
     * @see #unregisterKeyboardBacklightListener(KeyboardBacklightListener)
     * @throws IllegalArgumentException if {@code listener} has already been registered previously.
     * @throws NullPointerException if {@code listener} or {@code executor} is null.
     */
    @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT)
    public void registerKeyboardBacklightListener(@NonNull Executor executor,
            @NonNull KeyboardBacklightListener listener) throws IllegalArgumentException {
        Objects.requireNonNull(executor, "executor should not be null");
        Objects.requireNonNull(listener, "listener should not be null");

        synchronized (mKeyboardBacklightListenerLock) {
            if (mKeyboardBacklightListener == null) {
                mKeyboardBacklightListeners = new ArrayList<>();
                mKeyboardBacklightListener = new LocalKeyboardBacklightListener();

                try {
                    mIm.registerKeyboardBacklightListener(mKeyboardBacklightListener);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            for (KeyboardBacklightListenerDelegate delegate : mKeyboardBacklightListeners) {
                if (delegate.mListener == listener) {
                    throw new IllegalArgumentException("Listener has already been registered!");
                }
            }
            KeyboardBacklightListenerDelegate delegate =
                    new KeyboardBacklightListenerDelegate(listener, executor);
            mKeyboardBacklightListeners.add(delegate);
        }
    }

    /**
     * Unregisters a previously added Keyboard backlight change listener.
     *
     * @param listener the {@link KeyboardBacklightListener}
     * @see #registerKeyboardBacklightListener(Executor, KeyboardBacklightListener)
     * @hide
     */
    @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT)
    public void unregisterKeyboardBacklightListener(
            @NonNull KeyboardBacklightListener listener) {
        Objects.requireNonNull(listener, "listener should not be null");

        synchronized (mKeyboardBacklightListenerLock) {
            if (mKeyboardBacklightListeners == null) {
                return;
            }
            mKeyboardBacklightListeners.removeIf((delegate) -> delegate.mListener == listener);
            if (mKeyboardBacklightListeners.isEmpty()) {
                try {
                    mIm.unregisterKeyboardBacklightListener(mKeyboardBacklightListener);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
                mKeyboardBacklightListeners = null;
                mKeyboardBacklightListener = null;
            }
        }
    }

    /**
     * A callback used to be notified about battery state changes for an input device. The
     * {@link #onBatteryStateChanged(int, long, BatteryState)} method will be called once after the
@@ -2373,6 +2447,27 @@ public final class InputManager {
        void onTabletModeChanged(long whenNanos, boolean inTabletMode);
    }

    /**
     * A callback used to be notified about keyboard backlight state changes for keyboard device.
     * The {@link #onKeyboardBacklightChanged(int, KeyboardBacklightState, boolean)} method
     * will be called once after the listener is successfully registered to provide the initial
     * keyboard backlight state of the device.
     * @see #registerKeyboardBacklightListener(Executor, KeyboardBacklightListener)
     * @see #unregisterKeyboardBacklightListener(KeyboardBacklightListener)
     * @hide
     */
    public interface KeyboardBacklightListener {
        /**
         * Called when the keyboard backlight brightness level changes.
         * @param deviceId the keyboard for which the backlight brightness changed.
         * @param state the new keyboard backlight state, never null.
         * @param isTriggeredByKeyPress whether brightness change was triggered by the user
         *                              pressing up/down key on the keyboard.
         */
        void onKeyboardBacklightChanged(
                int deviceId, @NonNull KeyboardBacklightState state, boolean isTriggeredByKeyPress);
    }

    private final class TabletModeChangedListener extends ITabletModeChangedListener.Stub {
        @Override
        public void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
@@ -2481,4 +2576,59 @@ public final class InputManager {
            }
        }
    }

    // Implementation of the android.hardware.input.KeyboardBacklightState interface used to report
    // the keyboard backlight state via the KeyboardBacklightListener interfaces.
    private static final class LocalKeyboardBacklightState extends KeyboardBacklightState {

        private final int mBrightnessLevel;
        private final int mMaxBrightnessLevel;

        LocalKeyboardBacklightState(int brightnesslevel, int maxBrightnessLevel) {
            mBrightnessLevel = brightnesslevel;
            mMaxBrightnessLevel = maxBrightnessLevel;
        }

        @Override
        public int getBrightnessLevel() {
            return mBrightnessLevel;
        }

        @Override
        public int getMaxBrightnessLevel() {
            return mMaxBrightnessLevel;
        }
    }

    private static final class KeyboardBacklightListenerDelegate {
        final KeyboardBacklightListener mListener;
        final Executor mExecutor;

        KeyboardBacklightListenerDelegate(KeyboardBacklightListener listener, Executor executor) {
            mListener = listener;
            mExecutor = executor;
        }

        void notifyKeyboardBacklightChange(int deviceId, IKeyboardBacklightState state,
                boolean isTriggeredByKeyPress) {
            mExecutor.execute(() ->
                    mListener.onKeyboardBacklightChanged(deviceId,
                            new LocalKeyboardBacklightState(state.brightnessLevel,
                                    state.maxBrightnessLevel), isTriggeredByKeyPress));
        }
    }

    private class LocalKeyboardBacklightListener extends IKeyboardBacklightListener.Stub {

        @Override
        public void onBrightnessChanged(int deviceId, IKeyboardBacklightState state,
                boolean isTriggeredByKeyPress) {
            synchronized (mKeyboardBacklightListenerLock) {
                if (mKeyboardBacklightListeners == null) return;
                for (KeyboardBacklightListenerDelegate delegate : mKeyboardBacklightListeners) {
                    delegate.notifyKeyboardBacklightChange(deviceId, state, isTriggeredByKeyPress);
                }
            }
        }
    }
}
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.input;

/**
 * The KeyboardBacklightState class is a representation of a keyboard backlight which is a
 * single-colored backlight that illuminates all the keys on the keyboard.
 *
 * @hide
 */
public abstract class KeyboardBacklightState {

    /**
     * Get the backlight brightness level in range [0, {@link #getMaxBrightnessLevel()}].
     *
     * @return backlight brightness level
     */
    public abstract int getBrightnessLevel();

    /**
     * Get the max backlight brightness level.
     *
     * @return max backlight brightness level
     */
    public abstract int getMaxBrightnessLevel();
}
Loading