Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f30ce08 authored by Pablo Gamito's avatar Pablo Gamito Committed by Android (Google) Code Review
Browse files

Merge "Distinguish the reason why decoding failed." into main

parents a1d171f1 86237333
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import com.android.internal.protolog.common.IProtoLogGroup;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
@@ -161,15 +162,39 @@ public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
        messageString = message.getMessage(mViewerConfigReader);

        if (messageString == null) {
            throw new RuntimeException("Failed to decode message for logcat. "
                    + "Message hash (" + message.getMessageHash() + ") either not available in "
                    + "viewerConfig file (" +  mViewerConfigFilePath + ") or "
                    + "not loaded into memory from file before decoding.");
            // Either we failed to load the config for this log message from the viewer config file
            // into memory, or the message hash is simply not available in the viewer config file.
            // We want to confirm that the message hash is not available in the viewer config file
            // before throwing an exception.
            throw new RuntimeException(getReasonForFailureToGetMessageString(message));
        }

        return messageString;
    }

    private String getReasonForFailureToGetMessageString(Message message) {
        if (message.getMessageHash() == null) {
            return "Trying to get message from null message hash";
        }

        try {
            if (mViewerConfigReader.messageHashIsAvailableInFile(message.getMessageHash())) {
                return "Failed to decode message for logcat logging. "
                        + "Message hash (" + message.getMessageHash() + ") is not available in "
                        + "viewerConfig file (" +  mViewerConfigFilePath + "). This might be due "
                        + "to the viewer config file and the executing code being out of sync.";
            } else {
                return "Failed to decode message for logcat. "
                        + "Message hash (" + message.getMessageHash() + ") was available in the "
                        + "viewerConfig file (" +  mViewerConfigFilePath + ") but wasn't loaded "
                        + "into memory from file before decoding! This is likely a bug.";
            }
        } catch (IOException e) {
            return "Failed to get string message to log but could not identify the root cause due "
                    + "to an IO error in reading the viewer config file.";
        }
    }

    private void loadLogcatGroupsViewerConfig(@NonNull IProtoLogGroup[] protoLogGroups) {
        final var groupsLoggingToLogcat = new ArrayList<String>();
        for (IProtoLogGroup protoLogGroup : protoLogGroups) {
+30 −0
Original line number Diff line number Diff line
@@ -100,6 +100,36 @@ public class ProtoLogViewerConfigReader {
        }
    }

    /**
     * Return whether or not the viewer config file contains a message with the specified hash.
     * @param messageHash The hash message we are looking for in the viewer config file
     * @return True iff the message with message hash is contained in the viewer config.
     * @throws IOException if there was an issue reading the viewer config file.
     */
    public boolean messageHashIsAvailableInFile(long messageHash)
            throws IOException {
        try (var pisWrapper = mViewerConfigInputStreamProvider.getInputStream()) {
            final var pis = pisWrapper.get();
            while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                if (pis.getFieldNumber() == (int) MESSAGES) {
                    final long inMessageToken = pis.start(MESSAGES);

                    while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                        if (pis.getFieldNumber() == (int) MESSAGE_ID) {
                            if (pis.readLong(MESSAGE_ID) == messageHash) {
                                return true;
                            }
                        }
                    }

                    pis.end(inMessageToken);
                }
            }
        }

        return false;
    }

    @NonNull
    private Map<Long, String> loadViewerConfigMappingForGroup(@NonNull String group)
            throws IOException {
+11 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import org.junit.runners.JUnit4;
import perfetto.protos.ProtologCommon;

import java.io.File;
import java.io.IOException;

@Presubmit
@RunWith(JUnit4.class)
@@ -159,4 +160,14 @@ public class ProtoLogViewerConfigReaderTest {
        loadViewerConfig();
        unloadViewerConfig();
    }

    @Test
    public void testMessageHashIsAvailableInFile() throws IOException {
        Truth.assertThat(mConfig.messageHashIsAvailableInFile(1)).isTrue();
        Truth.assertThat(mConfig.messageHashIsAvailableInFile(2)).isTrue();
        Truth.assertThat(mConfig.messageHashIsAvailableInFile(3)).isTrue();
        Truth.assertThat(mConfig.messageHashIsAvailableInFile(4)).isTrue();
        Truth.assertThat(mConfig.messageHashIsAvailableInFile(5)).isTrue();
        Truth.assertThat(mConfig.messageHashIsAvailableInFile(6)).isFalse();
    }
}