[androiddebugbridge] Added DynamicCommandOptionsProvider to populate 'start-package' Channel (#12491)
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
committed by
GitHub
parent
e9cb9c30d0
commit
5a9e70ca6a
@@ -63,9 +63,9 @@ The available modes are:
|
|||||||
|
|
||||||
The configuration depends on the application, device and version used.
|
The configuration depends on the application, device and version used.
|
||||||
|
|
||||||
This is a sample of the mediaStateJSONConfig thing configuration:
|
This is a sample of the mediaStateJSONConfig thing configuration - the `label` is optional:
|
||||||
|
|
||||||
`[{"name": "com.amazon.tv.launcher", "mode": "idle"},{"name": "org.jellyfin.androidtv", "mode": "wake_lock", "wakeLockPlayStates": [2,3]},{"name": "com.amazon.firetv.youtube", "mode": "wake_lock", "wakeLockPlayStates": [2]}]`
|
`[{"name": "com.amazon.tv.launcher", "mode": "idle"}, {"name": "org.jellyfin.androidtv", "mode": "wake_lock", "wakeLockPlayStates": [2,3]}, {"name": "com.amazon.firetv.youtube", "label":"YouTube", "mode": "wake_lock", "wakeLockPlayStates": [2]}]`
|
||||||
|
|
||||||
## Record/Send input events
|
## Record/Send input events
|
||||||
|
|
||||||
@@ -80,18 +80,17 @@ An example of what you can do:
|
|||||||
|
|
||||||
Please note that events could fail if the input method is removed, for example it could fail if you clone the events of a bluetooth controller and the remote goes offline. This is happening for me when recording the Fire TV remote events but not for my Xiaomi TV which also has a bt remote controller.
|
Please note that events could fail if the input method is removed, for example it could fail if you clone the events of a bluetooth controller and the remote goes offline. This is happening for me when recording the Fire TV remote events but not for my Xiaomi TV which also has a bt remote controller.
|
||||||
|
|
||||||
|
|
||||||
## Channels
|
## Channels
|
||||||
|
|
||||||
| channel | type | description |
|
| channel | type | description |
|
||||||
|----------|--------|------------------------------|
|
|----------------------|--------|-------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| key-event | String | Send key event to android device. Possible values listed below |
|
| key-event | String | Send key event to android device. Possible values listed below |
|
||||||
| text | String | Send text to android device |
|
| text | String | Send text to android device |
|
||||||
| tap | String | Send tap event to android device (format x,y) |
|
| tap | String | Send tap event to android device (format x,y) |
|
||||||
| url | String | Open url in browser |
|
| url | String | Open url in browser |
|
||||||
| media-volume | Dimmer | Set or get media volume level on android device |
|
| media-volume | Dimmer | Set or get media volume level on android device |
|
||||||
| media-control | Player | Control media on android device |
|
| media-control | Player | Control media on android device |
|
||||||
| start-package | String | Run application by package name |
|
| start-package | String | Run application by package name. The commands for this Channel are populated dynamically based on the `mediaStateJSONConfig`. |
|
||||||
| stop-package | String | Stop application by package name |
|
| stop-package | String | Stop application by package name |
|
||||||
| stop-current-package | String | Stop current application |
|
| stop-current-package | String | Stop current application |
|
||||||
| current-package | String | Package name of the top application in screen |
|
| current-package | String | Package name of the top application in screen |
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.androiddebugbridge.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.events.EventPublisher;
|
||||||
|
import org.openhab.core.thing.binding.BaseDynamicCommandDescriptionProvider;
|
||||||
|
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
|
||||||
|
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
|
||||||
|
import org.openhab.core.thing.type.DynamicCommandDescriptionProvider;
|
||||||
|
import org.osgi.service.component.annotations.Activate;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamic provider of command options.
|
||||||
|
*
|
||||||
|
* @author Christoph Weitkamp - Initial contribution
|
||||||
|
*/
|
||||||
|
@Component(service = { DynamicCommandDescriptionProvider.class,
|
||||||
|
AndroidDebugBridgeDynamicCommandDescriptionProvider.class })
|
||||||
|
@NonNullByDefault
|
||||||
|
public class AndroidDebugBridgeDynamicCommandDescriptionProvider extends BaseDynamicCommandDescriptionProvider {
|
||||||
|
@Activate
|
||||||
|
public AndroidDebugBridgeDynamicCommandDescriptionProvider(final @Reference EventPublisher eventPublisher, //
|
||||||
|
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, //
|
||||||
|
final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
|
||||||
|
this.eventPublisher = eventPublisher;
|
||||||
|
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||||
|
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import java.util.concurrent.ScheduledFuture;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
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;
|
||||||
@@ -38,6 +39,7 @@ import org.openhab.core.thing.ThingStatus;
|
|||||||
import org.openhab.core.thing.ThingStatusDetail;
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.CommandOption;
|
||||||
import org.openhab.core.types.RefreshType;
|
import org.openhab.core.types.RefreshType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -65,6 +67,8 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
private static final Gson GSON = new Gson();
|
private static final Gson GSON = new Gson();
|
||||||
private static final Pattern RECORD_NAME_PATTERN = Pattern.compile("^[A-Za-z0-9_]*$");
|
private static final Pattern RECORD_NAME_PATTERN = Pattern.compile("^[A-Za-z0-9_]*$");
|
||||||
private final Logger logger = LoggerFactory.getLogger(AndroidDebugBridgeHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(AndroidDebugBridgeHandler.class);
|
||||||
|
|
||||||
|
private final AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider;
|
||||||
private final AndroidDebugBridgeDevice adbConnection;
|
private final AndroidDebugBridgeDevice adbConnection;
|
||||||
private int maxMediaVolume = 0;
|
private int maxMediaVolume = 0;
|
||||||
private AndroidDebugBridgeConfiguration config = new AndroidDebugBridgeConfiguration();
|
private AndroidDebugBridgeConfiguration config = new AndroidDebugBridgeConfiguration();
|
||||||
@@ -72,8 +76,10 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
private AndroidDebugBridgeMediaStatePackageConfig @Nullable [] packageConfigs = null;
|
private AndroidDebugBridgeMediaStatePackageConfig @Nullable [] packageConfigs = null;
|
||||||
private boolean deviceAwake = false;
|
private boolean deviceAwake = false;
|
||||||
|
|
||||||
public AndroidDebugBridgeHandler(Thing thing) {
|
public AndroidDebugBridgeHandler(Thing thing,
|
||||||
|
AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
|
||||||
super(thing);
|
super(thing);
|
||||||
|
this.commandDescriptionProvider = commandDescriptionProvider;
|
||||||
this.adbConnection = new AndroidDebugBridgeDevice(scheduler);
|
this.adbConnection = new AndroidDebugBridgeDevice(scheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,12 +323,18 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadMediaStateConfig(String mediaStateJSONConfig) {
|
private void loadMediaStateConfig(String mediaStateJSONConfig) {
|
||||||
|
List<CommandOption> commandOptions;
|
||||||
try {
|
try {
|
||||||
this.packageConfigs = GSON.fromJson(mediaStateJSONConfig,
|
packageConfigs = GSON.fromJson(mediaStateJSONConfig, AndroidDebugBridgeMediaStatePackageConfig[].class);
|
||||||
AndroidDebugBridgeMediaStatePackageConfig[].class);
|
commandOptions = Arrays.stream(packageConfigs)
|
||||||
|
.map(AndroidDebugBridgeMediaStatePackageConfig::toCommandOption)
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
} catch (JsonSyntaxException e) {
|
} catch (JsonSyntaxException e) {
|
||||||
logger.warn("unable to parse media state config: {}", e.getMessage());
|
logger.warn("unable to parse media state config: {}", e.getMessage());
|
||||||
|
commandOptions = List.of();
|
||||||
}
|
}
|
||||||
|
commandDescriptionProvider.setCommandOptions(new ChannelUID(getThing().getUID(), START_PACKAGE_CHANNEL),
|
||||||
|
commandOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -449,7 +461,12 @@ public class AndroidDebugBridgeHandler extends BaseThingHandler {
|
|||||||
|
|
||||||
static class AndroidDebugBridgeMediaStatePackageConfig {
|
static class AndroidDebugBridgeMediaStatePackageConfig {
|
||||||
public String name = "";
|
public String name = "";
|
||||||
|
public @Nullable String label;
|
||||||
public String mode = "";
|
public String mode = "";
|
||||||
public List<Integer> wakeLockPlayStates = List.of();
|
public List<Integer> wakeLockPlayStates = List.of();
|
||||||
|
|
||||||
|
public CommandOption toCommandOption() {
|
||||||
|
return new CommandOption(name, label == null ? name : label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ import org.openhab.core.thing.ThingTypeUID;
|
|||||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||||
import org.openhab.core.thing.binding.ThingHandler;
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||||
|
import org.osgi.service.component.annotations.Activate;
|
||||||
import org.osgi.service.component.annotations.Component;
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link AndroidDebugBridgeHandlerFactory} is responsible for creating things and thing
|
* The {@link AndroidDebugBridgeHandlerFactory} is responsible for creating things and thing
|
||||||
@@ -33,6 +35,14 @@ import org.osgi.service.component.annotations.Component;
|
|||||||
@Component(configurationPid = BINDING_CONFIGURATION_PID, service = ThingHandlerFactory.class)
|
@Component(configurationPid = BINDING_CONFIGURATION_PID, service = ThingHandlerFactory.class)
|
||||||
public class AndroidDebugBridgeHandlerFactory extends BaseThingHandlerFactory {
|
public class AndroidDebugBridgeHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
|
private final AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider;
|
||||||
|
|
||||||
|
@Activate
|
||||||
|
public AndroidDebugBridgeHandlerFactory(
|
||||||
|
final @Reference AndroidDebugBridgeDynamicCommandDescriptionProvider commandDescriptionProvider) {
|
||||||
|
this.commandDescriptionProvider = commandDescriptionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||||
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
|
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
|
||||||
@@ -42,7 +52,7 @@ public class AndroidDebugBridgeHandlerFactory extends BaseThingHandlerFactory {
|
|||||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
if (THING_TYPE_ANDROID_DEVICE.equals(thingTypeUID)) {
|
if (THING_TYPE_ANDROID_DEVICE.equals(thingTypeUID)) {
|
||||||
return new AndroidDebugBridgeHandler(thing);
|
return new AndroidDebugBridgeHandler(thing, commandDescriptionProvider);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user