summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java4
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java29
-rw-r--r--services/core/java/com/android/server/hdmi/VendorSpecificAction.java54
3 files changed, 86 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 6697a5315390..7a08f99f70a1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -139,6 +139,10 @@ abstract class HdmiCecLocalDevice {
return true;
}
+ protected boolean handleVendorSpecificCommand(HdmiCecMessage message) {
+ return false;
+ }
+
final void handleAddressAllocated(int logicalAddress) {
mAddress = mPreferredAddress = logicalAddress;
onAddressAllocated(logicalAddress);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 6394fe722f47..aa1769e4e389 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -23,6 +23,8 @@ import android.hardware.hdmi.HdmiCecMessage;
import android.os.RemoteException;
import android.util.Slog;
+import java.util.Collections;
+import java.util.List;
import java.util.Locale;
/**
@@ -72,7 +74,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
mService.removeAction(DeviceSelectAction.class);
mService.addAndStartAction(new DeviceSelectAction(mService, mAddress,
- mService.getPhysicalAddress(), targetDevice, callback));
+ mService.getPhysicalAddress(), targetDevice, callback));
}
private static void invokeCallback(IHdmiControlCallback callback, int result) {
@@ -110,4 +112,29 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return true;
}
+
+ @Override
+ protected boolean handleVendorSpecificCommand(HdmiCecMessage message) {
+ List<VendorSpecificAction> actions = Collections.emptyList();
+ // TODO: Call mService.getActions(VendorSpecificAction.class) to get all the actions.
+
+ // We assume that there can be multiple vendor-specific command actions running
+ // at the same time. Pass the message to each action to see if one of them needs it.
+ for (VendorSpecificAction action : actions) {
+ if (action.processCommand(message)) {
+ return true;
+ }
+ }
+ // Handle the message here if it is not already consumed by one of the running actions.
+ // Respond with a appropriate vendor-specific command or <Feature Abort>, or create another
+ // vendor-specific action:
+ //
+ // mService.addAndStartAction(new VendorSpecificAction(mService, mAddress));
+ //
+ // For now, simply reply with <Feature Abort> and mark it consumed by returning true.
+ mService.sendCecCommand(HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ message.getDestination(), message.getSource(), message.getOpcode(),
+ HdmiConstants.ABORT_REFUSED));
+ return true;
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/VendorSpecificAction.java b/services/core/java/com/android/server/hdmi/VendorSpecificAction.java
new file mode 100644
index 000000000000..9d457020fecc
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/VendorSpecificAction.java
@@ -0,0 +1,54 @@
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCecMessage;
+
+/**
+ * Handles vendor-specific commands that require a sequence of command exchange,
+ * or need to manage some states to complete the processing.
+ */
+public class VendorSpecificAction extends FeatureAction {
+
+ // Sample state this action can be in.
+ private static final int STATE_1 = 1;
+ private static final int STATE_2 = 2;
+
+ VendorSpecificAction(HdmiControlService service, int sourceAddress) {
+ super(service, sourceAddress);
+ // Modify the constructor if additional arguments are necessary.
+ }
+
+ @Override
+ boolean start() {
+ // Do initialization step and update the state accordingly here.
+ mState = STATE_1;
+ addTimer(STATE_1, TIMEOUT_MS);
+ return true;
+ }
+
+ @Override
+ boolean processCommand(HdmiCecMessage cmd) {
+ // Returns true if the command was consumed. Otherwise return false for other
+ // actions in progress can be given its turn to process it.
+ return false;
+ }
+
+ @Override
+ void handleTimerEvent(int state) {
+ // Ignore the timer event if the current state and the state this event should be
+ // handled in are different. Could be an outdated event which should have been cleared by
+ // calling {@code mActionTimer.clearTimerMessage()}.
+ if (mState != state) {
+ return;
+ }
+
+ switch (state) {
+ case STATE_1:
+ mState = STATE_2;
+ addTimer(STATE_2, TIMEOUT_MS);
+ break;
+ case STATE_2:
+ finish();
+ break;
+ }
+ }
+}