diff options
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() { } } |