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

Commit e513b7ff authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Add hidden API to query the bluetooth address of an InputDevice

Since revealing the bluetooth address of an input device can reveal
whether bluetooth is enabled, we require the BLUETOOTH permission for
this API.

This also means we cannot send the bluetooth address to apps using the
InputDevice class. We add an IInputManager method to query the address
instead that performs the permission check.

Since we are not using the Java InputDevice class to store the address,
we must cache the vector of last-reported InputDeviceInfos in
NativeInputManager.

DD: go/inputdevice-battery-notifications

Bug: 243005009
Test: manual
Change-Id: I560cb170ab7008314821e5150caf4868efb5d8d5
parent 7a762763
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -161,4 +161,11 @@ interface IInputManager {
    void registerBatteryListener(int deviceId, IInputDeviceBatteryListener listener);

    void unregisterBatteryListener(int deviceId, IInputDeviceBatteryListener listener);

    // Get the bluetooth address of an input device if known, returning null if it either is not
    // connected via bluetooth or if the address cannot be determined.
    @EnforcePermission("BLUETOOTH")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
            + "android.Manifest.permission.BLUETOOTH)")
    String getInputDeviceBluetoothAddress(int deviceId);
}
+18 −0
Original line number Diff line number Diff line
@@ -1480,6 +1480,24 @@ public final class InputManager {
        }
    }

    /**
     * Returns the Bluetooth address of this input device, if known.
     *
     * The returned string is always null if this input device is not connected
     * via Bluetooth, or if the Bluetooth address of the device cannot be
     * determined. The returned address will look like: "11:22:33:44:55:66".
     * @hide
     */
    @RequiresPermission(Manifest.permission.BLUETOOTH)
    @Nullable
    public String getInputDeviceBluetoothAddress(int deviceId) {
        try {
            return mIm.getInputDeviceBluetoothAddress(deviceId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Gets a vibrator service associated with an input device, always creates a new instance.
     * @return The vibrator, never null.
+17 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1009,6 +1010,22 @@ public final class InputDevice implements Parcelable {
        mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution));
    }

    /**
     * Returns the Bluetooth address of this input device, if known.
     *
     * The returned string is always null if this input device is not connected
     * via Bluetooth, or if the Bluetooth address of the device cannot be
     * determined. The returned address will look like: "11:22:33:44:55:66".
     * @hide
     */
    @RequiresPermission(Manifest.permission.BLUETOOTH)
    @Nullable
    public String getBluetoothAddress() {
        // We query the address via a separate InputManager API instead of pre-populating it in
        // this class to avoid leaking it to apps that do not have sufficient permissions.
        return InputManager.getInstance().getInputDeviceBluetoothAddress(mId);
    }

    /**
     * Gets the vibrator service associated with the device, if there is one.
     * Even if the device does not have a vibrator, the result is never null.
+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi
                                          deviceInfo.hasMic(), deviceInfo.hasButtonUnderPad(),
                                          deviceInfo.hasSensor(), deviceInfo.hasBattery(),
                                          deviceInfo.supportsUsi()));
    // Note: We do not populate the Bluetooth address into the InputDevice object to avoid leaking
    // it to apps that do not have the Bluetooth permission.

    const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
    for (const InputDeviceInfo::MotionRange& range: ranges) {
+8 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server.input;
import static android.provider.DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT;
import static android.view.KeyEvent.KEYCODE_UNKNOWN;

import android.Manifest;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
@@ -2671,6 +2673,12 @@ public class InputManagerService extends IInputManager.Stub
        mBatteryController.unregisterBatteryListener(deviceId, listener, Binder.getCallingPid());
    }

    @EnforcePermission(Manifest.permission.BLUETOOTH)
    @Override
    public String getInputDeviceBluetoothAddress(int deviceId) {
        return mNative.getBluetoothAddress(deviceId);
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Loading