From 16b2f2beb3663599d160a5a6d2a87ce63f372291 Mon Sep 17 00:00:00 2001 From: Michael Wachenschwanz Date: Wed, 9 Oct 2019 15:32:55 -0700 Subject: [PATCH] Ignore null package names on AppIdleHistory writes AppIdleHistory will fail to persist to disk if a null package name makes it into the map. This change avoids the failure and adds more detail to the log in the event of a failure. Test: atest AppIdleHistoryTests Bug: 122609407 Change-Id: Ifec5a14f488fdb425bdcfee6ffe1f48f9fa9d1e8 --- .../android/server/usage/AppIdleHistory.java | 9 +++++++-- .../server/usage/AppIdleHistoryTests.java | 18 +++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java index 1e4861a896940..82292cfeea09a 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java @@ -578,7 +578,7 @@ public class AppIdleHistory { } } } catch (IOException | XmlPullParserException e) { - Slog.e(TAG, "Unable to read app idle file for user " + userId); + Slog.e(TAG, "Unable to read app idle file for user " + userId, e); } finally { IoUtils.closeQuietly(fis); } @@ -608,6 +608,11 @@ public class AppIdleHistory { final int N = userHistory.size(); for (int i = 0; i < N; i++) { String packageName = userHistory.keyAt(i); + // Skip any unexpected null package names + if (packageName == null) { + Slog.w(TAG, "Skipping App Idle write for unexpected null package"); + continue; + } AppUsageHistory history = userHistory.valueAt(i); xml.startTag(null, TAG_PACKAGE); xml.attribute(null, ATTR_NAME, packageName); @@ -641,7 +646,7 @@ public class AppIdleHistory { appIdleFile.finishWrite(fos); } catch (Exception e) { appIdleFile.failWrite(fos); - Slog.e(TAG, "Error writing app idle file for user " + userId); + Slog.e(TAG, "Error writing app idle file for user " + userId, e); } } diff --git a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java index 36504ac7ec656..4a13dce5642ba 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java @@ -28,7 +28,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import android.app.usage.UsageStatsManager; import android.os.FileUtils; import android.test.AndroidTestCase; @@ -150,4 +149,21 @@ public class AppIdleHistoryTests extends AndroidTestCase { aih = new AppIdleHistory(mStorageDir, 5000); assertEquals(REASON_MAIN_TIMEOUT, aih.getAppStandbyReason(PACKAGE_1, USER_ID, 5000)); } + + public void testNullPackage() throws Exception { + AppIdleHistory aih = new AppIdleHistory(mStorageDir, 1000); + // Report usage of a package + aih.reportUsage(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE, + REASON_SUB_USAGE_MOVE_TO_FOREGROUND, 2000, 0); + // "Accidentally" report usage against a null named package + aih.reportUsage(null, USER_ID, STANDBY_BUCKET_ACTIVE, + REASON_SUB_USAGE_MOVE_TO_FOREGROUND, 2000, 0); + // Persist data + aih.writeAppIdleTimes(USER_ID); + // Recover data from disk + aih = new AppIdleHistory(mStorageDir, 5000); + // Verify data is intact + assertEquals(REASON_MAIN_USAGE | REASON_SUB_USAGE_MOVE_TO_FOREGROUND, + aih.getAppStandbyReason(PACKAGE_1, USER_ID, 3000)); + } } \ No newline at end of file