19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.util; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnorimport java.io.BufferedReader; 2062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnorimport java.io.FileReader; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.UnsupportedEncodingException; 2362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnorimport java.nio.BufferUnderflowException; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.ByteBuffer; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.ByteOrder; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collection; 2762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnorimport java.util.HashMap; 2862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnorimport java.util.regex.Matcher; 2962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnorimport java.util.regex.Pattern; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Access to the system diagnostic event record. System diagnostic events are 3362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * used to record certain system-level events (such as garbage collection, 3462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * activity manager state, system watchdogs, and other low level activity), 3562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * which may be automatically collected and analyzed during system development. 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * <p>This is <b>not</b> the main "logcat" debugging log ({@link android.util.Log})! 3862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * These diagnostic events are for system integrators, not application authors. 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * <p>Events use integer tag codes corresponding to /system/etc/event-log-tags. 4162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * They carry a payload of one or more int, long, or String values. The 4262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * event-log-tags file defines the payload contents for each type code. 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class EventLog { 45a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson /** @hide */ public EventLog() {} 46a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson 4762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final String TAG = "EventLog"; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final String TAGS_FILE = "/system/etc/event-log-tags"; 5062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final String COMMENT_PATTERN = "^\\s*(#.*)?$"; 5162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final String TAG_PATTERN = "^\\s*(\\d+)\\s+(\\w+)\\s*(\\(.*\\))?\\s*$"; 5262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static HashMap<String, Integer> sTagCodes = null; 5362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static HashMap<Integer, String> sTagNames = null; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** A previously logged event read from the logs. */ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final class Event { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ByteBuffer mBuffer; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 59747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn // Layout of event log entry received from Android logger. 60747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn // see system/core/include/log/logger.h 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LENGTH_OFFSET = 0; 62747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn private static final int HEADER_SIZE_OFFSET = 2; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int PROCESS_OFFSET = 4; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int THREAD_OFFSET = 8; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SECONDS_OFFSET = 12; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NANOSECONDS_OFFSET = 16; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn // Layout for event log v1 format, v2 and v3 use HEADER_SIZE_OFFSET 69747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn private static final int V1_PAYLOAD_START = 20; 70747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn private static final int DATA_OFFSET = 4; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor // Value types 7362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte INT_TYPE = 0; 7462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte LONG_TYPE = 1; 7562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte STRING_TYPE = 2; 7662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte LIST_TYPE = 3; 7762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @param data containing event, read from the system */ 7962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /*package*/ Event(byte[] data) { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuffer = ByteBuffer.wrap(data); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuffer.order(ByteOrder.nativeOrder()); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the process ID which wrote the log entry */ 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getProcessId() { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuffer.getInt(PROCESS_OFFSET); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the thread ID which wrote the log entry */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getThreadId() { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuffer.getInt(THREAD_OFFSET); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the wall clock time when the entry was written */ 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getTimeNanos() { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuffer.getInt(SECONDS_OFFSET) * 1000000000l 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mBuffer.getInt(NANOSECONDS_OFFSET); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the type tag code of the entry */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getTag() { 102747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn int offset = mBuffer.getShort(HEADER_SIZE_OFFSET); 103747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn if (offset == 0) { 104747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn offset = V1_PAYLOAD_START; 105747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn } 106747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn return mBuffer.getInt(offset); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return one of Integer, Long, String, null, or Object[] of same. */ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized Object getData() { 11162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { 112747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn int offset = mBuffer.getShort(HEADER_SIZE_OFFSET); 113747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn if (offset == 0) { 114747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn offset = V1_PAYLOAD_START; 115747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn } 116747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn mBuffer.limit(offset + mBuffer.getShort(LENGTH_OFFSET)); 117747802f8aa4d373885161724d9c2c61dcd4f8010Mark Salyzyn mBuffer.position(offset + DATA_OFFSET); // Just after the tag. 11862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return decodeObject(); 11962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (IllegalArgumentException e) { 12062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Illegal entry payload: tag=" + getTag(), e); 12162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return null; 12262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (BufferUnderflowException e) { 12362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Truncated entry payload: tag=" + getTag(), e); 12462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return null; 12562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 12630636876c079cdce5f856aa2269e2d2f769e8363Jim Miller } 12730636876c079cdce5f856aa2269e2d2f769e8363Jim Miller 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @return the loggable item at the current position in mBuffer. */ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object decodeObject() { 13062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor byte type = mBuffer.get(); 13162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor switch (type) { 13262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case INT_TYPE: 13330636876c079cdce5f856aa2269e2d2f769e8363Jim Miller return (Integer) mBuffer.getInt(); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case LONG_TYPE: 13630636876c079cdce5f856aa2269e2d2f769e8363Jim Miller return (Long) mBuffer.getLong(); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case STRING_TYPE: 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = mBuffer.getInt(); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int start = mBuffer.position(); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuffer.position(start + length); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new String(mBuffer.array(), start, length, "UTF-8"); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (UnsupportedEncodingException e) { 14562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "UTF-8 is not supported", e); 14662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return null; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case LIST_TYPE: 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = mBuffer.get(); 1516916089e838662b41d902cd9a0d2560b04633ef9Dan Egnor if (length < 0) length += 256; // treat as signed byte 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object[] array = new Object[length]; 15362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor for (int i = 0; i < length; ++i) array[i] = decodeObject(); 15462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return array; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 15762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor throw new IllegalArgumentException("Unknown entry type: " + type); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We assume that the native methods deal with any concurrency issues. 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 16662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param value A value to log 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int writeEvent(int tag, int value); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 17462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param value A value to log 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int writeEvent(int tag, long value); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 18262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param str A value to log 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int writeEvent(int tag, String str); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 19062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param list A list of values to log 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor public static native int writeEvent(int tag, Object... list); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read events from the log, filtered by type. 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tags to search for 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param output container to add events into 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException if something goes wrong reading events 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native void readEvents(int[] tags, Collection<Event> output) 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException; 20495ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller 20595ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller /** 20662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Get the name associated with an event type tag code. 20762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag code to look up 20862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @return the name of the tag, or null if no tag has that number 20995ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller */ 21062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor public static String getTagName(int tag) { 21162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor readTagsFile(); 21262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return sTagNames.get(tag); 21362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 21462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 21562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** 21662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Get the event type tag code associated with an event name. 21762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param name of event to look up 21862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @return the tag code, or -1 if no tag has that name 21962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor */ 22062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor public static int getTagCode(String name) { 22162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor readTagsFile(); 22262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Integer code = sTagCodes.get(name); 22362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return code != null ? code : -1; 22462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 22562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 22662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** 22762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Read TAGS_FILE, populating sTagCodes and sTagNames, if not already done. 22862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor */ 22962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static synchronized void readTagsFile() { 23062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor if (sTagCodes != null && sTagNames != null) return; 23162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 23262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagCodes = new HashMap<String, Integer>(); 23362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagNames = new HashMap<Integer, String>(); 23462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 23562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Pattern comment = Pattern.compile(COMMENT_PATTERN); 23662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Pattern tag = Pattern.compile(TAG_PATTERN); 23762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor BufferedReader reader = null; 23862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor String line; 23962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 24062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { 24162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor reader = new BufferedReader(new FileReader(TAGS_FILE), 256); 24262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor while ((line = reader.readLine()) != null) { 24362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor if (comment.matcher(line).matches()) continue; 24462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 24562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Matcher m = tag.matcher(line); 24662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor if (!m.matches()) { 24762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Bad entry in " + TAGS_FILE + ": " + line); 24862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor continue; 24962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 25062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 25162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { 25262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor int num = Integer.parseInt(m.group(1)); 25362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor String name = m.group(2); 25462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagCodes.put(name, num); 25562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagNames.put(num, name); 25662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (NumberFormatException e) { 25762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Error in " + TAGS_FILE + ": " + line, e); 25862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 25962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 26062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (IOException e) { 26162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Error reading " + TAGS_FILE, e); 26262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor // Leave the maps existing but unpopulated 26362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } finally { 26462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { if (reader != null) reader.close(); } catch (IOException e) {} 26562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 26662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 268