UsageStatsXmlV1.java revision 7f61e96db7c90c1f4418359672aa4656aebee500
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.FastXmlSerializer; 193516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport com.android.internal.util.XmlUtils; 203516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 213516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport org.xmlpull.v1.XmlPullParser; 223516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport org.xmlpull.v1.XmlPullParserException; 237f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport org.xmlpull.v1.XmlSerializer; 243516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 257f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport android.app.usage.ConfigurationStats; 263516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.TimeSparseArray; 273516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.UsageEvents; 283516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.app.usage.UsageStats; 293516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.content.ComponentName; 307f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport android.content.res.Configuration; 313516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 323516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport java.io.IOException; 333516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport java.net.ProtocolException; 347f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinskiimport java.util.Locale; 353516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 363516800b611a79339a3c188332d13a26e9086b09Adam Lesinski/** 373516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * UsageStats reader/writer for version 1 of the XML format. 383516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */ 393516800b611a79339a3c188332d13a26e9086b09Adam Lesinskifinal class UsageStatsXmlV1 { 407f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String PACKAGE_TAG = "package"; 417f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String CONFIGURATION_TAG = "config"; 427f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String EVENT_LOG_TAG = "event-log"; 437f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 443516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String BEGIN_TIME_ATTR = "beginTime"; 453516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String END_TIME_ATTR = "endTime"; 463516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String NAME_ATTR = "name"; 479d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski private static final String PACKAGE_ATTR = "package"; 489d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski private static final String CLASS_ATTR = "class"; 493516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String TOTAL_TIME_ACTIVE_ATTR = "totalTimeActive"; 503516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive"; 517f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String COUNT_ATTR = "count"; 527f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static final String ACTIVE_ATTR = "active"; 533516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String LAST_EVENT_ATTR = "lastEvent"; 543516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String TYPE_ATTR = "type"; 553516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private static final String TIME_ATTR = "time"; 563516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 577f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void loadUsageStats(XmlPullParser parser, IntervalStats statsOut) 583516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws XmlPullParserException, IOException { 593516800b611a79339a3c188332d13a26e9086b09Adam Lesinski final String name = parser.getAttributeValue(null, NAME_ATTR); 603516800b611a79339a3c188332d13a26e9086b09Adam Lesinski if (name == null) { 613516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throw new ProtocolException("no " + NAME_ATTR + " attribute present"); 623516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 633516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 647f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski UsageStats stats = statsOut.getOrCreateUsageStats(name); 653516800b611a79339a3c188332d13a26e9086b09Adam Lesinski stats.mTotalTimeInForeground = XmlUtils.readLongAttribute(parser, TOTAL_TIME_ACTIVE_ATTR); 663516800b611a79339a3c188332d13a26e9086b09Adam Lesinski stats.mLastTimeUsed = XmlUtils.readLongAttribute(parser, LAST_TIME_ACTIVE_ATTR); 673516800b611a79339a3c188332d13a26e9086b09Adam Lesinski stats.mLastEvent = XmlUtils.readIntAttribute(parser, LAST_EVENT_ATTR); 683516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 693516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 707f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void loadConfigStats(XmlPullParser parser, IntervalStats statsOut) 713516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws XmlPullParserException, IOException { 727f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final Configuration config = new Configuration(); 737f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski Configuration.readXmlAttrs(parser, config); 747f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 757f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski ConfigurationStats configStats = statsOut.getOrCreateConfigurationStats(config); 767f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski configStats.mLastTimeActive = XmlUtils.readLongAttribute(parser, LAST_TIME_ACTIVE_ATTR); 777f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski configStats.mTotalTimeActive = XmlUtils.readLongAttribute(parser, TOTAL_TIME_ACTIVE_ATTR); 787f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski configStats.mActivationCount = XmlUtils.readIntAttribute(parser, COUNT_ATTR); 797f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (XmlUtils.readBooleanAttribute(parser, ACTIVE_ATTR)) { 807f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.activeConfiguration = configStats.mConfiguration; 813516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 827f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 833516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 847f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void loadEvent(XmlPullParser parser, IntervalStats statsOut) 857f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski throws XmlPullParserException, IOException { 869d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski String packageName = XmlUtils.readStringAttribute(parser, PACKAGE_ATTR); 879d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski String className; 889d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski if (packageName == null) { 899d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski // Try getting the component name if it exists. 909d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski final String componentName = XmlUtils.readStringAttribute(parser, NAME_ATTR); 919d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski if (componentName == null) { 929d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski throw new ProtocolException("no " + NAME_ATTR + " or " + PACKAGE_ATTR + 939d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski " attribute present"); 949d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski } 959d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski ComponentName component = ComponentName.unflattenFromString(componentName); 969d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski if (component == null) { 979d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski throw new ProtocolException("ComponentName " + componentName + " is invalid"); 989d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski } 999d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski 1009d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski packageName = component.getPackageName(); 1019d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski className = component.getClassName(); 1029d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski } else { 1039d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski className = XmlUtils.readStringAttribute(parser, CLASS_ATTR); 1043516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1053516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1069d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski UsageEvents.Event event = statsOut.buildEvent(packageName, className); 1073516800b611a79339a3c188332d13a26e9086b09Adam Lesinski event.mEventType = XmlUtils.readIntAttribute(parser, TYPE_ATTR); 1083516800b611a79339a3c188332d13a26e9086b09Adam Lesinski event.mTimeStamp = XmlUtils.readLongAttribute(parser, TIME_ATTR); 1097f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 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 1217f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void writeUsageStats(XmlSerializer xml, final UsageStats stats) 1223516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws IOException { 1237f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.startTag(null, PACKAGE_TAG); 1247f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeStringAttribute(xml, NAME_ATTR, stats.mPackageName); 1257f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, stats.mTotalTimeInForeground); 1267f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, stats.mLastTimeUsed); 1277f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeIntAttribute(xml, LAST_EVENT_ATTR, stats.mLastEvent); 1287f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.endTag(null, PACKAGE_TAG); 1297f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1307f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1317f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void writeConfigStats(XmlSerializer xml, final ConfigurationStats stats, 1327f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski boolean isActive) throws IOException { 1337f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.startTag(null, CONFIGURATION_TAG); 1347f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, stats.mLastTimeActive); 1357f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, stats.mTotalTimeActive); 1367f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeIntAttribute(xml, COUNT_ATTR, stats.mActivationCount); 1377f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (isActive) { 1387f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeBooleanAttribute(xml, ACTIVE_ATTR, true); 1397f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1407f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1417f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski // Now write the attributes representing the configuration object. 1427f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski Configuration.writeXmlAttrs(xml, stats.mConfiguration); 1437f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1447f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.endTag(null, CONFIGURATION_TAG); 1453516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1463516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1477f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski private static void writeEvent(XmlSerializer xml, final UsageEvents.Event event) 1483516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws IOException { 1497f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.startTag(null, EVENT_LOG_TAG); 1507f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, event.mPackage); 1519d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski if (event.mClass != null) { 1527f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeStringAttribute(xml, CLASS_ATTR, event.mClass); 1537f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1547f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType); 1557f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski XmlUtils.writeLongAttribute(xml, TIME_ATTR, event.mTimeStamp); 1567f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1577f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE 1587f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski && event.mConfiguration != null) { 1597f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski Configuration.writeXmlAttrs(xml, event.mConfiguration); 1609d9607527f5bbf49c96565b63b90e36276b0dda7Adam Lesinski } 1617f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1627f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski xml.endTag(null, EVENT_LOG_TAG); 1633516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1643516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1653516800b611a79339a3c188332d13a26e9086b09Adam Lesinski /** 1663516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Reads from the {@link XmlPullParser}, assuming that it is already on the 1673516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * <code><usagestats></code> tag. 1683516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * 1693516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * @param parser The parser from which to read events. 1703516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * @param statsOut The stats object to populate with the data from the XML file. 1713516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */ 1723516800b611a79339a3c188332d13a26e9086b09Adam Lesinski public static void read(XmlPullParser parser, IntervalStats statsOut) 1733516800b611a79339a3c188332d13a26e9086b09Adam Lesinski throws XmlPullParserException, IOException { 1743516800b611a79339a3c188332d13a26e9086b09Adam Lesinski statsOut.stats.clear(); 1757f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.configurations.clear(); 1767f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski statsOut.activeConfiguration = null; 1773516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1783516800b611a79339a3c188332d13a26e9086b09Adam Lesinski if (statsOut.events != null) { 1793516800b611a79339a3c188332d13a26e9086b09Adam Lesinski statsOut.events.clear(); 1803516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 1813516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1823516800b611a79339a3c188332d13a26e9086b09Adam Lesinski statsOut.beginTime = XmlUtils.readLongAttribute(parser, BEGIN_TIME_ATTR); 1833516800b611a79339a3c188332d13a26e9086b09Adam Lesinski statsOut.endTime = XmlUtils.readLongAttribute(parser, END_TIME_ATTR); 1843516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1857f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski int eventCode; 1867f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski int outerDepth = parser.getDepth(); 1877f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski while ((eventCode = parser.next()) != XmlPullParser.END_DOCUMENT 1887f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski && (eventCode != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1897f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski if (eventCode != XmlPullParser.START_TAG) { 1907f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski continue; 1917f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 1927f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 1937f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final String tag = parser.getName(); 1947f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski switch (tag) { 1957f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski case PACKAGE_TAG: 1967f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski loadUsageStats(parser, statsOut); 1977f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski break; 1983516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 1997f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski case CONFIGURATION_TAG: 2007f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski loadConfigStats(parser, statsOut); 2017f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski break; 2027f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 2037f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski case EVENT_LOG_TAG: 2047f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski loadEvent(parser, statsOut); 2057f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski break; 2063516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2073516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2083516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2093516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 2103516800b611a79339a3c188332d13a26e9086b09Adam Lesinski /** 2113516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * Writes the stats object to an XML file. The {@link FastXmlSerializer} 2123516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * has already written the <code><usagestats></code> tag, but attributes may still 2133516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * be added. 2143516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * 2153516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * @param serializer The serializer to which to write the stats data. 2163516800b611a79339a3c188332d13a26e9086b09Adam Lesinski * @param stats The stats object to write to the XML file. 2173516800b611a79339a3c188332d13a26e9086b09Adam Lesinski */ 2183516800b611a79339a3c188332d13a26e9086b09Adam Lesinski public static void write(FastXmlSerializer serializer, IntervalStats stats) throws IOException { 2193516800b611a79339a3c188332d13a26e9086b09Adam Lesinski serializer.attribute(null, BEGIN_TIME_ATTR, Long.toString(stats.beginTime)); 2203516800b611a79339a3c188332d13a26e9086b09Adam Lesinski serializer.attribute(null, END_TIME_ATTR, Long.toString(stats.endTime)); 2213516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 2223516800b611a79339a3c188332d13a26e9086b09Adam Lesinski final int statsCount = stats.stats.size(); 2233516800b611a79339a3c188332d13a26e9086b09Adam Lesinski for (int i = 0; i < statsCount; i++) { 2243516800b611a79339a3c188332d13a26e9086b09Adam Lesinski writeUsageStats(serializer, stats.stats.valueAt(i)); 2253516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2263516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 2277f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final int configCount = stats.configurations.size(); 2287f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski for (int i = 0; i < configCount; i++) { 2297f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski boolean active = stats.activeConfiguration.equals(stats.configurations.keyAt(i)); 2307f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski writeConfigStats(serializer, stats.configurations.valueAt(i), active); 2317f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski } 2327f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski 2337f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski final int eventCount = stats.events != null ? stats.events.size() : 0; 2347f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski for (int i = 0; i < eventCount; i++) { 2357f61e96db7c90c1f4418359672aa4656aebee500Adam Lesinski writeEvent(serializer, stats.events.valueAt(i)); 2363516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2373516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2383516800b611a79339a3c188332d13a26e9086b09Adam Lesinski 2393516800b611a79339a3c188332d13a26e9086b09Adam Lesinski private UsageStatsXmlV1() { 2403516800b611a79339a3c188332d13a26e9086b09Adam Lesinski } 2413516800b611a79339a3c188332d13a26e9086b09Adam Lesinski} 242