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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user