mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-02-04 03:14:07 +01:00
[androiddebugbridge] Reconnect on max timeouts and improve volume channel (#15788)
* [androiddebugbridge] Reconnect on max timeouts and improve volume channel --------- Signed-off-by: Miguel Álvarez <miguelwork92@gmail.com>
This commit is contained in:
parent
cb74d85eb0
commit
94d9fb7d36
@ -10,11 +10,12 @@ If you are not familiar with adb I suggest you to search "How to enable adb over
|
|||||||
|
|
||||||
This binding was tested on :
|
This binding was tested on :
|
||||||
|
|
||||||
| Device | Android version | Comments |
|
| Device | Android version | Comments |
|
||||||
|--------------------|-----------------|----------------------------|
|
|------------------------|-----------------|------------------------------------|
|
||||||
| Fire TV Stick | 7.1.2 | Volume control not working |
|
| Fire TV Stick | 7.1.2 | Volume control not working |
|
||||||
| Nexus5x | 8.1.0 | Everything works nice |
|
| Nexus5x | 8.1.0 | Everything works nice |
|
||||||
| Freebox Pop Player | 9 | Everything works nice |
|
| Freebox Pop Player | 9 | Everything works nice |
|
||||||
|
| ChromeCast Google TV | 12 | Volume control partially working |
|
||||||
|
|
||||||
Please update this document if you tested it with other android versions to reflect the compatibility of the binding.
|
Please update this document if you tested it with other android versions to reflect the compatibility of the binding.
|
||||||
|
|
||||||
@ -30,29 +31,31 @@ You could customize the discovery process through the binding options.
|
|||||||
|
|
||||||
## Binding Configuration
|
## Binding Configuration
|
||||||
|
|
||||||
| Config | Type | description |
|
| Config | Type | description |
|
||||||
|----------|----------|------------------------------|
|
|---------------------|----------|-----------------------------------------------------------------------------------|
|
||||||
| discoveryPort | int | Port used on discovery to connect to the device through adb |
|
| discoveryPort | int | Port used on discovery to connect to the device through adb |
|
||||||
| discoveryReachableMs | int | Milliseconds to wait while discovering to determine if the ip is reachable |
|
| discoveryReachableMs| int | Milliseconds to wait while discovering to determine if the ip is reachable |
|
||||||
| discoveryIpRangeMin | int | Used to limit the number of IPs checked while discovering |
|
| discoveryIpRangeMin | int | Used to limit the number of IPs checked while discovering |
|
||||||
| discoveryIpRangeMax | int | Used to limit the number of IPs checked while discovering |
|
| discoveryIpRangeMax | int | Used to limit the number of IPs checked while discovering |
|
||||||
|
|
||||||
## Thing Configuration
|
## Thing Configuration
|
||||||
|
|
||||||
| ThingTypeID | description |
|
| ThingTypeID | Description |
|
||||||
|----------|------------------------------|
|
|---------------|-------------------------|
|
||||||
| android | Android device |
|
| android | Android device |
|
||||||
|
|
||||||
| Config | Type | description |
|
| Config | Type | Description |
|
||||||
|----------|----------|------------------------------|
|
|----------------------|--------|------------------------------------------------------------------------------------------------------------------------|
|
||||||
| ip | String | Device ip address |
|
| ip | String | Device ip address. |
|
||||||
| port | int | Device port listening to adb connections (default: 5555) |
|
| port | int | Device port listening to adb connections. (default: 5555) |
|
||||||
| refreshTime | int | Seconds between device status refreshes (default: 30) |
|
| refreshTime | int | Seconds between device status refreshes. (default: 30) |
|
||||||
| timeout | int | Command timeout in seconds (default: 5) |
|
| timeout | int | Command timeout in seconds. (default: 5) |
|
||||||
| recordDuration | int | Record input duration in seconds |
|
| recordDuration | int | Record input duration in seconds. |
|
||||||
| deviceMaxVolume | int | Assumed max volume for devices with android versions that do not expose this value. |
|
| 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). |
|
| 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 |
|
| volumeStepPercent | int | Percent to increase/decrease volume. |
|
||||||
|
| mediaStateJSONConfig | String | Expects a JSON array. Allow to configure the media state detection method per app. Described in the following section. |
|
||||||
|
| maxADBTimeouts | int | Max ADB command consecutive timeouts to force to reset the connection. |
|
||||||
|
|
||||||
## Media State Detection
|
## Media State Detection
|
||||||
|
|
||||||
|
@ -42,10 +42,18 @@ public class AndroidDebugBridgeConfiguration {
|
|||||||
* Record input duration in seconds.
|
* Record input duration in seconds.
|
||||||
*/
|
*/
|
||||||
public int recordDuration = 5;
|
public int recordDuration = 5;
|
||||||
|
/**
|
||||||
|
* Percent to increase/decrease volume.
|
||||||
|
*/
|
||||||
|
public int volumeStepPercent = 15;
|
||||||
/**
|
/**
|
||||||
* Assumed max volume for devices with android versions that do not expose this value (>=android 11).
|
* Assumed max volume for devices with android versions that do not expose this value (>=android 11).
|
||||||
*/
|
*/
|
||||||
public int deviceMaxVolume = 25;
|
public int deviceMaxVolume = 25;
|
||||||
|
/**
|
||||||
|
* Max ADB command consecutive timeouts to force to reset the connection. (0 for disabled)
|
||||||
|
*/
|
||||||
|
public int maxADBTimeouts;
|
||||||
/**
|
/**
|
||||||
* Settings key for android versions where volume is gather using settings command (>=android 11).
|
* Settings key for android versions where volume is gather using settings command (>=android 11).
|
||||||
*/
|
*/
|
||||||
|
@ -13,14 +13,14 @@
|
|||||||
package org.openhab.binding.androiddebugbridge.internal;
|
package org.openhab.binding.androiddebugbridge.internal;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -56,8 +56,8 @@ import com.tananaev.adblib.AdbStream;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class AndroidDebugBridgeDevice {
|
public class AndroidDebugBridgeDevice {
|
||||||
|
private static final Path ADB_FOLDER = Path.of(OpenHAB.getUserDataFolder(), ".adb");
|
||||||
public static final int ANDROID_MEDIA_STREAM = 3;
|
public static final int ANDROID_MEDIA_STREAM = 3;
|
||||||
private static final String ADB_FOLDER = OpenHAB.getUserDataFolder() + File.separator + ".adb";
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(AndroidDebugBridgeDevice.class);
|
private final Logger logger = LoggerFactory.getLogger(AndroidDebugBridgeDevice.class);
|
||||||
private static final Pattern VOLUME_PATTERN = Pattern
|
private static final Pattern VOLUME_PATTERN = Pattern
|
||||||
.compile("volume is (?<current>\\d.*) in range \\[(?<min>\\d.*)\\.\\.(?<max>\\d.*)]");
|
.compile("volume is (?<current>\\d.*) in range \\[(?<min>\\d.*)\\.\\.(?<max>\\d.*)]");
|
||||||
@ -76,20 +76,6 @@ public class AndroidDebugBridgeDevice {
|
|||||||
|
|
||||||
private static @Nullable AdbCrypto adbCrypto;
|
private static @Nullable AdbCrypto adbCrypto;
|
||||||
|
|
||||||
static {
|
|
||||||
var logger = LoggerFactory.getLogger(AndroidDebugBridgeDevice.class);
|
|
||||||
try {
|
|
||||||
File directory = new File(ADB_FOLDER);
|
|
||||||
if (!directory.exists()) {
|
|
||||||
directory.mkdir();
|
|
||||||
}
|
|
||||||
adbCrypto = loadKeyPair(ADB_FOLDER + File.separator + "adb_pub.key",
|
|
||||||
ADB_FOLDER + File.separator + "adb.key");
|
|
||||||
} catch (NoSuchAlgorithmException | IOException | InvalidKeySpecException e) {
|
|
||||||
logger.warn("Unable to setup adb keys: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ScheduledExecutorService scheduler;
|
private final ScheduledExecutorService scheduler;
|
||||||
private final ReentrantLock commandLock = new ReentrantLock();
|
private final ReentrantLock commandLock = new ReentrantLock();
|
||||||
|
|
||||||
@ -793,20 +779,30 @@ public class AndroidDebugBridgeDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AdbBase64 getBase64Impl() {
|
public static void initADB() {
|
||||||
Charset asciiCharset = Charset.forName("ASCII");
|
Logger logger = LoggerFactory.getLogger(AndroidDebugBridgeDevice.class);
|
||||||
return bytes -> new String(Base64.getEncoder().encode(bytes), asciiCharset);
|
try {
|
||||||
|
if (!Files.exists(ADB_FOLDER) || !Files.isDirectory(ADB_FOLDER)) {
|
||||||
|
Files.createDirectory(ADB_FOLDER);
|
||||||
|
logger.info("Binding folder {} created", ADB_FOLDER);
|
||||||
|
}
|
||||||
|
adbCrypto = loadKeyPair(ADB_FOLDER.resolve("adb_pub.key"), ADB_FOLDER.resolve("adb.key"));
|
||||||
|
} catch (NoSuchAlgorithmException | IOException | InvalidKeySpecException e) {
|
||||||
|
logger.warn("Unable to setup adb keys: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AdbCrypto loadKeyPair(String pubKeyFile, String privKeyFile)
|
private static AdbBase64 getBase64Impl() {
|
||||||
|
return bytes -> new String(Base64.getEncoder().encode(bytes), StandardCharsets.US_ASCII);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AdbCrypto loadKeyPair(Path pubKey, Path privKey)
|
||||||
throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
|
throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
|
||||||
File pub = new File(pubKeyFile);
|
|
||||||
File priv = new File(privKeyFile);
|
|
||||||
AdbCrypto c = null;
|
AdbCrypto c = null;
|
||||||
// load key pair
|
// load key pair
|
||||||
if (pub.exists() && priv.exists()) {
|
if (Files.exists(pubKey) && Files.exists(privKey)) {
|
||||||
try {
|
try {
|
||||||
c = AdbCrypto.loadAdbKeyPair(getBase64Impl(), priv, pub);
|
c = AdbCrypto.loadAdbKeyPair(getBase64Impl(), privKey.toFile(), pubKey.toFile());
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
// Keys don't exits
|
// Keys don't exits
|
||||||
}
|
}
|
||||||
@ -814,7 +810,7 @@ public class AndroidDebugBridgeDevice {
|
|||||||
if (c == null) {
|
if (c == null) {
|
||||||
// generate key pair
|
// generate key pair
|
||||||
c = AdbCrypto.generateAdbKeyPair(getBase64Impl());
|
c = AdbCrypto.generateAdbKeyPair(getBase64Impl());
|
||||||
c.saveAdbKeyPair(priv, pub);
|
c.saveAdbKeyPair(privKey.toFile(), pubKey.toFile());
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import java.util.stream.Collectors;
|
|||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
import org.openhab.core.library.types.DecimalType;
|
||||||
|
import org.openhab.core.library.types.IncreaseDecreaseType;
|
||||||
import org.openhab.core.library.types.NextPreviousType;
|
import org.openhab.core.library.types.NextPreviousType;
|
||||||
import org.openhab.core.library.types.OnOffType;
|
import org.openhab.core.library.types.OnOffType;
|
||||||
import org.openhab.core.library.types.PercentType;
|
import org.openhab.core.library.types.PercentType;
|
||||||
@ -74,6 +75,7 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
private @Nullable ScheduledFuture<?> connectionCheckerSchedule;
|
private @Nullable ScheduledFuture<?> connectionCheckerSchedule;
|
||||||
private AndroidDebugBridgeMediaStatePackageConfig @Nullable [] packageConfigs = null;
|
private AndroidDebugBridgeMediaStatePackageConfig @Nullable [] packageConfigs = null;
|
||||||
private boolean deviceAwake = false;
|
private boolean deviceAwake = false;
|
||||||
|
private int consecutiveTimeouts = 0;
|
||||||
|
|
||||||
public AndroidDebugBridgeHandler(Thing thing,
|
public AndroidDebugBridgeHandler(Thing thing,
|
||||||
AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
|
AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
|
||||||
@ -101,6 +103,7 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
logger.warn("{} - read error: {}", currentConfig.ip, e.getMessage());
|
logger.warn("{} - read error: {}", currentConfig.ip, e.getMessage());
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
logger.warn("{} - timeout error", currentConfig.ip);
|
logger.warn("{} - timeout error", currentConfig.ip);
|
||||||
|
disconnectOnMaxADBTimeouts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +199,7 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
consecutiveTimeouts = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordDeviceInput(Command recordNameCommand)
|
private void recordDeviceInput(Command recordNameCommand)
|
||||||
@ -236,6 +240,16 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
var volumeInfo = adbConnection.getMediaVolume();
|
var volumeInfo = adbConnection.getMediaVolume();
|
||||||
maxMediaVolume = volumeInfo.max;
|
maxMediaVolume = volumeInfo.max;
|
||||||
updateState(channelUID, new PercentType((int) Math.round(toPercent(volumeInfo.current, volumeInfo.max))));
|
updateState(channelUID, new PercentType((int) Math.round(toPercent(volumeInfo.current, volumeInfo.max))));
|
||||||
|
} else if (command instanceof IncreaseDecreaseType) {
|
||||||
|
var volumeInfo = adbConnection.getMediaVolume();
|
||||||
|
var volumeStep = fromPercent(config.volumeStepPercent, volumeInfo.max);
|
||||||
|
logger.debug("Device {} volume step: {}", getThing().getUID(), volumeStep);
|
||||||
|
var targetVolume = (int) Math
|
||||||
|
.round(IncreaseDecreaseType.INCREASE.equals(command) ? volumeInfo.current + volumeStep
|
||||||
|
: volumeInfo.current - volumeStep);
|
||||||
|
var newVolume = Integer.max(0, Integer.min(targetVolume, volumeInfo.max));
|
||||||
|
logger.debug("Device {} new volume : {}", getThing().getUID(), newVolume);
|
||||||
|
adbConnection.setMediaVolume(newVolume);
|
||||||
} else {
|
} else {
|
||||||
if (maxMediaVolume == 0) {
|
if (maxMediaVolume == 0) {
|
||||||
return; // We can not transform percentage
|
return; // We can not transform percentage
|
||||||
@ -250,8 +264,8 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
return (value / maxValue) * 100;
|
return (value / maxValue) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double fromPercent(double value, double maxValue) {
|
private double fromPercent(double percent, double maxValue) {
|
||||||
return (value / 100) * maxValue;
|
return (percent / 100) * maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMediaControlCommand(ChannelUID channelUID, Command command)
|
private void handleMediaControlCommand(ChannelUID channelUID, Command command)
|
||||||
@ -398,8 +412,16 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
// Add some information about the device
|
// Add some information about the device
|
||||||
try {
|
try {
|
||||||
Map<String, String> editProperties = editProperties();
|
Map<String, String> editProperties = editProperties();
|
||||||
editProperties.put(Thing.PROPERTY_SERIAL_NUMBER, adbConnection.getSerialNo());
|
try {
|
||||||
editProperties.put(Thing.PROPERTY_MODEL_ID, adbConnection.getModel());
|
editProperties.put(Thing.PROPERTY_SERIAL_NUMBER, adbConnection.getSerialNo());
|
||||||
|
} catch (AndroidDebugBridgeDeviceReadException ignored) {
|
||||||
|
// Allow devices without serial number.
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
editProperties.put(Thing.PROPERTY_MODEL_ID, adbConnection.getModel());
|
||||||
|
} catch (AndroidDebugBridgeDeviceReadException ignored) {
|
||||||
|
// Allow devices without model id.
|
||||||
|
}
|
||||||
var androidVersion = adbConnection.getAndroidVersion();
|
var androidVersion = adbConnection.getAndroidVersion();
|
||||||
editProperties.put(Thing.PROPERTY_FIRMWARE_VERSION, androidVersion);
|
editProperties.put(Thing.PROPERTY_FIRMWARE_VERSION, androidVersion);
|
||||||
// refresh android version to use
|
// refresh android version to use
|
||||||
@ -426,8 +448,10 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
// happen a lot when device is sleeping; abort refresh other channels
|
// happen a lot when device is sleeping; abort refresh other channels
|
||||||
logger.debug("Unable to refresh awake state: Timeout; aborting channels refresh");
|
logger.debug("Unable to refresh awake state: Timeout; aborting channels refresh");
|
||||||
|
disconnectOnMaxADBTimeouts();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
consecutiveTimeouts = 0;
|
||||||
var awakeStateChannelUID = new ChannelUID(this.thing.getUID(), AWAKE_STATE_CHANNEL);
|
var awakeStateChannelUID = new ChannelUID(this.thing.getUID(), AWAKE_STATE_CHANNEL);
|
||||||
if (isLinked(awakeStateChannelUID)) {
|
if (isLinked(awakeStateChannelUID)) {
|
||||||
updateState(awakeStateChannelUID, OnOffType.from(awakeState));
|
updateState(awakeStateChannelUID, OnOffType.from(awakeState));
|
||||||
@ -474,6 +498,16 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void disconnectOnMaxADBTimeouts() {
|
||||||
|
consecutiveTimeouts++;
|
||||||
|
if (config.maxADBTimeouts > 0 && consecutiveTimeouts >= config.maxADBTimeouts) {
|
||||||
|
logger.debug("Max consecutive timeouts reached, aborting connection");
|
||||||
|
adbConnection.disconnect();
|
||||||
|
checkConnection();
|
||||||
|
consecutiveTimeouts = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class AndroidDebugBridgeMediaStatePackageConfig {
|
static class AndroidDebugBridgeMediaStatePackageConfig {
|
||||||
public String name = "";
|
public String name = "";
|
||||||
public @Nullable String label;
|
public @Nullable String label;
|
||||||
|
@ -41,6 +41,7 @@ public class AndroidDebugBridgeHandlerFactory extends BaseThingHandlerFactory {
|
|||||||
public AndroidDebugBridgeHandlerFactory(
|
public AndroidDebugBridgeHandlerFactory(
|
||||||
final @Reference AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
|
final @Reference AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
|
||||||
this.commandDescriptionProvider = commandDescriptionProvider;
|
this.commandDescriptionProvider = commandDescriptionProvider;
|
||||||
|
AndroidDebugBridgeDevice.initADB();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,6 +25,8 @@ thing-type.config.androiddebugbridge.android.deviceMaxVolume.label = Device Max
|
|||||||
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.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.label = IP Address
|
||||||
thing-type.config.androiddebugbridge.android.ip.description = Device ip address.
|
thing-type.config.androiddebugbridge.android.ip.description = Device ip address.
|
||||||
|
thing-type.config.androiddebugbridge.android.maxADBTimeouts.label = Max ADB Timeouts
|
||||||
|
thing-type.config.androiddebugbridge.android.maxADBTimeouts.description = Max ADB command consecutive timeouts to force to reset the connection. (0 for disabled)
|
||||||
thing-type.config.androiddebugbridge.android.mediaStateJSONConfig.label = Media State Config
|
thing-type.config.androiddebugbridge.android.mediaStateJSONConfig.label = Media State Config
|
||||||
thing-type.config.androiddebugbridge.android.mediaStateJSONConfig.description = JSON config that allows to modify the media state detection strategy for each app. Refer to the binding documentation.
|
thing-type.config.androiddebugbridge.android.mediaStateJSONConfig.description = JSON config that allows to modify the media state detection strategy for each app. Refer to the binding documentation.
|
||||||
thing-type.config.androiddebugbridge.android.port.label = Port
|
thing-type.config.androiddebugbridge.android.port.label = Port
|
||||||
@ -45,6 +47,8 @@ thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_musi
|
|||||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_music_headset = volume music headset
|
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_music_usb_headset = volume music usb headset
|
||||||
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_system = volume system
|
thing-type.config.androiddebugbridge.android.volumeSettingKey.option.volume_system = volume system
|
||||||
|
thing-type.config.androiddebugbridge.android.volumeStepPercent.label = Volume Step Percent
|
||||||
|
thing-type.config.androiddebugbridge.android.volumeStepPercent.description = Percent to increase/decrease volume.
|
||||||
|
|
||||||
# channel types
|
# channel types
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
<description>Device port listening to adb connections.</description>
|
<description>Device port listening to adb connections.</description>
|
||||||
<default>5555</default>
|
<default>5555</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="refreshTime" type="integer" min="10" max="120" unit="s" required="true">
|
<parameter name="refreshTime" type="integer" min="5" max="120" unit="s" required="true">
|
||||||
<label>Refresh Time</label>
|
<label>Refresh Time</label>
|
||||||
<description>Seconds between device status refreshes.</description>
|
<description>Seconds between device status refreshes.</description>
|
||||||
<default>30</default>
|
<default>30</default>
|
||||||
@ -75,12 +75,24 @@
|
|||||||
</options>
|
</options>
|
||||||
<advanced>true</advanced>
|
<advanced>true</advanced>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
<parameter name="volumeStepPercent" type="integer" min="1" max="100">
|
||||||
|
<label>Volume Step Percent</label>
|
||||||
|
<description>Percent to increase/decrease volume.</description>
|
||||||
|
<default>15</default>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
</parameter>
|
||||||
<parameter name="deviceMaxVolume" type="integer" min="1" max="100">
|
<parameter name="deviceMaxVolume" type="integer" min="1" max="100">
|
||||||
<label>Device Max Volume</label>
|
<label>Device Max Volume</label>
|
||||||
<description>Assumed max volume for devices with android versions that do not expose this value (>=android 11).</description>
|
<description>Assumed max volume for devices with android versions that do not expose this value (>=android 11).</description>
|
||||||
<default>25</default>
|
<default>25</default>
|
||||||
<advanced>true</advanced>
|
<advanced>true</advanced>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
<parameter name="maxADBTimeouts" type="integer" min="0">
|
||||||
|
<label>Max ADB Timeouts</label>
|
||||||
|
<description>Max ADB command consecutive timeouts to force to reset the connection. (0 for disabled)</description>
|
||||||
|
<default>0</default>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
</parameter>
|
||||||
</config-description>
|
</config-description>
|
||||||
</thing-type>
|
</thing-type>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user