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 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Layout of event log entry received from kernel. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LENGTH_OFFSET = 0; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int PROCESS_OFFSET = 4; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int THREAD_OFFSET = 8; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SECONDS_OFFSET = 12; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NANOSECONDS_OFFSET = 16; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int PAYLOAD_START = 20; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int TAG_OFFSET = 20; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int DATA_START = 24; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor // Value types 7162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte INT_TYPE = 0; 7262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte LONG_TYPE = 1; 7362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte STRING_TYPE = 2; 7462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static final byte LIST_TYPE = 3; 7562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @param data containing event, read from the system */ 7762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /*package*/ Event(byte[] data) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuffer = ByteBuffer.wrap(data); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuffer.order(ByteOrder.nativeOrder()); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the process ID which wrote the log entry */ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getProcessId() { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuffer.getInt(PROCESS_OFFSET); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the thread ID which wrote the log entry */ 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getThreadId() { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuffer.getInt(THREAD_OFFSET); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the wall clock time when the entry was written */ 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getTimeNanos() { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuffer.getInt(SECONDS_OFFSET) * 1000000000l 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mBuffer.getInt(NANOSECONDS_OFFSET); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return the type tag code of the entry */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getTag() { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBuffer.getInt(TAG_OFFSET); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** @return one of Integer, Long, String, null, or Object[] of same. */ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized Object getData() { 10562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { 10662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor mBuffer.limit(PAYLOAD_START + mBuffer.getShort(LENGTH_OFFSET)); 10762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor mBuffer.position(DATA_START); // Just after the tag. 10862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return decodeObject(); 10962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (IllegalArgumentException e) { 11062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Illegal entry payload: tag=" + getTag(), e); 11162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return null; 11262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (BufferUnderflowException e) { 11362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Truncated entry payload: tag=" + getTag(), e); 11462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return null; 11562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 11630636876c079cdce5f856aa2269e2d2f769e8363Jim Miller } 11730636876c079cdce5f856aa2269e2d2f769e8363Jim Miller 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @return the loggable item at the current position in mBuffer. */ 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object decodeObject() { 12062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor byte type = mBuffer.get(); 12162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor switch (type) { 12262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case INT_TYPE: 12330636876c079cdce5f856aa2269e2d2f769e8363Jim Miller return (Integer) mBuffer.getInt(); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case LONG_TYPE: 12630636876c079cdce5f856aa2269e2d2f769e8363Jim Miller return (Long) mBuffer.getLong(); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case STRING_TYPE: 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = mBuffer.getInt(); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int start = mBuffer.position(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBuffer.position(start + length); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new String(mBuffer.array(), start, length, "UTF-8"); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (UnsupportedEncodingException e) { 13562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "UTF-8 is not supported", e); 13662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return null; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor case LIST_TYPE: 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = mBuffer.get(); 1416916089e838662b41d902cd9a0d2560b04633ef9Dan Egnor if (length < 0) length += 256; // treat as signed byte 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object[] array = new Object[length]; 14362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor for (int i = 0; i < length; ++i) array[i] = decodeObject(); 14462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return array; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 14762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor throw new IllegalArgumentException("Unknown entry type: " + type); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We assume that the native methods deal with any concurrency issues. 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 15662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param value A value to log 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int writeEvent(int tag, int value); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 16462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param value A value to log 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int writeEvent(int tag, long value); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 17262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param str A value to log 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int writeEvent(int tag, String str); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Record an event log message. 18062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag The event type tag code 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param list A list of values to log 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of bytes written 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor public static native int writeEvent(int tag, Object... list); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read events from the log, filtered by type. 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tags to search for 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param output container to add events into 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException if something goes wrong reading events 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native void readEvents(int[] tags, Collection<Event> output) 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException; 19495ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller 19595ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller /** 19662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Get the name associated with an event type tag code. 19762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param tag code to look up 19862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @return the name of the tag, or null if no tag has that number 19995ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller */ 20062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor public static String getTagName(int tag) { 20162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor readTagsFile(); 20262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return sTagNames.get(tag); 20362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 20462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 20562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** 20662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Get the event type tag code associated with an event name. 20762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @param name of event to look up 20862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * @return the tag code, or -1 if no tag has that name 20962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor */ 21062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor public static int getTagCode(String name) { 21162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor readTagsFile(); 21262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Integer code = sTagCodes.get(name); 21362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor return code != null ? code : -1; 21462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 21562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 21662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor /** 21762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor * Read TAGS_FILE, populating sTagCodes and sTagNames, if not already done. 21862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor */ 21962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor private static synchronized void readTagsFile() { 22062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor if (sTagCodes != null && sTagNames != null) return; 22162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 22262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagCodes = new HashMap<String, Integer>(); 22362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagNames = new HashMap<Integer, String>(); 22462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 22562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Pattern comment = Pattern.compile(COMMENT_PATTERN); 22662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Pattern tag = Pattern.compile(TAG_PATTERN); 22762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor BufferedReader reader = null; 22862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor String line; 22962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 23062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { 23162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor reader = new BufferedReader(new FileReader(TAGS_FILE), 256); 23262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor while ((line = reader.readLine()) != null) { 23362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor if (comment.matcher(line).matches()) continue; 23462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 23562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Matcher m = tag.matcher(line); 23662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor if (!m.matches()) { 23762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Bad entry in " + TAGS_FILE + ": " + line); 23862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor continue; 23962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 24062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor 24162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { 24262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor int num = Integer.parseInt(m.group(1)); 24362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor String name = m.group(2); 24462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagCodes.put(name, num); 24562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor sTagNames.put(num, name); 24662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (NumberFormatException e) { 24762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Error in " + TAGS_FILE + ": " + line, e); 24862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 24962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 25062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } catch (IOException e) { 25162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor Log.wtf(TAG, "Error reading " + TAGS_FILE, e); 25262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor // Leave the maps existing but unpopulated 25362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } finally { 25462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor try { if (reader != null) reader.close(); } catch (IOException e) {} 25562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 25662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 258