CEC: Dump recent message history for better logging
Logging for CEC messages is disabled by default, so it is hard to debug using bug report. Providing recent history of cec messages would be helpful to see what happened via CEC line. Bug: 33682018 Test: adb shell dumpsys hdmi_control Change-Id: I476ce454418d6da8d65f520cc79d653bf96f3afd
This commit is contained in:
@@ -29,9 +29,12 @@ import com.android.internal.util.Predicate;
|
||||
import com.android.server.hdmi.HdmiAnnotations.IoThreadOnly;
|
||||
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
|
||||
import com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import libcore.util.EmptyArray;
|
||||
import sun.util.locale.LanguageTag;
|
||||
|
||||
@@ -69,6 +72,8 @@ final class HdmiCecController {
|
||||
|
||||
private static final int NUM_LOGICAL_ADDRESS = 16;
|
||||
|
||||
private static final int MAX_CEC_MESSAGE_HISTORY = 20;
|
||||
|
||||
// Predicate for whether the given logical address is remote device's one or not.
|
||||
private final Predicate<Integer> mRemoteDeviceAddressPredicate = new Predicate<Integer>() {
|
||||
@Override
|
||||
@@ -101,6 +106,10 @@ final class HdmiCecController {
|
||||
// Stores the local CEC devices in the system. Device type is used for key.
|
||||
private final SparseArray<HdmiCecLocalDevice> mLocalDevices = new SparseArray<>();
|
||||
|
||||
// Stores recent CEC messages history for debugging purpose.
|
||||
private final ArrayBlockingQueue<MessageHistoryRecord> mMessageHistory =
|
||||
new ArrayBlockingQueue<>(MAX_CEC_MESSAGE_HISTORY);
|
||||
|
||||
// Private constructor. Use HdmiCecController.create().
|
||||
private HdmiCecController(HdmiControlService service) {
|
||||
mService = service;
|
||||
@@ -580,6 +589,7 @@ final class HdmiCecController {
|
||||
void sendCommand(final HdmiCecMessage cecMessage,
|
||||
final HdmiControlService.SendMessageCallback callback) {
|
||||
assertRunOnServiceThread();
|
||||
addMessageToHistory(false /* isReceived */, cecMessage);
|
||||
runOnIoThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -597,7 +607,7 @@ final class HdmiCecController {
|
||||
|
||||
final int finalError = errorCode;
|
||||
if (finalError != SendMessageResult.SUCCESS) {
|
||||
Slog.w(TAG, "Failed to send " + cecMessage);
|
||||
Slog.w(TAG, "Failed to send " + cecMessage + " with errorCode=" + finalError);
|
||||
}
|
||||
if (callback != null) {
|
||||
runOnServiceThread(new Runnable() {
|
||||
@@ -619,6 +629,7 @@ final class HdmiCecController {
|
||||
assertRunOnServiceThread();
|
||||
HdmiCecMessage command = HdmiCecMessageBuilder.of(srcAddress, dstAddress, body);
|
||||
HdmiLogger.debug("[R]:" + command);
|
||||
addMessageToHistory(true /* isReceived */, command);
|
||||
onReceiveCommand(command);
|
||||
}
|
||||
|
||||
@@ -632,6 +643,16 @@ final class HdmiCecController {
|
||||
mService.onHotplug(port, connected);
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
private void addMessageToHistory(boolean isReceived, HdmiCecMessage message) {
|
||||
assertRunOnServiceThread();
|
||||
MessageHistoryRecord record = new MessageHistoryRecord(isReceived, message);
|
||||
if (!mMessageHistory.offer(record)) {
|
||||
mMessageHistory.poll();
|
||||
mMessageHistory.offer(record);
|
||||
}
|
||||
}
|
||||
|
||||
void dump(final IndentingPrintWriter pw) {
|
||||
for (int i = 0; i < mLocalDevices.size(); ++i) {
|
||||
pw.println("HdmiCecLocalDevice #" + i + ":");
|
||||
@@ -639,6 +660,13 @@ final class HdmiCecController {
|
||||
mLocalDevices.valueAt(i).dump(pw);
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
pw.println("CEC message history:");
|
||||
pw.increaseIndent();
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
for (MessageHistoryRecord record : mMessageHistory) {
|
||||
record.dump(pw, sdf);
|
||||
}
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
private static native long nativeInit(HdmiCecController handler, MessageQueue messageQueue);
|
||||
@@ -654,4 +682,24 @@ final class HdmiCecController {
|
||||
private static native void nativeSetLanguage(long controllerPtr, String language);
|
||||
private static native void nativeEnableAudioReturnChannel(long controllerPtr, int port, boolean flag);
|
||||
private static native boolean nativeIsConnected(long controllerPtr, int port);
|
||||
|
||||
private final class MessageHistoryRecord {
|
||||
private final long mTime;
|
||||
private final boolean mIsReceived; // true if received message and false if sent message
|
||||
private final HdmiCecMessage mMessage;
|
||||
|
||||
public MessageHistoryRecord(boolean isReceived, HdmiCecMessage message) {
|
||||
mTime = System.currentTimeMillis();
|
||||
mIsReceived = isReceived;
|
||||
mMessage = message;
|
||||
}
|
||||
|
||||
void dump(final IndentingPrintWriter pw, SimpleDateFormat sdf) {
|
||||
pw.print(mIsReceived ? "[R]" : "[S]");
|
||||
pw.print(" time=");
|
||||
pw.print(sdf.format(new Date(mTime)));
|
||||
pw.print(" message=");
|
||||
pw.println(mMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user