Loading core/java/android/content/res/Configuration.java +0 −72 Original line number Diff line number Diff line Loading @@ -66,7 +66,6 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.lang.annotation.Retention; Loading Loading @@ -2641,75 +2640,4 @@ public final class Configuration implements Parcelable, Comparable<Configuration // For persistence, we don't care about assetsSeq and WindowConfiguration, so do not read it // out. } /** * Writes the Configuration's member fields as attributes into the XmlSerializer. * The serializer is expected to have already started a tag so that attributes can be * immediately written. * * @param xml The serializer to which to write the attributes. * @param config The Configuration whose member fields to write. * {@hide} */ public static void writeXmlAttrs(XmlSerializer xml, Configuration config) throws IOException { XmlUtils.writeIntAttribute(xml, XML_ATTR_FONT_SCALE, Float.floatToIntBits(config.fontScale)); if (config.mcc != 0) { XmlUtils.writeIntAttribute(xml, XML_ATTR_MCC, config.mcc); } if (config.mnc != 0) { XmlUtils.writeIntAttribute(xml, XML_ATTR_MNC, config.mnc); } config.fixUpLocaleList(); if (!config.mLocaleList.isEmpty()) { XmlUtils.writeStringAttribute(xml, XML_ATTR_LOCALES, config.mLocaleList.toLanguageTags()); } if (config.touchscreen != TOUCHSCREEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_TOUCHSCREEN, config.touchscreen); } if (config.keyboard != KEYBOARD_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD, config.keyboard); } if (config.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD_HIDDEN, config.keyboardHidden); } if (config.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_HARD_KEYBOARD_HIDDEN, config.hardKeyboardHidden); } if (config.navigation != NAVIGATION_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION, config.navigation); } if (config.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION_HIDDEN, config.navigationHidden); } if (config.orientation != ORIENTATION_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_ORIENTATION, config.orientation); } if (config.screenLayout != SCREENLAYOUT_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_LAYOUT, config.screenLayout); } if (config.colorMode != COLOR_MODE_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_COLOR_MODE, config.colorMode); } if (config.uiMode != 0) { XmlUtils.writeIntAttribute(xml, XML_ATTR_UI_MODE, config.uiMode); } if (config.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_WIDTH, config.screenWidthDp); } if (config.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_HEIGHT, config.screenHeightDp); } if (config.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SMALLEST_WIDTH, config.smallestScreenWidthDp); } if (config.densityDpi != DENSITY_DPI_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi); } // For persistence, we do not care about assetsSeq and window configuration, so do not write // it out. } } services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java +22 −9 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.usage.UsageEvents.Event.MAX_EVENT_TYPE; import static junit.framework.TestCase.fail; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import android.app.usage.TimeSparseArray; import android.app.usage.UsageEvents.Event; Loading @@ -35,6 +36,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -423,6 +425,11 @@ public class UsageStatsDatabaseTest { prevDB.putUsageStats(UsageStatsManager.INTERVAL_DAILY, mIntervalStats); // Create a backup with a specific version byte[] blob = prevDB.getBackupPayload(KEY_USAGE_STATS, version); if (version >= 1 && version <= 3) { assertFalse(blob != null && blob.length != 0, "UsageStatsDatabase shouldn't be able to write backups as XML"); return; } clearUsageStatsFiles(); Loading @@ -434,11 +441,9 @@ public class UsageStatsDatabaseTest { List<IntervalStats> stats = newDB.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, mEndTime, mIntervalStatsVerifier); if (version > newDB.BACKUP_VERSION || version < 1) { if (stats != null && stats.size() != 0) { fail("UsageStatsDatabase should ne be able to restore from unknown data versions"); } if (version > UsageStatsDatabase.BACKUP_VERSION || version < 1) { assertFalse(stats != null && !stats.isEmpty(), "UsageStatsDatabase shouldn't be able to restore from unknown data versions"); return; } Loading @@ -455,9 +460,12 @@ public class UsageStatsDatabaseTest { /** * Test the version upgrade from 3 to 4 * * Ignored - version 3 is now deprecated. */ @Ignore @Test public void testVersionUpgradeFrom3to4() throws IOException { public void ignore_testVersionUpgradeFrom3to4() throws IOException { runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_DAILY); runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_WEEKLY); runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_MONTHLY); Loading @@ -477,9 +485,12 @@ public class UsageStatsDatabaseTest { /** * Test the version upgrade from 3 to 5 * * Ignored - version 3 is now deprecated. */ @Ignore @Test public void testVersionUpgradeFrom3to5() throws IOException { public void ignore_testVersionUpgradeFrom3to5() throws IOException { runVersionChangeTest(3, 5, UsageStatsManager.INTERVAL_DAILY); runVersionChangeTest(3, 5, UsageStatsManager.INTERVAL_WEEKLY); runVersionChangeTest(3, 5, UsageStatsManager.INTERVAL_MONTHLY); Loading @@ -488,13 +499,15 @@ public class UsageStatsDatabaseTest { /** * Test the version upgrade from 3 to 4 * Test backup/restore */ @Test public void testBackupRestore() throws IOException { runBackupRestoreTest(1); runBackupRestoreTest(4); // test deprecated versions runBackupRestoreTest(1); // test invalid backup versions as well runBackupRestoreTest(0); runBackupRestoreTest(99999); Loading services/usage/java/com/android/server/usage/UsageStatsDatabase.java +28 −11 Original line number Diff line number Diff line Loading @@ -373,7 +373,12 @@ public class UsageStatsDatabase { Slog.e(TAG, "Failed read version upgrade breadcrumb"); throw new RuntimeException(e); } if (mCurrentVersion >= 4) { continueUpgradeLocked(previousVersion, token); } else { Slog.wtf(TAG, "Attempting to upgrade to an unsupported version: " + mCurrentVersion); } } if (version != mCurrentVersion || mNewUpdate) { Loading Loading @@ -487,6 +492,9 @@ public class UsageStatsDatabase { } private void continueUpgradeLocked(int version, long token) { if (version <= 3) { Slog.w(TAG, "Reading UsageStats as XML; current database version: " + mCurrentVersion); } final File backupDir = new File(mBackupsDir, Long.toString(token)); // Upgrade step logic for the entire usage stats directory, not individual interval dirs. Loading Loading @@ -876,6 +884,10 @@ public class UsageStatsDatabase { } private void writeLocked(AtomicFile file, IntervalStats stats) throws IOException { if (mCurrentVersion <= 3) { Slog.wtf(TAG, "Attempting to write UsageStats as XML with version " + mCurrentVersion); return; } writeLocked(file, stats, mCurrentVersion, mPackagesTokenData); } Loading @@ -892,17 +904,13 @@ public class UsageStatsDatabase { } } private void writeLocked(OutputStream out, IntervalStats stats) throws IOException { writeLocked(out, stats, mCurrentVersion, mPackagesTokenData); } private static void writeLocked(OutputStream out, IntervalStats stats, int version, PackagesTokenData packagesTokenData) throws IOException { switch (version) { case 1: case 2: case 3: UsageStatsXml.write(out, stats); Slog.wtf(TAG, "Attempting to write UsageStats as XML with version " + version); break; case 4: try { Loading @@ -927,6 +935,10 @@ public class UsageStatsDatabase { } private void readLocked(AtomicFile file, IntervalStats statsOut) throws IOException { if (mCurrentVersion <= 3) { Slog.wtf(TAG, "Reading UsageStats as XML; current database version: " + mCurrentVersion); } readLocked(file, statsOut, mCurrentVersion, mPackagesTokenData); } Loading @@ -951,17 +963,18 @@ public class UsageStatsDatabase { } } private void readLocked(InputStream in, IntervalStats statsOut) throws IOException { readLocked(in, statsOut, mCurrentVersion, mPackagesTokenData); } private static void readLocked(InputStream in, IntervalStats statsOut, int version, PackagesTokenData packagesTokenData) throws IOException { switch (version) { case 1: case 2: case 3: Slog.w(TAG, "Reading UsageStats as XML; database version: " + version); try { UsageStatsXml.read(in, statsOut); } catch (Exception e) { Slog.e(TAG, "Unable to read interval stats from XML", e); } break; case 4: try { Loading Loading @@ -1076,6 +1089,10 @@ public class UsageStatsDatabase { */ @VisibleForTesting public byte[] getBackupPayload(String key, int version) { if (version >= 1 && version <= 3) { Slog.wtf(TAG, "Attempting to backup UsageStats as XML with version " + version); return null; } synchronized (mLock) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (KEY_USAGE_STATS.equals(key)) { Loading services/usage/java/com/android/server/usage/UsageStatsXml.java +1 −19 Original line number Diff line number Diff line Loading @@ -16,14 +16,11 @@ package com.android.server.usage; import android.util.AtomicFile; import android.util.Slog; import android.util.Xml; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading @@ -31,7 +28,6 @@ import java.io.*; public class UsageStatsXml { private static final String TAG = "UsageStatsXml"; private static final int CURRENT_VERSION = 1; private static final String USAGESTATS_TAG = "usagestats"; private static final String VERSION_ATTR = "version"; static final String CHECKED_IN_SUFFIX = "-c"; Loading Loading @@ -61,18 +57,4 @@ public class UsageStatsXml { throw new IOException(e); } } public static void write(OutputStream out, IntervalStats stats) throws IOException { FastXmlSerializer xml = new FastXmlSerializer(); xml.setOutput(out, "utf-8"); xml.startDocument("utf-8", true); xml.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); xml.startTag(null, USAGESTATS_TAG); xml.attribute(null, VERSION_ATTR, Integer.toString(CURRENT_VERSION)); UsageStatsXmlV1.write(xml, stats); xml.endTag(null, USAGESTATS_TAG); xml.endDocument(); } } No newline at end of file services/usage/java/com/android/server/usage/UsageStatsXmlV1.java +0 −175 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.net.ProtocolException; Loading Loading @@ -243,135 +242,6 @@ final class UsageStatsXmlV1 { statsOut.addEvent(event); } private static void writeUsageStats(XmlSerializer xml, final IntervalStats stats, final UsageStats usageStats) throws IOException { xml.startTag(null, PACKAGE_TAG); // Write the time offset. XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, usageStats.mLastTimeUsed - stats.beginTime); XmlUtils.writeLongAttribute(xml, LAST_TIME_VISIBLE_ATTR, usageStats.mLastTimeVisible - stats.beginTime); XmlUtils.writeLongAttribute(xml, LAST_TIME_SERVICE_USED_ATTR, usageStats.mLastTimeForegroundServiceUsed - stats.beginTime); XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, usageStats.mPackageName); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, usageStats.mTotalTimeInForeground); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_VISIBLE_ATTR, usageStats.mTotalTimeVisible); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_SERVICE_USED_ATTR, usageStats.mTotalTimeForegroundServiceUsed); XmlUtils.writeIntAttribute(xml, LAST_EVENT_ATTR, usageStats.mLastEvent); if (usageStats.mAppLaunchCount > 0) { XmlUtils.writeIntAttribute(xml, APP_LAUNCH_COUNT_ATTR, usageStats.mAppLaunchCount); } writeChooserCounts(xml, usageStats); xml.endTag(null, PACKAGE_TAG); } private static void writeCountAndTime(XmlSerializer xml, String tag, int count, long time) throws IOException { xml.startTag(null, tag); XmlUtils.writeIntAttribute(xml, COUNT_ATTR, count); XmlUtils.writeLongAttribute(xml, TIME_ATTR, time); xml.endTag(null, tag); } private static void writeChooserCounts(XmlSerializer xml, final UsageStats usageStats) throws IOException { if (usageStats == null || usageStats.mChooserCounts == null || usageStats.mChooserCounts.keySet().isEmpty()) { return; } final int chooserCountSize = usageStats.mChooserCounts.size(); for (int i = 0; i < chooserCountSize; i++) { final String action = usageStats.mChooserCounts.keyAt(i); final ArrayMap<String, Integer> counts = usageStats.mChooserCounts.valueAt(i); if (action == null || counts == null || counts.isEmpty()) { continue; } xml.startTag(null, CHOOSER_COUNT_TAG); XmlUtils.writeStringAttribute(xml, NAME, action); writeCountsForAction(xml, counts); xml.endTag(null, CHOOSER_COUNT_TAG); } } private static void writeCountsForAction(XmlSerializer xml, ArrayMap<String, Integer> counts) throws IOException { final int countsSize = counts.size(); for (int i = 0; i < countsSize; i++) { String key = counts.keyAt(i); int count = counts.valueAt(i); if (count > 0) { xml.startTag(null, CATEGORY_TAG); XmlUtils.writeStringAttribute(xml, NAME, key); XmlUtils.writeIntAttribute(xml, COUNT, count); xml.endTag(null, CATEGORY_TAG); } } } private static void writeConfigStats(XmlSerializer xml, final IntervalStats stats, final ConfigurationStats configStats, boolean isActive) throws IOException { xml.startTag(null, CONFIG_TAG); // Write the time offset. XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, configStats.mLastTimeActive - stats.beginTime); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, configStats.mTotalTimeActive); XmlUtils.writeIntAttribute(xml, COUNT_ATTR, configStats.mActivationCount); if (isActive) { XmlUtils.writeBooleanAttribute(xml, ACTIVE_ATTR, true); } // Now write the attributes representing the configuration object. Configuration.writeXmlAttrs(xml, configStats.mConfiguration); xml.endTag(null, CONFIG_TAG); } private static void writeEvent(XmlSerializer xml, final IntervalStats stats, final UsageEvents.Event event) throws IOException { xml.startTag(null, EVENT_TAG); // Store the time offset. XmlUtils.writeLongAttribute(xml, TIME_ATTR, event.mTimeStamp - stats.beginTime); XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, event.mPackage); if (event.mClass != null) { XmlUtils.writeStringAttribute(xml, CLASS_ATTR, event.mClass); } XmlUtils.writeIntAttribute(xml, FLAGS_ATTR, event.mFlags); XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType); XmlUtils.writeIntAttribute(xml, INSTANCE_ID_ATTR, event.mInstanceId); switch (event.mEventType) { case UsageEvents.Event.CONFIGURATION_CHANGE: if (event.mConfiguration != null) { Configuration.writeXmlAttrs(xml, event.mConfiguration); } break; case UsageEvents.Event.SHORTCUT_INVOCATION: if (event.mShortcutId != null) { XmlUtils.writeStringAttribute(xml, SHORTCUT_ID_ATTR, event.mShortcutId); } break; case UsageEvents.Event.STANDBY_BUCKET_CHANGED: if (event.mBucketAndReason != 0) { XmlUtils.writeIntAttribute(xml, STANDBY_BUCKET_ATTR, event.mBucketAndReason); } break; case UsageEvents.Event.NOTIFICATION_INTERRUPTION: if (event.mNotificationChannelId != null) { XmlUtils.writeStringAttribute( xml, NOTIFICATION_CHANNEL_ATTR, event.mNotificationChannelId); } break; } xml.endTag(null, EVENT_TAG); } /** * Reads from the {@link XmlPullParser}, assuming that it is already on the * <code><usagestats></code> tag. Loading Loading @@ -440,51 +310,6 @@ final class UsageStatsXmlV1 { } } /** * Writes the stats object to an XML file. The {@link XmlSerializer} * has already written the <code><usagestats></code> tag, but attributes may still * be added. * * @param xml The serializer to which to write the packageStats data. * @param stats The stats object to write to the XML file. */ public static void write(XmlSerializer xml, IntervalStats stats) throws IOException { XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime); XmlUtils.writeIntAttribute(xml, MAJOR_VERSION_ATTR, stats.majorVersion); XmlUtils.writeIntAttribute(xml, MINOR_VERSION_ATTR, stats.minorVersion); writeCountAndTime(xml, INTERACTIVE_TAG, stats.interactiveTracker.count, stats.interactiveTracker.duration); writeCountAndTime(xml, NON_INTERACTIVE_TAG, stats.nonInteractiveTracker.count, stats.nonInteractiveTracker.duration); writeCountAndTime(xml, KEYGUARD_SHOWN_TAG, stats.keyguardShownTracker.count, stats.keyguardShownTracker.duration); writeCountAndTime(xml, KEYGUARD_HIDDEN_TAG, stats.keyguardHiddenTracker.count, stats.keyguardHiddenTracker.duration); xml.startTag(null, PACKAGES_TAG); final int statsCount = stats.packageStats.size(); for (int i = 0; i < statsCount; i++) { writeUsageStats(xml, stats, stats.packageStats.valueAt(i)); } xml.endTag(null, PACKAGES_TAG); xml.startTag(null, CONFIGURATIONS_TAG); final int configCount = stats.configurations.size(); for (int i = 0; i < configCount; i++) { boolean active = stats.activeConfiguration.equals(stats.configurations.keyAt(i)); writeConfigStats(xml, stats, stats.configurations.valueAt(i), active); } xml.endTag(null, CONFIGURATIONS_TAG); xml.startTag(null, EVENT_LOG_TAG); final int eventCount = stats.events.size(); for (int i = 0; i < eventCount; i++) { writeEvent(xml, stats, stats.events.get(i)); } xml.endTag(null, EVENT_LOG_TAG); } private UsageStatsXmlV1() { } } Loading
core/java/android/content/res/Configuration.java +0 −72 Original line number Diff line number Diff line Loading @@ -66,7 +66,6 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.lang.annotation.Retention; Loading Loading @@ -2641,75 +2640,4 @@ public final class Configuration implements Parcelable, Comparable<Configuration // For persistence, we don't care about assetsSeq and WindowConfiguration, so do not read it // out. } /** * Writes the Configuration's member fields as attributes into the XmlSerializer. * The serializer is expected to have already started a tag so that attributes can be * immediately written. * * @param xml The serializer to which to write the attributes. * @param config The Configuration whose member fields to write. * {@hide} */ public static void writeXmlAttrs(XmlSerializer xml, Configuration config) throws IOException { XmlUtils.writeIntAttribute(xml, XML_ATTR_FONT_SCALE, Float.floatToIntBits(config.fontScale)); if (config.mcc != 0) { XmlUtils.writeIntAttribute(xml, XML_ATTR_MCC, config.mcc); } if (config.mnc != 0) { XmlUtils.writeIntAttribute(xml, XML_ATTR_MNC, config.mnc); } config.fixUpLocaleList(); if (!config.mLocaleList.isEmpty()) { XmlUtils.writeStringAttribute(xml, XML_ATTR_LOCALES, config.mLocaleList.toLanguageTags()); } if (config.touchscreen != TOUCHSCREEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_TOUCHSCREEN, config.touchscreen); } if (config.keyboard != KEYBOARD_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD, config.keyboard); } if (config.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_KEYBOARD_HIDDEN, config.keyboardHidden); } if (config.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_HARD_KEYBOARD_HIDDEN, config.hardKeyboardHidden); } if (config.navigation != NAVIGATION_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION, config.navigation); } if (config.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_NAVIGATION_HIDDEN, config.navigationHidden); } if (config.orientation != ORIENTATION_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_ORIENTATION, config.orientation); } if (config.screenLayout != SCREENLAYOUT_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_LAYOUT, config.screenLayout); } if (config.colorMode != COLOR_MODE_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_COLOR_MODE, config.colorMode); } if (config.uiMode != 0) { XmlUtils.writeIntAttribute(xml, XML_ATTR_UI_MODE, config.uiMode); } if (config.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_WIDTH, config.screenWidthDp); } if (config.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SCREEN_HEIGHT, config.screenHeightDp); } if (config.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_SMALLEST_WIDTH, config.smallestScreenWidthDp); } if (config.densityDpi != DENSITY_DPI_UNDEFINED) { XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi); } // For persistence, we do not care about assetsSeq and window configuration, so do not write // it out. } }
services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java +22 −9 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.usage.UsageEvents.Event.MAX_EVENT_TYPE; import static junit.framework.TestCase.fail; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import android.app.usage.TimeSparseArray; import android.app.usage.UsageEvents.Event; Loading @@ -35,6 +36,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -423,6 +425,11 @@ public class UsageStatsDatabaseTest { prevDB.putUsageStats(UsageStatsManager.INTERVAL_DAILY, mIntervalStats); // Create a backup with a specific version byte[] blob = prevDB.getBackupPayload(KEY_USAGE_STATS, version); if (version >= 1 && version <= 3) { assertFalse(blob != null && blob.length != 0, "UsageStatsDatabase shouldn't be able to write backups as XML"); return; } clearUsageStatsFiles(); Loading @@ -434,11 +441,9 @@ public class UsageStatsDatabaseTest { List<IntervalStats> stats = newDB.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, mEndTime, mIntervalStatsVerifier); if (version > newDB.BACKUP_VERSION || version < 1) { if (stats != null && stats.size() != 0) { fail("UsageStatsDatabase should ne be able to restore from unknown data versions"); } if (version > UsageStatsDatabase.BACKUP_VERSION || version < 1) { assertFalse(stats != null && !stats.isEmpty(), "UsageStatsDatabase shouldn't be able to restore from unknown data versions"); return; } Loading @@ -455,9 +460,12 @@ public class UsageStatsDatabaseTest { /** * Test the version upgrade from 3 to 4 * * Ignored - version 3 is now deprecated. */ @Ignore @Test public void testVersionUpgradeFrom3to4() throws IOException { public void ignore_testVersionUpgradeFrom3to4() throws IOException { runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_DAILY); runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_WEEKLY); runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_MONTHLY); Loading @@ -477,9 +485,12 @@ public class UsageStatsDatabaseTest { /** * Test the version upgrade from 3 to 5 * * Ignored - version 3 is now deprecated. */ @Ignore @Test public void testVersionUpgradeFrom3to5() throws IOException { public void ignore_testVersionUpgradeFrom3to5() throws IOException { runVersionChangeTest(3, 5, UsageStatsManager.INTERVAL_DAILY); runVersionChangeTest(3, 5, UsageStatsManager.INTERVAL_WEEKLY); runVersionChangeTest(3, 5, UsageStatsManager.INTERVAL_MONTHLY); Loading @@ -488,13 +499,15 @@ public class UsageStatsDatabaseTest { /** * Test the version upgrade from 3 to 4 * Test backup/restore */ @Test public void testBackupRestore() throws IOException { runBackupRestoreTest(1); runBackupRestoreTest(4); // test deprecated versions runBackupRestoreTest(1); // test invalid backup versions as well runBackupRestoreTest(0); runBackupRestoreTest(99999); Loading
services/usage/java/com/android/server/usage/UsageStatsDatabase.java +28 −11 Original line number Diff line number Diff line Loading @@ -373,7 +373,12 @@ public class UsageStatsDatabase { Slog.e(TAG, "Failed read version upgrade breadcrumb"); throw new RuntimeException(e); } if (mCurrentVersion >= 4) { continueUpgradeLocked(previousVersion, token); } else { Slog.wtf(TAG, "Attempting to upgrade to an unsupported version: " + mCurrentVersion); } } if (version != mCurrentVersion || mNewUpdate) { Loading Loading @@ -487,6 +492,9 @@ public class UsageStatsDatabase { } private void continueUpgradeLocked(int version, long token) { if (version <= 3) { Slog.w(TAG, "Reading UsageStats as XML; current database version: " + mCurrentVersion); } final File backupDir = new File(mBackupsDir, Long.toString(token)); // Upgrade step logic for the entire usage stats directory, not individual interval dirs. Loading Loading @@ -876,6 +884,10 @@ public class UsageStatsDatabase { } private void writeLocked(AtomicFile file, IntervalStats stats) throws IOException { if (mCurrentVersion <= 3) { Slog.wtf(TAG, "Attempting to write UsageStats as XML with version " + mCurrentVersion); return; } writeLocked(file, stats, mCurrentVersion, mPackagesTokenData); } Loading @@ -892,17 +904,13 @@ public class UsageStatsDatabase { } } private void writeLocked(OutputStream out, IntervalStats stats) throws IOException { writeLocked(out, stats, mCurrentVersion, mPackagesTokenData); } private static void writeLocked(OutputStream out, IntervalStats stats, int version, PackagesTokenData packagesTokenData) throws IOException { switch (version) { case 1: case 2: case 3: UsageStatsXml.write(out, stats); Slog.wtf(TAG, "Attempting to write UsageStats as XML with version " + version); break; case 4: try { Loading @@ -927,6 +935,10 @@ public class UsageStatsDatabase { } private void readLocked(AtomicFile file, IntervalStats statsOut) throws IOException { if (mCurrentVersion <= 3) { Slog.wtf(TAG, "Reading UsageStats as XML; current database version: " + mCurrentVersion); } readLocked(file, statsOut, mCurrentVersion, mPackagesTokenData); } Loading @@ -951,17 +963,18 @@ public class UsageStatsDatabase { } } private void readLocked(InputStream in, IntervalStats statsOut) throws IOException { readLocked(in, statsOut, mCurrentVersion, mPackagesTokenData); } private static void readLocked(InputStream in, IntervalStats statsOut, int version, PackagesTokenData packagesTokenData) throws IOException { switch (version) { case 1: case 2: case 3: Slog.w(TAG, "Reading UsageStats as XML; database version: " + version); try { UsageStatsXml.read(in, statsOut); } catch (Exception e) { Slog.e(TAG, "Unable to read interval stats from XML", e); } break; case 4: try { Loading Loading @@ -1076,6 +1089,10 @@ public class UsageStatsDatabase { */ @VisibleForTesting public byte[] getBackupPayload(String key, int version) { if (version >= 1 && version <= 3) { Slog.wtf(TAG, "Attempting to backup UsageStats as XML with version " + version); return null; } synchronized (mLock) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (KEY_USAGE_STATS.equals(key)) { Loading
services/usage/java/com/android/server/usage/UsageStatsXml.java +1 −19 Original line number Diff line number Diff line Loading @@ -16,14 +16,11 @@ package com.android.server.usage; import android.util.AtomicFile; import android.util.Slog; import android.util.Xml; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading @@ -31,7 +28,6 @@ import java.io.*; public class UsageStatsXml { private static final String TAG = "UsageStatsXml"; private static final int CURRENT_VERSION = 1; private static final String USAGESTATS_TAG = "usagestats"; private static final String VERSION_ATTR = "version"; static final String CHECKED_IN_SUFFIX = "-c"; Loading Loading @@ -61,18 +57,4 @@ public class UsageStatsXml { throw new IOException(e); } } public static void write(OutputStream out, IntervalStats stats) throws IOException { FastXmlSerializer xml = new FastXmlSerializer(); xml.setOutput(out, "utf-8"); xml.startDocument("utf-8", true); xml.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); xml.startTag(null, USAGESTATS_TAG); xml.attribute(null, VERSION_ATTR, Integer.toString(CURRENT_VERSION)); UsageStatsXmlV1.write(xml, stats); xml.endTag(null, USAGESTATS_TAG); xml.endDocument(); } } No newline at end of file
services/usage/java/com/android/server/usage/UsageStatsXmlV1.java +0 −175 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.net.ProtocolException; Loading Loading @@ -243,135 +242,6 @@ final class UsageStatsXmlV1 { statsOut.addEvent(event); } private static void writeUsageStats(XmlSerializer xml, final IntervalStats stats, final UsageStats usageStats) throws IOException { xml.startTag(null, PACKAGE_TAG); // Write the time offset. XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, usageStats.mLastTimeUsed - stats.beginTime); XmlUtils.writeLongAttribute(xml, LAST_TIME_VISIBLE_ATTR, usageStats.mLastTimeVisible - stats.beginTime); XmlUtils.writeLongAttribute(xml, LAST_TIME_SERVICE_USED_ATTR, usageStats.mLastTimeForegroundServiceUsed - stats.beginTime); XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, usageStats.mPackageName); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, usageStats.mTotalTimeInForeground); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_VISIBLE_ATTR, usageStats.mTotalTimeVisible); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_SERVICE_USED_ATTR, usageStats.mTotalTimeForegroundServiceUsed); XmlUtils.writeIntAttribute(xml, LAST_EVENT_ATTR, usageStats.mLastEvent); if (usageStats.mAppLaunchCount > 0) { XmlUtils.writeIntAttribute(xml, APP_LAUNCH_COUNT_ATTR, usageStats.mAppLaunchCount); } writeChooserCounts(xml, usageStats); xml.endTag(null, PACKAGE_TAG); } private static void writeCountAndTime(XmlSerializer xml, String tag, int count, long time) throws IOException { xml.startTag(null, tag); XmlUtils.writeIntAttribute(xml, COUNT_ATTR, count); XmlUtils.writeLongAttribute(xml, TIME_ATTR, time); xml.endTag(null, tag); } private static void writeChooserCounts(XmlSerializer xml, final UsageStats usageStats) throws IOException { if (usageStats == null || usageStats.mChooserCounts == null || usageStats.mChooserCounts.keySet().isEmpty()) { return; } final int chooserCountSize = usageStats.mChooserCounts.size(); for (int i = 0; i < chooserCountSize; i++) { final String action = usageStats.mChooserCounts.keyAt(i); final ArrayMap<String, Integer> counts = usageStats.mChooserCounts.valueAt(i); if (action == null || counts == null || counts.isEmpty()) { continue; } xml.startTag(null, CHOOSER_COUNT_TAG); XmlUtils.writeStringAttribute(xml, NAME, action); writeCountsForAction(xml, counts); xml.endTag(null, CHOOSER_COUNT_TAG); } } private static void writeCountsForAction(XmlSerializer xml, ArrayMap<String, Integer> counts) throws IOException { final int countsSize = counts.size(); for (int i = 0; i < countsSize; i++) { String key = counts.keyAt(i); int count = counts.valueAt(i); if (count > 0) { xml.startTag(null, CATEGORY_TAG); XmlUtils.writeStringAttribute(xml, NAME, key); XmlUtils.writeIntAttribute(xml, COUNT, count); xml.endTag(null, CATEGORY_TAG); } } } private static void writeConfigStats(XmlSerializer xml, final IntervalStats stats, final ConfigurationStats configStats, boolean isActive) throws IOException { xml.startTag(null, CONFIG_TAG); // Write the time offset. XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, configStats.mLastTimeActive - stats.beginTime); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, configStats.mTotalTimeActive); XmlUtils.writeIntAttribute(xml, COUNT_ATTR, configStats.mActivationCount); if (isActive) { XmlUtils.writeBooleanAttribute(xml, ACTIVE_ATTR, true); } // Now write the attributes representing the configuration object. Configuration.writeXmlAttrs(xml, configStats.mConfiguration); xml.endTag(null, CONFIG_TAG); } private static void writeEvent(XmlSerializer xml, final IntervalStats stats, final UsageEvents.Event event) throws IOException { xml.startTag(null, EVENT_TAG); // Store the time offset. XmlUtils.writeLongAttribute(xml, TIME_ATTR, event.mTimeStamp - stats.beginTime); XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, event.mPackage); if (event.mClass != null) { XmlUtils.writeStringAttribute(xml, CLASS_ATTR, event.mClass); } XmlUtils.writeIntAttribute(xml, FLAGS_ATTR, event.mFlags); XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType); XmlUtils.writeIntAttribute(xml, INSTANCE_ID_ATTR, event.mInstanceId); switch (event.mEventType) { case UsageEvents.Event.CONFIGURATION_CHANGE: if (event.mConfiguration != null) { Configuration.writeXmlAttrs(xml, event.mConfiguration); } break; case UsageEvents.Event.SHORTCUT_INVOCATION: if (event.mShortcutId != null) { XmlUtils.writeStringAttribute(xml, SHORTCUT_ID_ATTR, event.mShortcutId); } break; case UsageEvents.Event.STANDBY_BUCKET_CHANGED: if (event.mBucketAndReason != 0) { XmlUtils.writeIntAttribute(xml, STANDBY_BUCKET_ATTR, event.mBucketAndReason); } break; case UsageEvents.Event.NOTIFICATION_INTERRUPTION: if (event.mNotificationChannelId != null) { XmlUtils.writeStringAttribute( xml, NOTIFICATION_CHANNEL_ATTR, event.mNotificationChannelId); } break; } xml.endTag(null, EVENT_TAG); } /** * Reads from the {@link XmlPullParser}, assuming that it is already on the * <code><usagestats></code> tag. Loading Loading @@ -440,51 +310,6 @@ final class UsageStatsXmlV1 { } } /** * Writes the stats object to an XML file. The {@link XmlSerializer} * has already written the <code><usagestats></code> tag, but attributes may still * be added. * * @param xml The serializer to which to write the packageStats data. * @param stats The stats object to write to the XML file. */ public static void write(XmlSerializer xml, IntervalStats stats) throws IOException { XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime); XmlUtils.writeIntAttribute(xml, MAJOR_VERSION_ATTR, stats.majorVersion); XmlUtils.writeIntAttribute(xml, MINOR_VERSION_ATTR, stats.minorVersion); writeCountAndTime(xml, INTERACTIVE_TAG, stats.interactiveTracker.count, stats.interactiveTracker.duration); writeCountAndTime(xml, NON_INTERACTIVE_TAG, stats.nonInteractiveTracker.count, stats.nonInteractiveTracker.duration); writeCountAndTime(xml, KEYGUARD_SHOWN_TAG, stats.keyguardShownTracker.count, stats.keyguardShownTracker.duration); writeCountAndTime(xml, KEYGUARD_HIDDEN_TAG, stats.keyguardHiddenTracker.count, stats.keyguardHiddenTracker.duration); xml.startTag(null, PACKAGES_TAG); final int statsCount = stats.packageStats.size(); for (int i = 0; i < statsCount; i++) { writeUsageStats(xml, stats, stats.packageStats.valueAt(i)); } xml.endTag(null, PACKAGES_TAG); xml.startTag(null, CONFIGURATIONS_TAG); final int configCount = stats.configurations.size(); for (int i = 0; i < configCount; i++) { boolean active = stats.activeConfiguration.equals(stats.configurations.keyAt(i)); writeConfigStats(xml, stats, stats.configurations.valueAt(i), active); } xml.endTag(null, CONFIGURATIONS_TAG); xml.startTag(null, EVENT_LOG_TAG); final int eventCount = stats.events.size(); for (int i = 0; i < eventCount; i++) { writeEvent(xml, stats, stats.events.get(i)); } xml.endTag(null, EVENT_LOG_TAG); } private UsageStatsXmlV1() { } }