am 964c00dd: CEC: Buffer Cec messages while allocating logical address

* commit '964c00dd7b270dcf80aea3450bbfc23502965cce':
  CEC: Buffer Cec messages while allocating logical address
This commit is contained in:
Jinsuk Kim
2015-01-16 08:17:07 +00:00
committed by Android Git Automerger
2 changed files with 93 additions and 10 deletions

View File

@@ -77,11 +77,13 @@ final class DelayedMessageBuffer {
}
void processAllMessages() {
for (HdmiCecMessage message : mBuffer) {
// Use the copied buffer.
ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<HdmiCecMessage>(mBuffer);
mBuffer.clear();
for (HdmiCecMessage message : copiedBuffer) {
mDevice.onMessage(message);
HdmiLogger.debug("Processing message:" + message);
}
mBuffer.clear();
}
/**
@@ -95,15 +97,21 @@ final class DelayedMessageBuffer {
* are associated with
*/
void processMessagesForDevice(int address) {
ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<HdmiCecMessage>(mBuffer);
mBuffer.clear();
HdmiLogger.debug("Checking message for address:" + address);
for (Iterator<HdmiCecMessage> iter = mBuffer.iterator(); iter.hasNext(); ) {
HdmiCecMessage message = iter.next();
if (message.getSource() != address) continue;
for (HdmiCecMessage message : copiedBuffer) {
if (message.getSource() != address) {
mBuffer.add(message);
continue;
}
if (message.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE
&& !mDevice.isInputReady(HdmiDeviceInfo.idForCecDevice(address))) continue;
&& !mDevice.isInputReady(HdmiDeviceInfo.idForCecDevice(address))) {
mBuffer.add(message);
continue;
}
mDevice.onMessage(message);
HdmiLogger.debug("Processing message:" + message);
iter.remove();
}
}
@@ -119,13 +127,15 @@ final class DelayedMessageBuffer {
* @param address logical address of the device to be the active source
*/
void processActiveSource(int address) {
for (Iterator<HdmiCecMessage> iter = mBuffer.iterator(); iter.hasNext(); ) {
HdmiCecMessage message = iter.next();
ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<HdmiCecMessage>(mBuffer);
mBuffer.clear();
for (HdmiCecMessage message : copiedBuffer) {
if (message.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE
&& message.getSource() == address) {
mDevice.onMessage(message);
HdmiLogger.debug("Processing message:" + message);
iter.remove();
} else {
mBuffer.add(message);
}
}
}

View File

@@ -286,6 +286,69 @@ public final class HdmiControlService extends SystemService {
@ServiceThreadOnly
private int mLastInputMhl = Constants.INVALID_PORT_ID;
// Set to true if the logical address allocation is completed.
private boolean mAddressAllocated = false;
// Buffer for processing the incoming cec messages while allocating logical addresses.
private final class CecMessageBuffer {
private List<HdmiCecMessage> mBuffer = new ArrayList<>();
public void bufferMessage(HdmiCecMessage message) {
switch (message.getOpcode()) {
case Constants.MESSAGE_ACTIVE_SOURCE:
bufferActiveSource(message);
break;
case Constants.MESSAGE_IMAGE_VIEW_ON:
case Constants.MESSAGE_TEXT_VIEW_ON:
bufferImageOrTextViewOn(message);
break;
// Add here if new message that needs to buffer
default:
// Do not need to buffer messages other than above
break;
}
}
public void processMessages() {
for (final HdmiCecMessage message : mBuffer) {
runOnServiceThread(new Runnable() {
@Override
public void run() {
handleCecCommand(message);
}
});
}
mBuffer.clear();
}
private void bufferActiveSource(HdmiCecMessage message) {
if (!replaceMessageIfBuffered(message, Constants.MESSAGE_ACTIVE_SOURCE)) {
mBuffer.add(message);
}
}
private void bufferImageOrTextViewOn(HdmiCecMessage message) {
if (!replaceMessageIfBuffered(message, Constants.MESSAGE_IMAGE_VIEW_ON) &&
!replaceMessageIfBuffered(message, Constants.MESSAGE_TEXT_VIEW_ON)) {
mBuffer.add(message);
}
}
// Returns true if the message is replaced
private boolean replaceMessageIfBuffered(HdmiCecMessage message, int opcode) {
for (int i = 0; i < mBuffer.size(); i++) {
HdmiCecMessage bufferedMessage = mBuffer.get(i);
if (bufferedMessage.getOpcode() == opcode) {
mBuffer.set(i, message);
return true;
}
}
return false;
}
}
private CecMessageBuffer mCecMessageBuffer = new CecMessageBuffer();
public HdmiControlService(Context context) {
super(context);
mLocalDevices = getIntList(SystemProperties.get(Constants.PROPERTY_DEVICE_TYPE));
@@ -474,6 +537,7 @@ public final class HdmiControlService extends SystemService {
}
private void initializeCec(int initiatedBy) {
mAddressAllocated = false;
mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, ENABLED);
initializeLocalDevices(initiatedBy);
}
@@ -504,6 +568,8 @@ public final class HdmiControlService extends SystemService {
mCecController.clearLogicalAddress();
final ArrayList<HdmiCecLocalDevice> allocatedDevices = new ArrayList<>();
final int[] finished = new int[1];
mAddressAllocated = allocatingDevices.isEmpty();
for (final HdmiCecLocalDevice localDevice : allocatingDevices) {
mCecController.allocateLogicalAddress(localDevice.getType(),
localDevice.getPreferredAddress(), new AllocateAddressCallback() {
@@ -524,12 +590,14 @@ public final class HdmiControlService extends SystemService {
// Address allocation completed for all devices. Notify each device.
if (allocatingDevices.size() == ++finished[0]) {
mAddressAllocated = true;
if (initiatedBy != INITIATED_BY_HOTPLUG) {
// In case of the hotplug we don't call onInitializeCecComplete()
// since we reallocate the logical address only.
onInitializeCecComplete(initiatedBy);
}
notifyAddressAllocated(allocatedDevices, initiatedBy);
mCecMessageBuffer.processMessages();
}
}
});
@@ -762,6 +830,10 @@ public final class HdmiControlService extends SystemService {
@ServiceThreadOnly
boolean handleCecCommand(HdmiCecMessage message) {
assertRunOnServiceThread();
if (!mAddressAllocated) {
mCecMessageBuffer.bufferMessage(message);
return true;
}
int errorCode = mMessageValidator.isValid(message);
if (errorCode != HdmiCecMessageValidator.OK) {
// We'll not response on the messages with the invalid source or destination
@@ -1990,6 +2062,7 @@ public final class HdmiControlService extends SystemService {
device.onStandby(mStandbyMessageReceived);
}
mStandbyMessageReceived = false;
mAddressAllocated = false;
mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, DISABLED);
}