summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJinsuk Kim <jinsukkim@google.com>2014-09-12 13:51:10 +0900
committerJinsuk Kim <jinsukkim@google.com>2014-09-12 16:22:23 +0900
commitd4a94db1cd44a536d535de890a0a14919a39a0dc (patch)
tree37981d342326d4137b3efbb163cd7ed7d071058a
parent753fcc8a8a25b2a8625957b2edcad0af77dfd5e5 (diff)
downloadframeworks_base-d4a94db1cd44a536d535de890a0a14919a39a0dc.zip
frameworks_base-d4a94db1cd44a536d535de890a0a14919a39a0dc.tar.gz
frameworks_base-d4a94db1cd44a536d535de890a0a14919a39a0dc.tar.bz2
CEC: Bug fixes for vendor-specific command handling
- Add sendStandby() - Respond with <Feature Abort>[INCORRECT_MODE] when the listener is not ready Bug: 17379243 Bug: 17358887 Change-Id: I26a4157a70f11206978763fbbe69e4190e3e1d5c
-rw-r--r--core/java/android/hardware/hdmi/IHdmiControlService.aidl1
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java17
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java10
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java22
4 files changed, 46 insertions, 4 deletions
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index 602f866..4866a9a 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -62,6 +62,7 @@ interface IHdmiControlService {
void sendVendorCommand(int deviceType, int targetAddress, in byte[] params,
boolean hasVendorId);
void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType);
+ void sendStandby(int deviceType, int deviceId);
void setHdmiRecordListener(IHdmiRecordListener callback);
void startOneTouchRecord(int recorderAddress, in byte[] recordSource);
void stopOneTouchRecord(int recorderAddress);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 2f36181..41ac589 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -517,8 +517,12 @@ abstract class HdmiCecLocalDevice {
}
protected boolean handleVendorCommand(HdmiCecMessage message) {
- mService.invokeVendorCommandListeners(mDeviceType, message.getSource(),
- message.getParams(), false);
+ if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(),
+ message.getParams(), false)) {
+ // Vendor command listener may not have been registered yet. Respond with
+ // <Feature Abort> [NOT_IN_CORRECT_MODE] so that the sender can try again later.
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+ }
return true;
}
@@ -526,7 +530,10 @@ abstract class HdmiCecLocalDevice {
byte[] params = message.getParams();
int vendorId = HdmiUtils.threeBytesToInt(params);
if (vendorId == mService.getVendorId()) {
- mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params, true);
+ if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params,
+ true)) {
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+ }
} else if (message.getDestination() != Constants.ADDR_BROADCAST &&
message.getSource() != Constants.ADDR_UNREGISTERED) {
Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>");
@@ -537,6 +544,10 @@ abstract class HdmiCecLocalDevice {
return true;
}
+ protected void sendStandby(int deviceId) {
+ // Do nothing.
+ }
+
protected boolean handleSetOsdName(HdmiCecMessage message) {
// The default behavior of <Set Osd Name> is doing nothing.
return true;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index c9b7b45..9033c38 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1652,6 +1652,16 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
@Override
+ protected void sendStandby(int deviceId) {
+ HdmiDeviceInfo targetDevice = mDeviceInfos.get(deviceId);
+ if (targetDevice == null) {
+ return;
+ }
+ int targetAddress = targetDevice.getLogicalAddress();
+ mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(mAddress, targetAddress));
+ }
+
+ @Override
protected void dump(final IndentingPrintWriter pw) {
super.dump(pw);
pw.println("mArcEstablished: " + mArcEstablished);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 55eb180..9a4000c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1345,6 +1345,22 @@ public final class HdmiControlService extends SystemService {
}
@Override
+ public void sendStandby(final int deviceType, final int deviceId) {
+ enforceAccessPermission();
+ runOnServiceThread(new Runnable() {
+ @Override
+ public void run() {
+ HdmiCecLocalDevice device = mCecController.getLocalDevice(deviceType);
+ if (device == null) {
+ Slog.w(TAG, "Local device not available");
+ return;
+ }
+ device.sendStandby(deviceId);
+ }
+ });
+ }
+
+ @Override
public void setHdmiRecordListener(IHdmiRecordListener listener) {
HdmiControlService.this.setHdmiRecordListener(listener);
}
@@ -1869,9 +1885,12 @@ public final class HdmiControlService extends SystemService {
}
}
- void invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params,
+ boolean invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params,
boolean hasVendorId) {
synchronized (mLock) {
+ if (mVendorCommandListenerRecords.isEmpty()) {
+ return false;
+ }
for (VendorCommandListenerRecord record : mVendorCommandListenerRecords) {
if (record.mDeviceType != deviceType) {
continue;
@@ -1882,6 +1901,7 @@ public final class HdmiControlService extends SystemService {
Slog.e(TAG, "Failed to notify vendor command reception", e);
}
}
+ return true;
}
}