diff options
| author | 2019-10-22 21:25:45 -0700 | |
|---|---|---|
| committer | 2019-10-22 21:42:32 -0700 | |
| commit | 21c82c3ebde50090a57dacac2b06a24c25e4af37 (patch) | |
| tree | eed033c57eeed8ed09b799c2769a0d8ae9c16f7a | |
| parent | 26d4e011de573bb10d267a87071e2cb3d06f9280 (diff) | |
Remove XML write functions from UsageStats.
UsageStats has moved away from XML and is now using protos. This removes
dead XML write functions which should ideally never be triggered. A
warning will be logged when reading XML data and a WTF when some
codepath attempts to write data in XML.
Certain tests are now marked as ignored since the XML write functions are
removed. It was decided to not move those functions into the test context
since the read/write code is so intertwined within the database logic.
Bug: 143187610
Test: atest UsageStatsDatabaseTest
Change-Id: If622b646e0edfe389e49aec9b51accdb9fbf1f45
5 files changed, 51 insertions, 286 deletions
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index ac1cbd4619df..578d08617b5f 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -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; @@ -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. - } } diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java index df0c37a9856c..e32103fe6bff 100644 --- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java +++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java @@ -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; @@ -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; @@ -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(); @@ -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; } @@ -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); @@ -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); @@ -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); diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index db7ed1f58c1a..27d7360313ad 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -373,7 +373,12 @@ public class UsageStatsDatabase { Slog.e(TAG, "Failed read version upgrade breadcrumb"); throw new RuntimeException(e); } - continueUpgradeLocked(previousVersion, token); + if (mCurrentVersion >= 4) { + continueUpgradeLocked(previousVersion, token); + } else { + Slog.wtf(TAG, "Attempting to upgrade to an unsupported version: " + + mCurrentVersion); + } } if (version != mCurrentVersion || mNewUpdate) { @@ -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. @@ -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); } @@ -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 { @@ -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); } @@ -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: - UsageStatsXml.read(in, statsOut); + 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 { @@ -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)) { diff --git a/services/usage/java/com/android/server/usage/UsageStatsXml.java b/services/usage/java/com/android/server/usage/UsageStatsXml.java index f8d1113e8460..3100310368da 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsXml.java +++ b/services/usage/java/com/android/server/usage/UsageStatsXml.java @@ -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; @@ -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"; @@ -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 diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java index 565ca9ed1a00..259873987aef 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java +++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java @@ -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; @@ -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. @@ -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() { } } |