mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[androiddebugbridge] Fix volume channel for android 11/12 (#13828)
* [androiddebugbridge] Fix volume channel for android 11/12 * [androiddebugbridge] Try get max volume level from device properties * [androiddebugbridge] Fixes reported code analysis * [androiddebugbridge] Fix comparison Signed-off-by: Miguel Álvarez <miguelwork92@gmail.com>
This commit is contained in:
parent
d777aa46c9
commit
3e068ed431
@ -50,6 +50,8 @@ You could customize the discovery process through the binding options.
|
||||
| refreshTime | int | Seconds between device status refreshes (default: 30) |
|
||||
| timeout | int | Command timeout in seconds (default: 5) |
|
||||
| recordDuration | int | Record input duration in seconds |
|
||||
| deviceMaxVolume | int | Assumed max volume for devices with android versions that do not expose this value. |
|
||||
| volumeSettingKey | String | Settings key for android versions where volume is gather using settings command (>=android 11). |
|
||||
| mediaStateJSONConfig | String | Expects a JSON array. Allow to configure the media state detection method per app. Described in the following section |
|
||||
|
||||
## Media State Detection
|
||||
|
@ -42,6 +42,14 @@ public class AndroidDebugBridgeConfiguration {
|
||||
* Record input duration in seconds.
|
||||
*/
|
||||
public int recordDuration = 5;
|
||||
/**
|
||||
* Assumed max volume for devices with android versions that do not expose this value (>=android 11).
|
||||
*/
|
||||
public int deviceMaxVolume = 25;
|
||||
/**
|
||||
* Settings key for android versions where volume is gather using settings command (>=android 11).
|
||||
*/
|
||||
public String volumeSettingKey = "volume_music_hdmi";
|
||||
/**
|
||||
* Configure media state detection behavior by package
|
||||
*/
|
||||
|
@ -97,22 +97,34 @@ public class AndroidDebugBridgeDevice {
|
||||
private int port = 5555;
|
||||
private int timeoutSec = 5;
|
||||
private int recordDuration;
|
||||
private @Nullable Integer maxVolumeLevel = null;
|
||||
private @Nullable Socket socket;
|
||||
private @Nullable AdbConnection connection;
|
||||
private @Nullable Future<String> commandFuture;
|
||||
private int majorVersionNumber = 0;
|
||||
private int minorVersionNumber = 0;
|
||||
private int patchVersionNumber = 0;
|
||||
/**
|
||||
* Assumed max volume for android versions that do not expose this value.
|
||||
*/
|
||||
private int deviceMaxVolume = 25;
|
||||
private String volumeSettingKey = "volume_music_hdmi";
|
||||
|
||||
public AndroidDebugBridgeDevice(ScheduledExecutorService scheduler) {
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
public void configure(String ip, int port, int timeout, int recordDuration) {
|
||||
public void configure(AndroidDebugBridgeConfiguration config) {
|
||||
configureConnection(config.ip, config.port, config.timeout);
|
||||
this.recordDuration = config.recordDuration;
|
||||
this.volumeSettingKey = config.volumeSettingKey;
|
||||
this.deviceMaxVolume = config.deviceMaxVolume;
|
||||
}
|
||||
|
||||
public void configureConnection(String ip, int port, int timeout) {
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.timeoutSec = timeout;
|
||||
this.recordDuration = recordDuration;
|
||||
}
|
||||
|
||||
public void sendKeyEvent(String eventCode)
|
||||
@ -291,7 +303,16 @@ public class AndroidDebugBridgeDevice {
|
||||
|
||||
private void setVolume(int stream, int volume)
|
||||
throws AndroidDebugBridgeDeviceException, InterruptedException, TimeoutException, ExecutionException {
|
||||
runAdbShell("media", "volume", "--show", "--stream", String.valueOf(stream), "--set", String.valueOf(volume));
|
||||
if (isAtLeastVersion(12)) {
|
||||
runAdbShell("service", "call", "audio", "11", "i32", String.valueOf(stream), "i32", String.valueOf(volume),
|
||||
"i32", "1");
|
||||
} else if (isAtLeastVersion(11)) {
|
||||
runAdbShell("service", "call", "audio", "10", "i32", String.valueOf(stream), "i32", String.valueOf(volume),
|
||||
"i32", "1");
|
||||
} else {
|
||||
runAdbShell("media", "volume", "--show", "--stream", String.valueOf(stream), "--set",
|
||||
String.valueOf(volume));
|
||||
}
|
||||
}
|
||||
|
||||
public String getModel() throws AndroidDebugBridgeDeviceException, InterruptedException,
|
||||
@ -353,17 +374,32 @@ public class AndroidDebugBridgeDevice {
|
||||
|
||||
private VolumeInfo getVolume(int stream) throws AndroidDebugBridgeDeviceException, InterruptedException,
|
||||
AndroidDebugBridgeDeviceReadException, TimeoutException, ExecutionException {
|
||||
String volumeResp = runAdbShell("media", "volume", "--show", "--stream", String.valueOf(stream), "--get", "|",
|
||||
"grep", "volume");
|
||||
Matcher matcher = VOLUME_PATTERN.matcher(volumeResp);
|
||||
if (!matcher.find()) {
|
||||
throw new AndroidDebugBridgeDeviceReadException("Unable to get volume info");
|
||||
if (isAtLeastVersion(11)) {
|
||||
String volumeResp = runAdbShell("settings", "get", "system", volumeSettingKey);
|
||||
var maxVolumeLevel = this.maxVolumeLevel;
|
||||
if (maxVolumeLevel == null) {
|
||||
try {
|
||||
maxVolumeLevel = Integer.parseInt(getDeviceProp("ro.config.media_vol_steps"));
|
||||
this.maxVolumeLevel = maxVolumeLevel;
|
||||
} catch (NumberFormatException ignored) {
|
||||
logger.debug("Max volume level not available, using 'deviceMaxVolume' config");
|
||||
maxVolumeLevel = deviceMaxVolume;
|
||||
}
|
||||
}
|
||||
return new VolumeInfo(Integer.parseInt(volumeResp.replace("\n", "")), 0, maxVolumeLevel);
|
||||
} else {
|
||||
String volumeResp = runAdbShell("media", "volume", "--show", "--stream", String.valueOf(stream), "--get",
|
||||
"|", "grep", "volume");
|
||||
Matcher matcher = VOLUME_PATTERN.matcher(volumeResp);
|
||||
if (!matcher.find()) {
|
||||
throw new AndroidDebugBridgeDeviceReadException("Unable to get volume info");
|
||||
}
|
||||
var volumeInfo = new VolumeInfo(Integer.parseInt(matcher.group("current")),
|
||||
Integer.parseInt(matcher.group("min")), Integer.parseInt(matcher.group("max")));
|
||||
logger.debug("Device {}:{} VolumeInfo: current {}, min {}, max {}", this.ip, this.port, volumeInfo.current,
|
||||
volumeInfo.min, volumeInfo.max);
|
||||
return volumeInfo;
|
||||
}
|
||||
var volumeInfo = new VolumeInfo(Integer.parseInt(matcher.group("current")),
|
||||
Integer.parseInt(matcher.group("min")), Integer.parseInt(matcher.group("max")));
|
||||
logger.debug("Device {}:{} VolumeInfo: current {}, min {}, max {}", this.ip, this.port, volumeInfo.current,
|
||||
volumeInfo.min, volumeInfo.max);
|
||||
return volumeInfo;
|
||||
}
|
||||
|
||||
public String recordInputEvents()
|
||||
|
@ -320,8 +320,7 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
||||
if (mediaStateJSONConfig != null && !mediaStateJSONConfig.isEmpty()) {
|
||||
loadMediaStateConfig(mediaStateJSONConfig);
|
||||
}
|
||||
adbConnection.configure(currentConfig.ip, currentConfig.port, currentConfig.timeout,
|
||||
currentConfig.recordDuration);
|
||||
adbConnection.configure(currentConfig);
|
||||
var androidVersion = thing.getProperties().get(Thing.PROPERTY_FIRMWARE_VERSION);
|
||||
if (androidVersion != null) {
|
||||
// configure android implementation to use
|
||||
|
@ -135,7 +135,7 @@ public class AndroidDebugBridgeDiscoveryService extends AbstractDiscoveryService
|
||||
throws InterruptedException, AndroidDebugBridgeDeviceException, AndroidDebugBridgeDeviceReadException,
|
||||
TimeoutException, ExecutionException {
|
||||
var device = new AndroidDebugBridgeDevice(scheduler);
|
||||
device.configure(ip, port, 10, 0);
|
||||
device.configureConnection(ip, port, 10);
|
||||
try {
|
||||
device.connect();
|
||||
logger.debug("connected adb at {}:{}", ip, port);
|
||||
|
@ -34,8 +34,6 @@ import org.osgi.service.component.ComponentContext;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Modified;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link AndroidTVMDNSDiscoveryParticipant} is responsible for discovering new and removed Android TV devices. It
|
||||
@ -50,7 +48,6 @@ public class AndroidTVMDNSDiscoveryParticipant implements MDNSDiscoveryParticipa
|
||||
|
||||
private static final String SERVICE_TYPE = "_androidtvremote2._tcp.local.";
|
||||
private static final String MDNS_PROPERTY_MAC_ADDRESS = "bt";
|
||||
private final Logger logger = LoggerFactory.getLogger(AndroidTVMDNSDiscoveryParticipant.class);
|
||||
|
||||
private boolean isAutoDiscoveryEnabled = true;
|
||||
|
||||
|
@ -21,6 +21,8 @@ thing-type.androiddebugbridge.android.description = Android Device Thing for And
|
||||
|
||||
# thing types config
|
||||
|
||||
thing-type.config.androiddebugbridge.android.deviceMaxVolume.label = Device Max Volume
|
||||
thing-type.config.androiddebugbridge.android.deviceMaxVolume.description = Assumed max volume for devices with android versions that do not expose this value (>=android 11).
|
||||
thing-type.config.androiddebugbridge.android.ip.label = IP Address
|
||||
thing-type.config.androiddebugbridge.android.ip.description = Device ip address.
|
||||
thing-type.config.androiddebugbridge.android.mediaStateJSONConfig.label = Media State Config
|
||||
@ -33,6 +35,16 @@ thing-type.config.androiddebugbridge.android.refreshTime.label = Refresh Time
|
||||
thing-type.config.androiddebugbridge.android.refreshTime.description = Seconds between device status refreshes.
|
||||
thing-type.config.androiddebugbridge.android.timeout.label = Command Timeout
|
||||
thing-type.config.androiddebugbridge.android.timeout.description = Command timeout seconds.
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.label = Volume Setting Key
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.description = Settings key for android versions where the volume level is gathered using the 'settings' cli (>=android 11).
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_bluetooth_sco = volume bluetooth sco
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_music = volume music
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_music_bt_a2dp = volume music bt a2dp
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_music_hdmi = volume music hdmi
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_music_headphone = volume music headphone
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_music_headset = volume music headset
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_music_usb_headset = volume music usb headset
|
||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_system = volume system
|
||||
|
||||
# channel types
|
||||
|
||||
|
@ -58,6 +58,29 @@
|
||||
<description>JSON config that allows to modify the media state detection strategy for each app. Refer to the binding
|
||||
documentation.</description>
|
||||
</parameter>
|
||||
<parameter name="volumeSettingKey" type="text">
|
||||
<label>Volume Setting Key</label>
|
||||
<description>Settings key for android versions where the volume level is gathered using the 'settings' cli
|
||||
(>=android 11).</description>
|
||||
<default>volume_music_hdmi</default>
|
||||
<options>
|
||||
<option value="volume_bluetooth_sco">volume bluetooth sco</option>
|
||||
<option value="volume_music">volume music</option>
|
||||
<option value="volume_music_bt_a2dp">volume music bt a2dp</option>
|
||||
<option value="volume_music_hdmi">volume music hdmi</option>
|
||||
<option value="volume_music_headphone">volume music headphone</option>
|
||||
<option value="volume_music_headset">volume music headset</option>
|
||||
<option value="volume_music_usb_headset">volume music usb headset</option>
|
||||
<option value="volume_system">volume system</option>
|
||||
</options>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
<parameter name="deviceMaxVolume" type="integer" min="1" max="100">
|
||||
<label>Device Max Volume</label>
|
||||
<description>Assumed max volume for devices with android versions that do not expose this value (>=android 11).</description>
|
||||
<default>25</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user