am f1702487: CEC: make it sure to send vendor commands when changing a setting.
* commit 'f17024873b10dabed069e502030dd85d6257c0c4':
CEC: make it sure to send vendor commands when changing a setting.
diff --git a/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl b/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl
index a16e878..c708d20 100644
--- a/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl
@@ -22,7 +22,7 @@
*
* @hide
*/
-oneway interface IHdmiVendorCommandListener {
+interface IHdmiVendorCommandListener {
void onReceived(int logicalAddress, int destAddress, in byte[] operands, boolean hasVendorId);
void onControlStateChanged(boolean enabled, int reason);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 0e8788a..1486fee 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -129,7 +129,7 @@
}
private void init(long nativePtr) {
- mIoHandler = new Handler(mService.getServiceLooper());
+ mIoHandler = new Handler(mService.getIoLooper());
mControlHandler = new Handler(mService.getServiceLooper());
mNativePtr = nativePtr;
}
@@ -324,6 +324,7 @@
@ServiceThreadOnly
void setOption(int flag, int value) {
assertRunOnServiceThread();
+ HdmiLogger.debug("setOption: [flag:%d, value:%d]", flag, value);
nativeSetOption(mNativePtr, flag, value);
}
@@ -501,6 +502,19 @@
mControlHandler.post(runnable);
}
+ @ServiceThreadOnly
+ void flush(final Runnable runnable) {
+ assertRunOnServiceThread();
+ runOnIoThread(new Runnable() {
+ @Override
+ public void run() {
+ // This ensures the runnable for cleanup is performed after all the pending
+ // commands are processed by IO thread.
+ runOnServiceThread(runnable);
+ }
+ });
+ }
+
private boolean isAcceptableAddress(int address) {
// Can access command targeting devices available in local device or broadcast command.
if (address == Constants.ADDR_BROADCAST) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 8a25f62..5f8b389 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -2021,30 +2021,52 @@
void setControlEnabled(boolean enabled) {
assertRunOnServiceThread();
- if (!enabled) {
- // Call the vendor handler before the service is disabled.
- invokeVendorCommandListenersOnControlStateChanged(false,
- HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
- }
- int value = toInt(enabled);
- mCecController.setOption(OPTION_CEC_ENABLE, value);
- mMhlController.setOption(OPTION_MHL_ENABLE, value);
-
synchronized (mLock) {
mHdmiControlEnabled = enabled;
}
if (enabled) {
- initializeCec(INITIATED_BY_ENABLE_CEC);
- } else {
- disableDevices(new PendingActionClearedCallback() {
- @Override
- public void onCleared(HdmiCecLocalDevice device) {
- assertRunOnServiceThread();
- clearLocalDevices();
- }
- });
+ enableHdmiControlService();
+ return;
}
+ // Call the vendor handler before the service is disabled.
+ invokeVendorCommandListenersOnControlStateChanged(false,
+ HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
+ // Post the remained tasks in the service thread again to give the vendor-issued-tasks
+ // a chance to run.
+ runOnServiceThread(new Runnable() {
+ @Override
+ public void run() {
+ disableHdmiControlService();
+ }
+ });
+ return;
+ }
+
+ @ServiceThreadOnly
+ private void enableHdmiControlService() {
+ mCecController.setOption(OPTION_CEC_ENABLE, ENABLED);
+ mMhlController.setOption(OPTION_MHL_ENABLE, ENABLED);
+
+ initializeCec(INITIATED_BY_ENABLE_CEC);
+ }
+
+ @ServiceThreadOnly
+ private void disableHdmiControlService() {
+ disableDevices(new PendingActionClearedCallback() {
+ @Override
+ public void onCleared(HdmiCecLocalDevice device) {
+ assertRunOnServiceThread();
+ mCecController.flush(new Runnable() {
+ @Override
+ public void run() {
+ mCecController.setOption(OPTION_CEC_ENABLE, DISABLED);
+ mMhlController.setOption(OPTION_MHL_ENABLE, DISABLED);
+ clearLocalDevices();
+ }
+ });
+ }
+ });
}
@ServiceThreadOnly