blob: e2c12bba489503daa534a31637fc6ebb46baa6bc [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.watchdog;
import static android.car.watchdog.PackageKillableState.KILLABLE_STATE_NEVER;
import static android.car.watchdog.PackageKillableState.KILLABLE_STATE_NO;
import static android.car.watchdog.PackageKillableState.KILLABLE_STATE_YES;
import static com.android.car.watchdog.WatchdogStorage.RETENTION_PERIOD;
import static com.android.car.watchdog.WatchdogStorage.STATS_TEMPORAL_UNIT;
import static com.android.car.watchdog.WatchdogStorage.WatchdogDbHelper.DATABASE_NAME;
import static com.android.car.watchdog.WatchdogStorage.ZONE_OFFSET;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.automotive.watchdog.PerStateBytes;
import android.car.watchdog.IoOveruseStats;
import android.content.Context;
import android.util.Slog;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* <p>This class contains unit tests for the {@link WatchdogStorage}.
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
public final class WatchdogStorageUnitTest {
private static final String TAG = WatchdogStorageUnitTest.class.getSimpleName();
private WatchdogStorage mService;
private File mDatabaseFile;
private TimeSourceInterface mTimeSource;
@Before
public void setUp() throws Exception {
Context context = InstrumentationRegistry.getTargetContext();
mDatabaseFile = context.createDeviceProtectedStorageContext()
.getDatabasePath(DATABASE_NAME);
mService = new WatchdogStorage(context, /* useDataSystemCarDir= */ false);
setDate(/* numDaysAgo= */ 0);
}
@After
public void tearDown() {
mService.release();
if (!mDatabaseFile.delete()) {
Slog.e(TAG, "Failed to delete the database file: " + mDatabaseFile.getAbsolutePath());
}
}
@Test
public void testSaveUserPackageSettings() throws Exception {
List<WatchdogStorage.UserPackageSettingsEntry> expected = sampleSettings();
assertThat(mService.saveUserPackageSettings(expected)).isTrue();
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(expected);
}
@Test
public void testOverwriteUserPackageSettings() throws Exception {
List<WatchdogStorage.UserPackageSettingsEntry> expected = Arrays.asList(
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 100, "system_package.non_critical.A", KILLABLE_STATE_YES),
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 100, "system_package.non_critical.B", KILLABLE_STATE_NO));
assertThat(mService.saveUserPackageSettings(expected)).isTrue();
expected = Arrays.asList(
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 100, "system_package.non_critical.A", KILLABLE_STATE_NEVER),
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 100, "system_package.non_critical.B", KILLABLE_STATE_NO));
assertThat(mService.saveUserPackageSettings(expected)).isTrue();
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(expected);
}
@Test
public void testSaveAndGetIoOveruseStats() throws Exception {
injectSampleUserPackageSettings();
/* Start time aligned to the beginning of the day. */
long startTime = mTimeSource.now().atZone(ZONE_OFFSET).truncatedTo(STATS_TEMPORAL_UNIT)
.toEpochSecond();
assertWithMessage("Saved I/O usage stats successfully")
.that(mService.saveIoUsageStats(sampleStatsForDate(startTime, /* duration= */ 60)))
.isTrue();
long expectedDuration =
mTimeSource.now().atZone(ZONE_OFFSET).toEpochSecond() - startTime;
List<WatchdogStorage.IoUsageStatsEntry> expected = sampleStatsForDate(
startTime, expectedDuration);
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(expected);
}
@Test
public void testSaveAndGetIoOveruseStatsWithOffsettedStartTime() throws Exception {
injectSampleUserPackageSettings();
/* Start time in the middle of the day. */
long startTime = mTimeSource.now().atZone(ZONE_OFFSET).truncatedTo(STATS_TEMPORAL_UNIT)
.plusHours(12).toEpochSecond();
List<WatchdogStorage.IoUsageStatsEntry> entries = sampleStatsForDate(
startTime, /* duration= */ 60);
assertWithMessage("Saved I/O usage stats successfully")
.that(mService.saveIoUsageStats(entries)).isTrue();
long expectedStartTime = mTimeSource.now().atZone(ZONE_OFFSET)
.truncatedTo(STATS_TEMPORAL_UNIT).toEpochSecond();
long expectedDuration =
mTimeSource.now().atZone(ZONE_OFFSET).toEpochSecond() - expectedStartTime;
List<WatchdogStorage.IoUsageStatsEntry> expected = sampleStatsForDate(
expectedStartTime, expectedDuration);
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(expected);
}
@Test
public void testOverwriteIoOveruseStats() throws Exception {
injectSampleUserPackageSettings();
long startTime = mTimeSource.now().atZone(ZONE_OFFSET).truncatedTo(STATS_TEMPORAL_UNIT)
.toEpochSecond();
long duration = mTimeSource.now().atZone(ZONE_OFFSET).toEpochSecond() - startTime;
List<WatchdogStorage.IoUsageStatsEntry> expected = Collections.singletonList(
constructIoUsageStatsEntry(
/* userId= */ 100, "system_package.non_critical.A", startTime, duration,
/* remainingWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(200, 300, 400),
/* writtenBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(1000, 2000, 3000),
/* forgivenWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(100, 100, 100),
/* totalOveruses= */ 2, /* totalTimesKilled= */ 1));
assertWithMessage("Saved I/O usage stats successfully")
.that(mService.saveIoUsageStats(expected)).isTrue();
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(expected);
expected = Collections.singletonList(
constructIoUsageStatsEntry(
/* userId= */ 100, "system_package.non_critical.A", startTime, duration,
/* remainingWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(400, 600, 800),
/* writtenBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(2000, 3000, 4000),
/* forgivenWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(1200, 2300, 3400),
/* totalOveruses= */ 4, /* totalTimesKilled= */ 2));
assertWithMessage("Saved I/O usage stats successfully")
.that(mService.saveIoUsageStats(expected)).isTrue();
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(expected);
}
@Test
public void testSaveIoOveruseStatsOutsideRetentionPeriod() throws Exception {
injectSampleUserPackageSettings();
int retentionDaysAgo = RETENTION_PERIOD.getDays();
assertWithMessage("Saved I/O usage stats successfully")
.that(mService.saveIoUsageStats(sampleStatsBetweenDates(
/* includingStartDaysAgo= */ retentionDaysAgo,
/* excludingEndDaysAgo= */ retentionDaysAgo + 1))).isTrue();
assertWithMessage("Didn't fetch I/O overuse stats outside retention period")
.that(mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "system_package.non_critical.A", retentionDaysAgo))
.isNull();
}
@Test
public void testGetHistoricalIoOveruseStats() throws Exception {
injectSampleUserPackageSettings();
assertThat(mService.saveIoUsageStats(sampleStatsBetweenDates(
/* includingStartDaysAgo= */ 0, /* excludingEndDaysAgo= */ 5))).isTrue();
IoOveruseStats actual = mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "system_package.non_critical.A", /* numDaysAgo= */ 7);
assertWithMessage("Fetched I/O overuse stats").that(actual).isNotNull();
/*
* Returned stats shouldn't include stats for the current date as WatchdogPerfHandler fills
* the current day's stats.
*/
ZonedDateTime currentDate = mTimeSource.now().atZone(ZONE_OFFSET)
.truncatedTo(STATS_TEMPORAL_UNIT);
long startTime = currentDate.minus(4, STATS_TEMPORAL_UNIT).toEpochSecond();
long duration = currentDate.toEpochSecond() - startTime;
IoOveruseStats expected = new IoOveruseStats.Builder(startTime, duration)
.setTotalOveruses(8).setTotalTimesKilled(4).setTotalBytesWritten(24_000).build();
IoOveruseStatsSubject.assertWithMessage(
"Fetched stats only for 4 days. Expected stats (%s) equals actual stats (%s)",
expected.toString(), actual.toString()).that(actual)
.isEqualTo(expected);
}
@Test
public void testGetHistoricalIoOveruseStatsWithNoRecentStats() throws Exception {
injectSampleUserPackageSettings();
assertThat(mService.saveIoUsageStats(sampleStatsBetweenDates(
/* includingStartDaysAgo= */ 3, /* excludingEndDaysAgo= */ 5))).isTrue();
IoOveruseStats actual = mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "system_package.non_critical.A", /* numDaysAgo= */ 7);
assertWithMessage("Fetched I/O overuse stats").that(actual).isNotNull();
/*
* Returned stats shouldn't include stats for the current date as WatchdogPerfHandler fills
* the current day's stats.
*/
ZonedDateTime currentDate = mTimeSource.now().atZone(ZONE_OFFSET)
.truncatedTo(STATS_TEMPORAL_UNIT);
long startTime = currentDate.minus(4, STATS_TEMPORAL_UNIT).toEpochSecond();
long duration = currentDate.toEpochSecond() - startTime;
IoOveruseStats expected = new IoOveruseStats.Builder(startTime, duration)
.setTotalOveruses(4).setTotalTimesKilled(2).setTotalBytesWritten(12_000).build();
IoOveruseStatsSubject.assertWithMessage(
"Fetched stats only for 2 days. Expected stats (%s) equals actual stats (%s)",
expected.toString(), actual.toString()).that(actual)
.isEqualTo(expected);
}
@Test
public void testDeleteUserPackage() throws Exception {
ArrayList<WatchdogStorage.UserPackageSettingsEntry> settingsEntries = sampleSettings();
List<WatchdogStorage.IoUsageStatsEntry> ioUsageStatsEntries = sampleStatsForToday();
assertThat(mService.saveUserPackageSettings(settingsEntries)).isTrue();
assertThat(mService.saveIoUsageStats(ioUsageStatsEntries)).isTrue();
int deleteUserId = 100;
String deletePackageName = "system_package.non_critical.A";
mService.deleteUserPackage(deleteUserId, deletePackageName);
settingsEntries.removeIf(
(s) -> s.userId == deleteUserId && s.packageName.equals(deletePackageName));
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(settingsEntries);
ioUsageStatsEntries.removeIf(
(e) -> e.userId == deleteUserId && e.packageName.equals(deletePackageName));
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(ioUsageStatsEntries);
}
@Test
public void testDeleteUserPackageWithNonexistentPackage() throws Exception {
injectSampleUserPackageSettings();
List<WatchdogStorage.IoUsageStatsEntry> ioUsageStatsEntries = sampleStatsForToday();
assertThat(mService.saveIoUsageStats(ioUsageStatsEntries)).isTrue();
int deleteUserId = 100;
String deletePackageName = "system_package.non_existent.A";
mService.deleteUserPackage(deleteUserId, deletePackageName);
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(sampleSettings());
ioUsageStatsEntries.removeIf(
(e) -> e.userId == deleteUserId && e.packageName.equals(deletePackageName));
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(ioUsageStatsEntries);
}
@Test
public void testDeleteUserPackageWithHistoricalIoOveruseStats()
throws Exception {
ArrayList<WatchdogStorage.UserPackageSettingsEntry> settingsEntries = sampleSettings();
assertThat(mService.saveUserPackageSettings(settingsEntries)).isTrue();
assertThat(mService.saveIoUsageStats(sampleStatsBetweenDates(
/* includingStartDaysAgo= */ 1, /* excludingEndDaysAgo= */ 6))).isTrue();
int deleteUserId = 100;
String deletePackageName = "system_package.non_critical.A";
mService.deleteUserPackage(deleteUserId, deletePackageName);
settingsEntries.removeIf(
(s) -> s.userId == deleteUserId && s.packageName.equals(deletePackageName));
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(settingsEntries);
IoOveruseStats actual = mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "system_package.non_critical.A", /* numDaysAgo= */ 7);
assertWithMessage("Fetched historical I/O overuse stats").that(actual).isNull();
}
@Test
public void testSyncUsers() throws Exception {
List<WatchdogStorage.UserPackageSettingsEntry> settingsEntries = sampleSettings();
List<WatchdogStorage.IoUsageStatsEntry> ioUsageStatsEntries = sampleStatsForToday();
assertThat(mService.saveUserPackageSettings(settingsEntries)).isTrue();
assertThat(mService.saveIoUsageStats(ioUsageStatsEntries)).isTrue();
mService.syncUsers(/* aliveUserIds= */ new int[] {101});
settingsEntries.removeIf((s) -> s.userId == 100);
ioUsageStatsEntries.removeIf((e) -> e.userId == 100);
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(settingsEntries);
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(ioUsageStatsEntries);
}
@Test
public void testSyncUsersWithHistoricalIoOveruseStats() throws Exception {
List<WatchdogStorage.UserPackageSettingsEntry> settingsEntries = sampleSettings();
assertThat(mService.saveUserPackageSettings(settingsEntries)).isTrue();
assertThat(mService.saveIoUsageStats(sampleStatsBetweenDates(
/* includingStartDaysAgo= */ 1, /* excludingEndDaysAgo= */ 6))).isTrue();
mService.syncUsers(/* aliveUserIds= */ new int[] {101});
settingsEntries.removeIf((s) -> s.userId == 100);
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(settingsEntries);
IoOveruseStats actualSystemPackage = mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "system_package.non_critical.A", /* numDaysAgo= */ 7);
IoOveruseStats actualVendorPackage = mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "vendor_package.critical.C", /* numDaysAgo= */ 7);
assertWithMessage("System I/O overuse stats for deleted user")
.that(actualSystemPackage).isNull();
assertWithMessage("Vendor I/O overuse stats for deleted user")
.that(actualVendorPackage).isNull();
}
@Test
public void testSyncUsersWithNoDataForDeletedUser() throws Exception {
List<WatchdogStorage.UserPackageSettingsEntry> settingsEntries = sampleSettings();
List<WatchdogStorage.IoUsageStatsEntry> ioUsageStatsEntries = sampleStatsForToday();
assertThat(mService.saveUserPackageSettings(settingsEntries)).isTrue();
assertThat(mService.saveIoUsageStats(ioUsageStatsEntries)).isTrue();
mService.syncUsers(/* aliveUserIds= */ new int[] {100, 101});
UserPackageSettingsEntrySubject.assertThat(mService.getUserPackageSettings())
.containsExactlyElementsIn(settingsEntries);
IoUsageStatsEntrySubject.assertThat(mService.getTodayIoUsageStats())
.containsExactlyElementsIn(ioUsageStatsEntries);
}
@Test
public void testTruncateStatsOutsideRetentionPeriodOnDateChange() throws Exception {
injectSampleUserPackageSettings();
setDate(/* numDaysAgo= */ 1);
assertThat(mService.saveIoUsageStats(sampleStatsBetweenDates(
/* includingStartDaysAgo= */ 0, /* excludingEndDaysAgo= */ 40),
/* shouldCheckRetention= */ false)).isTrue();
IoOveruseStats actual = mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "system_package.non_critical.A", /* numDaysAgo= */ 40);
assertWithMessage("Fetched I/O overuse stats").that(actual).isNotNull();
ZonedDateTime currentDate = mTimeSource.now().atZone(ZONE_OFFSET)
.truncatedTo(STATS_TEMPORAL_UNIT);
long startTime = currentDate.minus(39, STATS_TEMPORAL_UNIT).toEpochSecond();
long duration = currentDate.toEpochSecond() - startTime;
IoOveruseStats expected = new IoOveruseStats.Builder(startTime, duration)
.setTotalOveruses(78).setTotalTimesKilled(39).setTotalBytesWritten(234_000).build();
IoOveruseStatsSubject.assertWithMessage(
"Fetched stats only for 39 days. Expected stats (%s) equals actual stats (%s)",
expected.toString(), actual.toString()).that(actual)
.isEqualTo(expected);
setDate(/* numDaysAgo= */ 0);
mService.shrinkDatabase();
actual = mService.getHistoricalIoOveruseStats(
/* userId= */ 100, "system_package.non_critical.A", /* numDaysAgo= */ 40);
assertWithMessage("Fetched I/O overuse stats").that(actual).isNotNull();
currentDate = mTimeSource.now().atZone(ZONE_OFFSET).truncatedTo(STATS_TEMPORAL_UNIT);
startTime = currentDate.minus(RETENTION_PERIOD.minusDays(1)).toEpochSecond();
duration = currentDate.toEpochSecond() - startTime;
expected = new IoOveruseStats.Builder(startTime, duration)
.setTotalOveruses(58).setTotalTimesKilled(29).setTotalBytesWritten(174_000).build();
IoOveruseStatsSubject.assertWithMessage("Fetched stats only within retention period. "
+ "Expected stats (%s) equals actual stats (%s)",
expected.toString(), actual.toString()).that(actual).isEqualTo(expected);
}
private void setDate(int numDaysAgo) {
TimeSourceInterface timeSource = new TimeSourceInterface() {
@Override
public Instant now() {
/* Return the same time, so the tests are deterministic. */
return mNow;
}
@Override
public String toString() {
return "Mocked date to " + now();
}
private final Instant mNow = Instant.now().minus(numDaysAgo, ChronoUnit.DAYS);
};
mService.setTimeSource(timeSource);
mTimeSource = timeSource;
}
private void injectSampleUserPackageSettings() throws Exception {
List<WatchdogStorage.UserPackageSettingsEntry> expected = sampleSettings();
assertThat(mService.saveUserPackageSettings(expected)).isTrue();
}
private static ArrayList<WatchdogStorage.UserPackageSettingsEntry> sampleSettings() {
return new ArrayList<>(Arrays.asList(
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 100, "system_package.non_critical.A", KILLABLE_STATE_YES),
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 100, "system_package.non_critical.B", KILLABLE_STATE_NO),
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 100, "vendor_package.critical.C", KILLABLE_STATE_NEVER),
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 101, "system_package.non_critical.A", KILLABLE_STATE_NO),
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 101, "system_package.non_critical.B", KILLABLE_STATE_YES),
new WatchdogStorage.UserPackageSettingsEntry(
/* userId= */ 101, "vendor_package.critical.C", KILLABLE_STATE_NEVER)));
}
private ArrayList<WatchdogStorage.IoUsageStatsEntry> sampleStatsBetweenDates(
int includingStartDaysAgo, int excludingEndDaysAgo) {
ZonedDateTime currentDate = mTimeSource.now().atZone(ZONE_OFFSET)
.truncatedTo(STATS_TEMPORAL_UNIT);
ArrayList<WatchdogStorage.IoUsageStatsEntry> entries = new ArrayList<>();
for (int i = includingStartDaysAgo; i < excludingEndDaysAgo; ++i) {
entries.addAll(sampleStatsForDate(
currentDate.minus(i, STATS_TEMPORAL_UNIT).toEpochSecond(),
STATS_TEMPORAL_UNIT.getDuration().toSeconds()));
}
return entries;
}
private ArrayList<WatchdogStorage.IoUsageStatsEntry> sampleStatsForToday() {
long currentTime = mTimeSource.now().atZone(ZONE_OFFSET)
.truncatedTo(STATS_TEMPORAL_UNIT).toEpochSecond();
long duration = mTimeSource.now().atZone(ZONE_OFFSET).toEpochSecond() - currentTime;
return sampleStatsForDate(currentTime, duration);
}
private static ArrayList<WatchdogStorage.IoUsageStatsEntry> sampleStatsForDate(
long statsDateEpoch, long duration) {
ArrayList<WatchdogStorage.IoUsageStatsEntry> entries = new ArrayList<>();
for (int i = 100; i <= 101; ++i) {
entries.add(constructIoUsageStatsEntry(
/* userId= */ i, "system_package.non_critical.A", statsDateEpoch, duration,
/* remainingWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(200, 300, 400),
/* writtenBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(1000, 2000, 3000),
/* forgivenWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(100, 100, 100),
/* totalOveruses= */ 2, /* totalTimesKilled= */ 1));
entries.add(constructIoUsageStatsEntry(
/* userId= */ i, "vendor_package.critical.C", statsDateEpoch, duration,
/* remainingWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(500, 600, 700),
/* writtenBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(4000, 5000, 6000),
/* forgivenWriteBytes= */
CarWatchdogServiceUnitTest.constructPerStateBytes(200, 200, 200),
/* totalOveruses= */ 1, /* totalTimesKilled= */ 0));
}
return entries;
}
private static WatchdogStorage.IoUsageStatsEntry constructIoUsageStatsEntry(
int userId, String packageName, long startTime, long duration,
PerStateBytes remainingWriteBytes, PerStateBytes writtenBytes,
PerStateBytes forgivenWriteBytes, int totalOveruses, int totalTimesKilled) {
WatchdogPerfHandler.PackageIoUsage ioUsage = new WatchdogPerfHandler.PackageIoUsage(
constructInternalIoOveruseStats(startTime, duration, remainingWriteBytes,
writtenBytes, totalOveruses), forgivenWriteBytes, totalTimesKilled);
return new WatchdogStorage.IoUsageStatsEntry(userId, packageName, ioUsage);
}
private static android.automotive.watchdog.IoOveruseStats constructInternalIoOveruseStats(
long startTime, long duration, PerStateBytes remainingWriteBytes,
PerStateBytes writtenBytes, int totalOveruses) {
android.automotive.watchdog.IoOveruseStats stats =
new android.automotive.watchdog.IoOveruseStats();
stats.startTime = startTime;
stats.durationInSeconds = duration;
stats.remainingWriteBytes = remainingWriteBytes;
stats.writtenBytes = writtenBytes;
stats.totalOveruses = totalOveruses;
return stats;
}
}