Using reflection to get private BluetoothHearingAid APIs for short term

* APIs: getDeviceSideInternal(), getDeviceModeInternal()

Bug: 224323976
Test: manual test
Change-Id: I76e078225634bd9a58fd6cdddd53a3ff9d4c6348
This commit is contained in:
jasonwshsu
2022-04-25 16:41:56 +08:00
parent d2303d97a4
commit 7e923104ff

View File

@@ -29,13 +29,48 @@ import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.util.Log;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import com.android.settingslib.R;
import com.android.settingslib.Utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class HearingAidProfile implements LocalBluetoothProfile {
@Retention(RetentionPolicy.SOURCE)
@IntDef({
DeviceSide.SIDE_INVALID,
DeviceSide.SIDE_LEFT,
DeviceSide.SIDE_RIGHT
})
/** Side definition for hearing aids. See {@link BluetoothHearingAid}. */
public @interface DeviceSide {
int SIDE_INVALID = -1;
int SIDE_LEFT = 0;
int SIDE_RIGHT = 1;
}
@Retention(RetentionPolicy.SOURCE)
@IntDef({
DeviceMode.MODE_INVALID,
DeviceMode.MODE_MONAURAL,
DeviceMode.MODE_BINAURAL
})
/** Mode definition for hearing aids. See {@link BluetoothHearingAid}. */
public @interface DeviceMode {
int MODE_INVALID = -1;
int MODE_MONAURAL = 0;
int MODE_BINAURAL = 1;
}
private static final String TAG = "HearingAidProfile";
private static boolean V = true;
@@ -212,6 +247,11 @@ public class HearingAidProfile implements LocalBluetoothProfile {
return isEnabled;
}
/**
* Tells remote device to set an absolute volume.
*
* @param volume Absolute volume to be set on remote
*/
public void setVolume(int volume) {
if (mService == null) {
return;
@@ -219,6 +259,12 @@ public class HearingAidProfile implements LocalBluetoothProfile {
mService.setVolume(volume);
}
/**
* Gets the HiSyncId (unique hearing aid device identifier) of the device.
*
* @param device Bluetooth device
* @return the HiSyncId of the device
*/
public long getHiSyncId(BluetoothDevice device) {
if (mService == null || device == null) {
return BluetoothHearingAid.HI_SYNC_ID_INVALID;
@@ -226,6 +272,59 @@ public class HearingAidProfile implements LocalBluetoothProfile {
return mService.getHiSyncId(device);
}
/**
* Gets the side of the device.
*
* @param device Bluetooth device.
* @return side of the device. See {@link DeviceSide}.
*/
@DeviceSide
public int getDeviceSide(@NonNull BluetoothDevice device) {
final int defaultValue = DeviceSide.SIDE_INVALID;
if (mService == null) {
Log.w(TAG, "Proxy not attached to HearingAidService");
return defaultValue;
}
try {
Method method = mService.getClass().getDeclaredMethod("getDeviceSideInternal",
BluetoothDevice.class);
method.setAccessible(true);
return (int) method.invoke(mService, device);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Log.e(TAG, "fail to get getDeviceSideInternal\n" + e.toString() + "\n"
+ Log.getStackTraceString(new Throwable()));
return defaultValue;
}
}
/**
* Gets the mode of the device.
*
* @param device Bluetooth device
* @return mode of the device. See {@link DeviceMode}.
*/
@DeviceMode
public int getDeviceMode(@NonNull BluetoothDevice device) {
final int defaultValue = DeviceMode.MODE_INVALID;
if (mService == null) {
Log.w(TAG, "Proxy not attached to HearingAidService");
return defaultValue;
}
try {
Method method = mService.getClass().getDeclaredMethod("getDeviceModeInternal",
BluetoothDevice.class);
method.setAccessible(true);
return (int) method.invoke(mService, device);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Log.e(TAG, "fail to get getDeviceModeInternal\n" + e.toString() + "\n"
+ Log.getStackTraceString(new Throwable()));
return defaultValue;
}
}
public String toString() {
return NAME;
}