Merge "Avoid using stale sessions for cleanup alarm." into sc-dev
This commit is contained in:
@@ -1502,13 +1502,14 @@ public final class QuotaController extends StateController {
|
|||||||
/** Schedule a cleanup alarm if necessary and there isn't already one scheduled. */
|
/** Schedule a cleanup alarm if necessary and there isn't already one scheduled. */
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void maybeScheduleCleanupAlarmLocked() {
|
void maybeScheduleCleanupAlarmLocked() {
|
||||||
if (mNextCleanupTimeElapsed > sElapsedRealtimeClock.millis()) {
|
final long nowElapsed = sElapsedRealtimeClock.millis();
|
||||||
|
if (mNextCleanupTimeElapsed > nowElapsed) {
|
||||||
// There's already an alarm scheduled. Just stick with that one. There's no way we'll
|
// There's already an alarm scheduled. Just stick with that one. There's no way we'll
|
||||||
// end up scheduling an earlier alarm.
|
// end up scheduling an earlier alarm.
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.v(TAG, "Not scheduling cleanup since there's already one at "
|
Slog.v(TAG, "Not scheduling cleanup since there's already one at "
|
||||||
+ mNextCleanupTimeElapsed + " (in " + (mNextCleanupTimeElapsed
|
+ mNextCleanupTimeElapsed
|
||||||
- sElapsedRealtimeClock.millis()) + "ms)");
|
+ " (in " + (mNextCleanupTimeElapsed - nowElapsed) + "ms)");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1530,7 +1531,7 @@ public final class QuotaController extends StateController {
|
|||||||
if (nextCleanupElapsed - mNextCleanupTimeElapsed <= 10 * MINUTE_IN_MILLIS) {
|
if (nextCleanupElapsed - mNextCleanupTimeElapsed <= 10 * MINUTE_IN_MILLIS) {
|
||||||
// No need to clean up too often. Delay the alarm if the next cleanup would be too soon
|
// No need to clean up too often. Delay the alarm if the next cleanup would be too soon
|
||||||
// after it.
|
// after it.
|
||||||
nextCleanupElapsed += 10 * MINUTE_IN_MILLIS;
|
nextCleanupElapsed = mNextCleanupTimeElapsed + 10 * MINUTE_IN_MILLIS;
|
||||||
}
|
}
|
||||||
mNextCleanupTimeElapsed = nextCleanupElapsed;
|
mNextCleanupTimeElapsed = nextCleanupElapsed;
|
||||||
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextCleanupElapsed, ALARM_TAG_CLEANUP,
|
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextCleanupElapsed, ALARM_TAG_CLEANUP,
|
||||||
@@ -2478,30 +2479,60 @@ public final class QuotaController extends StateController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class DeleteTimingSessionsFunctor implements Consumer<List<TimingSession>> {
|
private static final class TimingSessionTooOldPredicate implements Predicate<TimingSession> {
|
||||||
private final Predicate<TimingSession> mTooOld = new Predicate<TimingSession>() {
|
private long mNowElapsed;
|
||||||
public boolean test(TimingSession ts) {
|
|
||||||
return ts.endTimeElapsed <= sElapsedRealtimeClock.millis() - MAX_PERIOD_MS;
|
private void updateNow() {
|
||||||
}
|
mNowElapsed = sElapsedRealtimeClock.millis();
|
||||||
};
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(List<TimingSession> sessions) {
|
public boolean test(TimingSession ts) {
|
||||||
if (sessions != null) {
|
return ts.endTimeElapsed <= mNowElapsed - MAX_PERIOD_MS;
|
||||||
// Remove everything older than MAX_PERIOD_MS time ago.
|
|
||||||
sessions.removeIf(mTooOld);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final DeleteTimingSessionsFunctor mDeleteOldSessionsFunctor =
|
private final TimingSessionTooOldPredicate mTimingSessionTooOld =
|
||||||
new DeleteTimingSessionsFunctor();
|
new TimingSessionTooOldPredicate();
|
||||||
|
|
||||||
|
private final Consumer<List<TimingSession>> mDeleteOldSessionsFunctor = sessions -> {
|
||||||
|
if (sessions != null) {
|
||||||
|
// Remove everything older than MAX_PERIOD_MS time ago.
|
||||||
|
sessions.removeIf(mTimingSessionTooOld);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void deleteObsoleteSessionsLocked() {
|
void deleteObsoleteSessionsLocked() {
|
||||||
|
mTimingSessionTooOld.updateNow();
|
||||||
|
|
||||||
|
// Regular sessions
|
||||||
mTimingSessions.forEach(mDeleteOldSessionsFunctor);
|
mTimingSessions.forEach(mDeleteOldSessionsFunctor);
|
||||||
// Don't delete EJ timing sessions here. They'll be removed in
|
|
||||||
// getRemainingEJExecutionTimeLocked().
|
// EJ sessions
|
||||||
|
for (int uIdx = 0; uIdx < mEJTimingSessions.numMaps(); ++uIdx) {
|
||||||
|
final int userId = mEJTimingSessions.keyAt(uIdx);
|
||||||
|
for (int pIdx = 0; pIdx < mEJTimingSessions.numElementsForKey(userId); ++pIdx) {
|
||||||
|
final String packageName = mEJTimingSessions.keyAt(uIdx, pIdx);
|
||||||
|
final ShrinkableDebits debits = getEJDebitsLocked(userId, packageName);
|
||||||
|
final List<TimingSession> sessions = mEJTimingSessions.get(userId, packageName);
|
||||||
|
if (sessions == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sessions.size() > 0) {
|
||||||
|
final TimingSession ts = sessions.get(0);
|
||||||
|
if (mTimingSessionTooOld.test(ts)) {
|
||||||
|
// Stale sessions may still be factored into tally. Remove them.
|
||||||
|
final long duration = ts.endTimeElapsed - ts.startTimeElapsed;
|
||||||
|
debits.transactLocked(-duration);
|
||||||
|
sessions.remove(0);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class QcHandler extends Handler {
|
private class QcHandler extends Handler {
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.IPackageManager;
|
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManagerInternal;
|
import android.content.pm.PackageManagerInternal;
|
||||||
@@ -475,7 +474,6 @@ public class QuotaControllerTest {
|
|||||||
expectedRegular.add(thr);
|
expectedRegular.add(thr);
|
||||||
expectedRegular.add(two);
|
expectedRegular.add(two);
|
||||||
expectedRegular.add(one);
|
expectedRegular.add(one);
|
||||||
expectedEJ.add(fiv); // EJ list should be unaffected
|
|
||||||
expectedEJ.add(fou);
|
expectedEJ.add(fou);
|
||||||
expectedEJ.add(one);
|
expectedEJ.add(one);
|
||||||
mQuotaController.saveTimingSession(0, "com.android.test", fiv, false);
|
mQuotaController.saveTimingSession(0, "com.android.test", fiv, false);
|
||||||
|
|||||||
Reference in New Issue
Block a user