Loading core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java +3 −3 Original line number Diff line number Diff line Loading @@ -211,7 +211,7 @@ public class PerfettoProtoLogImpl implements IProtoLog { */ public int startLoggingToLogcat(String[] groups, ILogger logger) { if (mViewerConfigReader != null) { mViewerConfigReader.loadViewerConfig(logger); mViewerConfigReader.loadViewerConfig(groups, logger); } return setTextLogging(true, logger, groups); } Loading @@ -224,7 +224,7 @@ public class PerfettoProtoLogImpl implements IProtoLog { */ public int stopLoggingToLogcat(String[] groups, ILogger logger) { if (mViewerConfigReader != null) { mViewerConfigReader.unloadViewerConfig(); mViewerConfigReader.unloadViewerConfig(groups, logger); } return setTextLogging(false, logger, groups); } Loading Loading @@ -268,7 +268,7 @@ public class PerfettoProtoLogImpl implements IProtoLog { } case "enable-text" -> { if (mViewerConfigReader != null) { mViewerConfigReader.loadViewerConfig(logger); mViewerConfigReader.loadViewerConfig(groups, logger); } return setTextLogging(true, logger, groups); } Loading core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java +100 −22 Original line number Diff line number Diff line package com.android.internal.protolog; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.GROUPS; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.Group.ID; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.Group.NAME; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MESSAGES; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE_ID; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.GROUP_ID; import android.util.ArrayMap; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.Log; import android.util.LongSparseArray; import android.util.proto.ProtoInputStream; import com.android.internal.protolog.common.ILogger; import java.io.IOException; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.TreeMap; public class ProtoLogViewerConfigReader { private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider; private Map<Long, String> mLogMessageMap = null; private final Map<String, Set<Long>> mGroupHashes = new TreeMap<>(); private final LongSparseArray<String> mLogMessageMap = new LongSparseArray<>(); public ProtoLogViewerConfigReader( ViewerConfigInputStreamProvider viewerConfigInputStreamProvider) { Loading @@ -26,39 +38,62 @@ public class ProtoLogViewerConfigReader { * or the viewer config is not loaded into memory. */ public synchronized String getViewerString(long messageHash) { if (mLogMessageMap != null) { return mLogMessageMap.get(messageHash); } else { return null; } public synchronized void loadViewerConfig(String[] groups) { loadViewerConfig(groups, (message) -> {}); } /** * Loads the viewer config into memory. No-op if already loaded in memory. */ public synchronized void loadViewerConfig(ILogger logger) { if (mLogMessageMap != null) { return; public synchronized void loadViewerConfig(String[] groups, @NonNull ILogger logger) { for (String group : groups) { if (mGroupHashes.containsKey(group)) { continue; } try { doLoadViewerConfig(); Map<Long, String> mappings = loadViewerConfigMappingForGroup(group); mGroupHashes.put(group, mappings.keySet()); for (Long key : mappings.keySet()) { mLogMessageMap.put(key, mappings.get(key)); } logger.log("Loaded " + mLogMessageMap.size() + " log definitions"); } catch (IOException e) { logger.log("Unable to load log definitions: " + "IOException while processing viewer config" + e); } } } public synchronized void unloadViewerConfig(String[] groups) { unloadViewerConfig(groups, (message) -> {}); } /** * Unload the viewer config from memory. */ public synchronized void unloadViewerConfig() { mLogMessageMap = null; public synchronized void unloadViewerConfig(String[] groups, @NonNull ILogger logger) { for (String group : groups) { if (!mGroupHashes.containsKey(group)) { continue; } final Set<Long> hashes = mGroupHashes.get(group); for (Long hash : hashes) { logger.log("Unloading viewer config hash " + hash); mLogMessageMap.remove(hash); } } } private Map<Long, String> loadViewerConfigMappingForGroup(String group) throws IOException { Long targetGroupId = loadGroupId(group); private void doLoadViewerConfig() throws IOException { mLogMessageMap = new ArrayMap<>(); final Map<Long, String> hashesForGroup = new TreeMap<>(); final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream(); while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { Loading @@ -67,6 +102,7 @@ public class ProtoLogViewerConfigReader { long messageId = 0; String message = null; int groupId = 0; while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { switch (pis.getFieldNumber()) { case (int) MESSAGE_ID: Loading @@ -75,9 +111,16 @@ public class ProtoLogViewerConfigReader { case (int) MESSAGE: message = pis.readString(MESSAGE); break; case (int) GROUP_ID: groupId = pis.readInt(GROUP_ID); break; } } if (groupId == 0) { throw new IOException("Failed to get group id"); } if (messageId == 0) { throw new IOException("Failed to get message id"); } Loading @@ -86,10 +129,45 @@ public class ProtoLogViewerConfigReader { throw new IOException("Failed to get message string"); } mLogMessageMap.put(messageId, message); if (groupId == targetGroupId) { hashesForGroup.put(messageId, message); } pis.end(inMessageToken); } } return hashesForGroup; } private Long loadGroupId(String group) throws IOException { final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream(); while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { if (pis.getFieldNumber() == (int) GROUPS) { final long inMessageToken = pis.start(GROUPS); long groupId = 0; String groupName = null; while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { switch (pis.getFieldNumber()) { case (int) ID: groupId = pis.readInt(ID); break; case (int) NAME: groupName = pis.readString(NAME); break; } } if (Objects.equals(groupName, group)) { return groupId; } pis.end(inMessageToken); } } throw new RuntimeException("Group " + group + "not found in viewer config"); } } Loading
core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java +3 −3 Original line number Diff line number Diff line Loading @@ -211,7 +211,7 @@ public class PerfettoProtoLogImpl implements IProtoLog { */ public int startLoggingToLogcat(String[] groups, ILogger logger) { if (mViewerConfigReader != null) { mViewerConfigReader.loadViewerConfig(logger); mViewerConfigReader.loadViewerConfig(groups, logger); } return setTextLogging(true, logger, groups); } Loading @@ -224,7 +224,7 @@ public class PerfettoProtoLogImpl implements IProtoLog { */ public int stopLoggingToLogcat(String[] groups, ILogger logger) { if (mViewerConfigReader != null) { mViewerConfigReader.unloadViewerConfig(); mViewerConfigReader.unloadViewerConfig(groups, logger); } return setTextLogging(false, logger, groups); } Loading Loading @@ -268,7 +268,7 @@ public class PerfettoProtoLogImpl implements IProtoLog { } case "enable-text" -> { if (mViewerConfigReader != null) { mViewerConfigReader.loadViewerConfig(logger); mViewerConfigReader.loadViewerConfig(groups, logger); } return setTextLogging(true, logger, groups); } Loading
core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java +100 −22 Original line number Diff line number Diff line package com.android.internal.protolog; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.GROUPS; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.Group.ID; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.Group.NAME; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MESSAGES; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE_ID; import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.GROUP_ID; import android.util.ArrayMap; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.Log; import android.util.LongSparseArray; import android.util.proto.ProtoInputStream; import com.android.internal.protolog.common.ILogger; import java.io.IOException; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.TreeMap; public class ProtoLogViewerConfigReader { private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider; private Map<Long, String> mLogMessageMap = null; private final Map<String, Set<Long>> mGroupHashes = new TreeMap<>(); private final LongSparseArray<String> mLogMessageMap = new LongSparseArray<>(); public ProtoLogViewerConfigReader( ViewerConfigInputStreamProvider viewerConfigInputStreamProvider) { Loading @@ -26,39 +38,62 @@ public class ProtoLogViewerConfigReader { * or the viewer config is not loaded into memory. */ public synchronized String getViewerString(long messageHash) { if (mLogMessageMap != null) { return mLogMessageMap.get(messageHash); } else { return null; } public synchronized void loadViewerConfig(String[] groups) { loadViewerConfig(groups, (message) -> {}); } /** * Loads the viewer config into memory. No-op if already loaded in memory. */ public synchronized void loadViewerConfig(ILogger logger) { if (mLogMessageMap != null) { return; public synchronized void loadViewerConfig(String[] groups, @NonNull ILogger logger) { for (String group : groups) { if (mGroupHashes.containsKey(group)) { continue; } try { doLoadViewerConfig(); Map<Long, String> mappings = loadViewerConfigMappingForGroup(group); mGroupHashes.put(group, mappings.keySet()); for (Long key : mappings.keySet()) { mLogMessageMap.put(key, mappings.get(key)); } logger.log("Loaded " + mLogMessageMap.size() + " log definitions"); } catch (IOException e) { logger.log("Unable to load log definitions: " + "IOException while processing viewer config" + e); } } } public synchronized void unloadViewerConfig(String[] groups) { unloadViewerConfig(groups, (message) -> {}); } /** * Unload the viewer config from memory. */ public synchronized void unloadViewerConfig() { mLogMessageMap = null; public synchronized void unloadViewerConfig(String[] groups, @NonNull ILogger logger) { for (String group : groups) { if (!mGroupHashes.containsKey(group)) { continue; } final Set<Long> hashes = mGroupHashes.get(group); for (Long hash : hashes) { logger.log("Unloading viewer config hash " + hash); mLogMessageMap.remove(hash); } } } private Map<Long, String> loadViewerConfigMappingForGroup(String group) throws IOException { Long targetGroupId = loadGroupId(group); private void doLoadViewerConfig() throws IOException { mLogMessageMap = new ArrayMap<>(); final Map<Long, String> hashesForGroup = new TreeMap<>(); final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream(); while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { Loading @@ -67,6 +102,7 @@ public class ProtoLogViewerConfigReader { long messageId = 0; String message = null; int groupId = 0; while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { switch (pis.getFieldNumber()) { case (int) MESSAGE_ID: Loading @@ -75,9 +111,16 @@ public class ProtoLogViewerConfigReader { case (int) MESSAGE: message = pis.readString(MESSAGE); break; case (int) GROUP_ID: groupId = pis.readInt(GROUP_ID); break; } } if (groupId == 0) { throw new IOException("Failed to get group id"); } if (messageId == 0) { throw new IOException("Failed to get message id"); } Loading @@ -86,10 +129,45 @@ public class ProtoLogViewerConfigReader { throw new IOException("Failed to get message string"); } mLogMessageMap.put(messageId, message); if (groupId == targetGroupId) { hashesForGroup.put(messageId, message); } pis.end(inMessageToken); } } return hashesForGroup; } private Long loadGroupId(String group) throws IOException { final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream(); while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { if (pis.getFieldNumber() == (int) GROUPS) { final long inMessageToken = pis.start(GROUPS); long groupId = 0; String groupName = null; while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { switch (pis.getFieldNumber()) { case (int) ID: groupId = pis.readInt(ID); break; case (int) NAME: groupName = pis.readString(NAME); break; } } if (Objects.equals(groupName, group)) { return groupId; } pis.end(inMessageToken); } } throw new RuntimeException("Group " + group + "not found in viewer config"); } }