13516800b611a79339a3c188332d13a26e9086b09Adam Lesinski/** 23516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Copyright (C) 2014 The Android Open Source Project 33516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * 43516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); you may not 53516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * use this file except in compliance with the License. You may obtain a copy 63516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * of the License at 73516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * 83516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 93516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * 103516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Unless required by applicable law or agreed to in writing, software 113516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 123516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 133516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * License for the specific language governing permissions and limitations 143516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * under the License. 153516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */ 163516800b611a79339a3c188332d13a26e9086b09Adam Lesinskipackage com.android.server.usage; 173516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 183516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport com.android.internal.util.XmlUtils; 193516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 203516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport org.xmlpull.v1.XmlPullParser; 213516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport org.xmlpull.v1.XmlPullParserException; 227f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport org.xmlpull.v1.XmlSerializer; 233516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 247f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport android.app.usage.ConfigurationStats; 253516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.TimeSparseArray; 263516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.UsageEvents; 273516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.UsageStats; 287f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport android.content.res.Configuration; 293516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 303516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport java.io.IOException; 313516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport java.net.ProtocolException; 323516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 333516800b611a79339a3c188332d13a26e9086b09Adam Lesinski/** 343516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * UsageStats reader/writer for version 1 of the XML format. 353516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */ 363516800b611a79339a3c188332d13a26e9086b09Adam Lesinskifinal class UsageStatsXmlV1 { 3737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static final String PACKAGES_TAG = "packages"; 387f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String PACKAGE_TAG = "package"; 3937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 4037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static final String CONFIGURATIONS_TAG = "configurations"; 4137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static final String CONFIG_TAG = "config"; 4237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 437f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String EVENT_LOG_TAG = "event-log"; 4437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static final String EVENT_TAG = "event"; 457f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 4637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Attributes 479d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski private static final String PACKAGE_ATTR = "package"; 489d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski private static final String CLASS_ATTR = "class"; 4937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static final String TOTAL_TIME_ACTIVE_ATTR = "timeActive"; 507f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String COUNT_ATTR = "count"; 517f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String ACTIVE_ATTR = "active"; 523516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String LAST_EVENT_ATTR = "lastEvent"; 533516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String TYPE_ATTR = "type"; 5437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 5537a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Time attributes stored as an offset of the beginTime. 5637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive"; 5737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static final String END_TIME_ATTR = "endTime"; 583516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String TIME_ATTR = "time"; 593516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 607f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void loadUsageStats(XmlPullParser parser, IntervalStats statsOut) 613516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws XmlPullParserException, IOException { 6237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final String pkg = parser.getAttributeValue(null, PACKAGE_ATTR); 6337a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski if (pkg == null) { 6437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski throw new ProtocolException("no " + PACKAGE_ATTR + " attribute present"); 653516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 663516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 6737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final UsageStats stats = statsOut.getOrCreateUsageStats(pkg); 6837a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 6937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Apply the offset to the beginTime to find the absolute time. 7037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski stats.mLastTimeUsed = statsOut.beginTime + XmlUtils.readLongAttribute( 7137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski parser, LAST_TIME_ACTIVE_ATTR); 7237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 733516800b611a79339a3c188332d13a26e9086b09Adam Lesinski stats.mTotalTimeInForeground = XmlUtils.readLongAttribute(parser, TOTAL_TIME_ACTIVE_ATTR); 743516800b611a79339a3c188332d13a26e9086b09Adam Lesinski stats.mLastEvent = XmlUtils.readIntAttribute(parser, LAST_EVENT_ATTR); 753516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 763516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 777f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void loadConfigStats(XmlPullParser parser, IntervalStats statsOut) 783516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws XmlPullParserException, IOException { 797f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final Configuration config = new Configuration(); 807f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski Configuration.readXmlAttrs(parser, config); 817f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 8237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final ConfigurationStats configStats = statsOut.getOrCreateConfigurationStats(config); 8337a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 8437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Apply the offset to the beginTime to find the absolute time. 8537a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski configStats.mLastTimeActive = statsOut.beginTime + XmlUtils.readLongAttribute( 8637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski parser, LAST_TIME_ACTIVE_ATTR); 8737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 887f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski configStats.mTotalTimeActive = XmlUtils.readLongAttribute(parser, TOTAL_TIME_ACTIVE_ATTR); 897f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski configStats.mActivationCount = XmlUtils.readIntAttribute(parser, COUNT_ATTR); 907f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (XmlUtils.readBooleanAttribute(parser, ACTIVE_ATTR)) { 917f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.activeConfiguration = configStats.mConfiguration; 923516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 937f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 943516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 957f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void loadEvent(XmlPullParser parser, IntervalStats statsOut) 967f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski throws XmlPullParserException, IOException { 9737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final String packageName = XmlUtils.readStringAttribute(parser, PACKAGE_ATTR); 989d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski if (packageName == null) { 9937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski throw new ProtocolException("no " + PACKAGE_ATTR + " attribute present"); 1003516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1013516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 10237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final String className = XmlUtils.readStringAttribute(parser, CLASS_ATTR); 1037f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 10437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final UsageEvents.Event event = statsOut.buildEvent(packageName, className); 10537a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 10637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Apply the offset to the beginTime to find the absolute time of this event. 10737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski event.mTimeStamp = statsOut.beginTime + XmlUtils.readLongAttribute(parser, TIME_ATTR); 10837a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 10937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski event.mEventType = XmlUtils.readIntAttribute(parser, TYPE_ATTR); 1107f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE) { 1117f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski event.mConfiguration = new Configuration(); 1127f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski Configuration.readXmlAttrs(parser, event.mConfiguration); 1137f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1147f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1157f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (statsOut.events == null) { 1167f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.events = new TimeSparseArray<>(); 1177f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1187f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.events.put(event.mTimeStamp, event); 1193516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1203516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 12137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static void writeUsageStats(XmlSerializer xml, final IntervalStats stats, 12237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final UsageStats usageStats) throws IOException { 1237f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.startTag(null, PACKAGE_TAG); 12437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 12537a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Write the time offset. 12637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, 12737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski usageStats.mLastTimeUsed - stats.beginTime); 12837a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 12937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, usageStats.mPackageName); 13037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, usageStats.mTotalTimeInForeground); 13137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeIntAttribute(xml, LAST_EVENT_ATTR, usageStats.mLastEvent); 13237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 1337f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.endTag(null, PACKAGE_TAG); 1347f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1357f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 13637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static void writeConfigStats(XmlSerializer xml, final IntervalStats stats, 13737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final ConfigurationStats configStats, boolean isActive) throws IOException { 13837a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.startTag(null, CONFIG_TAG); 13937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 14037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Write the time offset. 14137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, 14237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski configStats.mLastTimeActive - stats.beginTime); 14337a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 14437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, configStats.mTotalTimeActive); 14537a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeIntAttribute(xml, COUNT_ATTR, configStats.mActivationCount); 1467f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (isActive) { 1477f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeBooleanAttribute(xml, ACTIVE_ATTR, true); 1487f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1497f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1507f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski // Now write the attributes representing the configuration object. 15137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski Configuration.writeXmlAttrs(xml, configStats.mConfiguration); 1527f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 15337a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.endTag(null, CONFIG_TAG); 1543516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1553516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 15637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski private static void writeEvent(XmlSerializer xml, final IntervalStats stats, 15737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final UsageEvents.Event event) throws IOException { 15837a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.startTag(null, EVENT_TAG); 15937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 16037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski // Store the time offset. 16137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeLongAttribute(xml, TIME_ATTR, event.mTimeStamp - stats.beginTime); 16237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 1637f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, event.mPackage); 1649d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski if (event.mClass != null) { 1657f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeStringAttribute(xml, CLASS_ATTR, event.mClass); 1667f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1677f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType); 1687f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1697f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE 1707f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski && event.mConfiguration != null) { 1717f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski Configuration.writeXmlAttrs(xml, event.mConfiguration); 1729d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski } 1737f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 17437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.endTag(null, EVENT_TAG); 1753516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1763516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1773516800b611a79339a3c188332d13a26e9086b09Adam Lesinski /** 1783516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Reads from the {@link XmlPullParser}, assuming that it is already on the 1793516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * <code><usagestats></code> tag. 1803516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * 1813516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * @param parser The parser from which to read events. 1823516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * @param statsOut The stats object to populate with the data from the XML file. 1833516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */ 1843516800b611a79339a3c188332d13a26e9086b09Adam Lesinski public static void read(XmlPullParser parser, IntervalStats statsOut) 1853516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws XmlPullParserException, IOException { 18637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski statsOut.packageStats.clear(); 1877f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.configurations.clear(); 1887f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.activeConfiguration = null; 1893516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1903516800b611a79339a3c188332d13a26e9086b09Adam Lesinski if (statsOut.events != null) { 1913516800b611a79339a3c188332d13a26e9086b09Adam Lesinski statsOut.events.clear(); 1923516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1933516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1943516800b611a79339a3c188332d13a26e9086b09Adam Lesinski statsOut.endTime = XmlUtils.readLongAttribute(parser, END_TIME_ATTR); 1953516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1967f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski int eventCode; 1977f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski int outerDepth = parser.getDepth(); 1987f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski while ((eventCode = parser.next()) != XmlPullParser.END_DOCUMENT 1997f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski && (eventCode != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2007f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (eventCode != XmlPullParser.START_TAG) { 2017f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski continue; 2027f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 2037f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 2047f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final String tag = parser.getName(); 2057f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski switch (tag) { 2067f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski case PACKAGE_TAG: 2077f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski loadUsageStats(parser, statsOut); 2087f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski break; 2093516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 21037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski case CONFIG_TAG: 2117f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski loadConfigStats(parser, statsOut); 2127f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski break; 2137f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 21437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski case EVENT_TAG: 2157f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski loadEvent(parser, statsOut); 2167f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski break; 2173516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2183516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2193516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2203516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 2213516800b611a79339a3c188332d13a26e9086b09Adam Lesinski /** 22237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski * Writes the stats object to an XML file. The {@link XmlSerializer} 2233516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * has already written the <code><usagestats></code> tag, but attributes may still 2243516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * be added. 2253516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * 22637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski * @param xml The serializer to which to write the packageStats data. 2273516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * @param stats The stats object to write to the XML file. 2283516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */ 22937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski public static void write(XmlSerializer xml, IntervalStats stats) throws IOException { 23037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime); 2313516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 23237a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.startTag(null, PACKAGES_TAG); 23337a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski final int statsCount = stats.packageStats.size(); 2343516800b611a79339a3c188332d13a26e9086b09Adam Lesinski for (int i = 0; i < statsCount; i++) { 23537a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski writeUsageStats(xml, stats, stats.packageStats.valueAt(i)); 2363516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 23737a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.endTag(null, PACKAGES_TAG); 2383516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 23937a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski 24037a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.startTag(null, CONFIGURATIONS_TAG); 2417f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final int configCount = stats.configurations.size(); 2427f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski for (int i = 0; i < configCount; i++) { 2437f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski boolean active = stats.activeConfiguration.equals(stats.configurations.keyAt(i)); 24437a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski writeConfigStats(xml, stats, stats.configurations.valueAt(i), active); 2457f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 24637a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.endTag(null, CONFIGURATIONS_TAG); 2477f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 24837a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.startTag(null, EVENT_LOG_TAG); 2497f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final int eventCount = stats.events != null ? stats.events.size() : 0; 2507f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski for (int i = 0; i < eventCount; i++) { 25137a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski writeEvent(xml, stats, stats.events.valueAt(i)); 2523516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 25337a46b48dcb7e34ee3669cfb2ed78af08bfca3c7Adam Lesinski xml.endTag(null, EVENT_LOG_TAG); 2543516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2553516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 2563516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private UsageStatsXmlV1() { 2573516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2583516800b611a79339a3c188332d13a26e9086b09Adam Lesinski} 259