diff options
author | Jinsuk Kim <jinsukkim@google.com> | 2014-09-12 13:51:10 +0900 |
---|---|---|
committer | Jinsuk Kim <jinsukkim@google.com> | 2014-09-12 16:22:23 +0900 |
commit | d4a94db1cd44a536d535de890a0a14919a39a0dc (patch) | |
tree | 37981d342326d4137b3efbb163cd7ed7d071058a | |
parent | 753fcc8a8a25b2a8625957b2edcad0af77dfd5e5 (diff) | |
download | frameworks_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
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; } } |