1 package com.android.internal.protolog; 2 3 import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MESSAGES; 4 import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE; 5 import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE_ID; 6 7 import android.util.ArrayMap; 8 import android.util.proto.ProtoInputStream; 9 10 import com.android.internal.protolog.common.ILogger; 11 12 import java.io.IOException; 13 import java.util.Map; 14 15 public class ProtoLogViewerConfigReader { 16 private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider; 17 private Map<Long, String> mLogMessageMap = null; 18 ProtoLogViewerConfigReader( ViewerConfigInputStreamProvider viewerConfigInputStreamProvider)19 public ProtoLogViewerConfigReader( 20 ViewerConfigInputStreamProvider viewerConfigInputStreamProvider) { 21 this.mViewerConfigInputStreamProvider = viewerConfigInputStreamProvider; 22 } 23 24 /** 25 * Returns message format string for its hash or null if unavailable 26 * or the viewer config is not loaded into memory. 27 */ getViewerString(long messageHash)28 public synchronized String getViewerString(long messageHash) { 29 if (mLogMessageMap != null) { 30 return mLogMessageMap.get(messageHash); 31 } else { 32 return null; 33 } 34 } 35 36 /** 37 * Loads the viewer config into memory. No-op if already loaded in memory. 38 */ loadViewerConfig(ILogger logger)39 public synchronized void loadViewerConfig(ILogger logger) { 40 if (mLogMessageMap != null) { 41 return; 42 } 43 44 try { 45 doLoadViewerConfig(); 46 logger.log("Loaded " + mLogMessageMap.size() + " log definitions"); 47 } catch (IOException e) { 48 logger.log("Unable to load log definitions: " 49 + "IOException while processing viewer config" + e); 50 } 51 } 52 53 /** 54 * Unload the viewer config from memory. 55 */ unloadViewerConfig()56 public synchronized void unloadViewerConfig() { 57 mLogMessageMap = null; 58 } 59 doLoadViewerConfig()60 private void doLoadViewerConfig() throws IOException { 61 mLogMessageMap = new ArrayMap<>(); 62 final ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream(); 63 64 while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { 65 if (pis.getFieldNumber() == (int) MESSAGES) { 66 final long inMessageToken = pis.start(MESSAGES); 67 68 long messageId = 0; 69 String message = null; 70 while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { 71 switch (pis.getFieldNumber()) { 72 case (int) MESSAGE_ID: 73 messageId = pis.readLong(MESSAGE_ID); 74 break; 75 case (int) MESSAGE: 76 message = pis.readString(MESSAGE); 77 break; 78 } 79 } 80 81 if (messageId == 0) { 82 throw new IOException("Failed to get message id"); 83 } 84 85 if (message == null) { 86 throw new IOException("Failed to get message string"); 87 } 88 89 mLogMessageMap.put(messageId, message); 90 91 pis.end(inMessageToken); 92 } 93 } 94 } 95 } 96