Loading services/core/java/com/android/server/notification/NotificationUsageStats.java +1 −1 Original line number Diff line number Diff line Loading @@ -384,7 +384,7 @@ public class NotificationUsageStats { noisyImportance = new ImportanceHistogram(context, "note_imp_noisy_"); quietImportance = new ImportanceHistogram(context, "note_imp_quiet_"); finalImportance = new ImportanceHistogram(context, "note_importance_"); enqueueRate = new RateEstimator(mCreated); enqueueRate = new RateEstimator(); } public AggregatedStats getPrevious() { Loading services/core/java/com/android/server/notification/RateEstimator.java +22 −9 Original line number Diff line number Diff line Loading @@ -25,30 +25,43 @@ package com.android.server.notification; public class RateEstimator { private static final double RATE_ALPHA = 0.8; private static final double MINIMUM_DT = 0.0005; private long mLastEventTime; private float mInterarrivalTime; private Long mLastEventTime; private Float mInterarrivalTime; public RateEstimator(long now) { mLastEventTime = now; } public RateEstimator() {} /** Update the estimate to account for an event that jsut happened. */ /** Update the estimate to account for an event that just happened. */ public float update(long now) { float rate; if (mLastEventTime == null) { // No last event time, rate is zero. rate = 0f; } else { // Calculate the new inter-arrival time based on last event time. mInterarrivalTime = (float) getInterarrivalEstimate(now); rate = (float) (1.0 / mInterarrivalTime); } mLastEventTime = now; return (float) (1.0 / mInterarrivalTime); return rate; } /** @return the estimated rate if there were a new event right now. */ public float getRate(long now) { if (mLastEventTime == null) { return 0f; } return (float) (1.0 / getInterarrivalEstimate(now)); } /** @return the average inter-arrival time if there were a new event right now. */ private double getInterarrivalEstimate(long now) { // a*iat_old + (1-a)*(t_now-t_last) double dt = ((double) (now - mLastEventTime)) / 1000.0; dt = Math.max(dt, MINIMUM_DT); if (mInterarrivalTime == null) { // No last inter-arrival time, return the new value directly. return dt; } // a*iat_old + (1-a)*(t_now-t_last) return (RATE_ALPHA * mInterarrivalTime + (1.0 - RATE_ALPHA) * dt); } } services/tests/servicestests/src/com/android/server/notification/RateEstimatorTest.java +25 −7 Original line number Diff line number Diff line Loading @@ -26,18 +26,18 @@ public class RateEstimatorTest extends AndroidTestCase { @Override public void setUp() { mTestStartTime = 1225731600000L; mEstimator = new RateEstimator(mTestStartTime); mEstimator = new RateEstimator(); } @SmallTest public void testRunningTimeBackwardDoesntExplodeUpdate() throws Exception { final float rate = mEstimator.update(mTestStartTime - 1000L); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); assertUpdateTime(mTestStartTime); assertUpdateTime(mTestStartTime - 1000L); } @SmallTest public void testRunningTimeBackwardDoesntExplodeGet() throws Exception { assertUpdateTime(mTestStartTime); final float rate = mEstimator.getRate(mTestStartTime - 1000L); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); Loading @@ -45,13 +45,14 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testInstantaneousEventsDontExplodeUpdate() throws Exception { final float rate = mEstimator.update(mTestStartTime); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); assertUpdateTime(mTestStartTime); assertUpdateTime(mTestStartTime); } @SmallTest public void testInstantaneousEventsDontExplodeGet() throws Exception { assertUpdateTime(mTestStartTime); assertUpdateTime(mTestStartTime); final float rate = mEstimator.getRate(mTestStartTime); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); Loading @@ -59,6 +60,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testCompactBurstIsEstimatedUnderTwoPercent() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 1, 5); // five events at 1000Hz final float rate = mEstimator.getRate(nextEventTime); Loading @@ -67,6 +69,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testSustained1000HzBurstIsEstimatedOverNinetyPercent() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 1, 100); // one hundred events at 1000Hz final float rate = mEstimator.getRate(nextEventTime); Loading @@ -75,6 +78,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testSustained100HzBurstIsEstimatedOverNinetyPercent() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 10, 100); // one hundred events at 100Hz final float rate = mEstimator.getRate(nextEventTime); Loading @@ -84,6 +88,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testRecoverQuicklyAfterSustainedBurst() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 10, 1000); // one hundred events at 100Hz final float rate = mEstimator.getRate(nextEventTime + 5000L); // two seconds later Loading @@ -92,12 +97,19 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testEstimateShouldNotOvershoot() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 1, 1000); // one thousand events at 1000Hz final float rate = mEstimator.getRate(nextEventTime); assertLessThan("Rate", rate, 1000f); } @SmallTest public void testGetRateWithoutUpdate() throws Exception { final float rate = mEstimator.getRate(mTestStartTime); assertLessThan("Rate", rate, 0.1f); } private void assertLessThan(String label, float a, float b) { assertTrue(String.format("%s was %f, but should be less than %f", label, a, b), a < b); } Loading @@ -115,4 +127,10 @@ public class RateEstimatorTest extends AndroidTestCase { } return time; } private void assertUpdateTime(long time) { final float rate = mEstimator.update(time); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); } } Loading
services/core/java/com/android/server/notification/NotificationUsageStats.java +1 −1 Original line number Diff line number Diff line Loading @@ -384,7 +384,7 @@ public class NotificationUsageStats { noisyImportance = new ImportanceHistogram(context, "note_imp_noisy_"); quietImportance = new ImportanceHistogram(context, "note_imp_quiet_"); finalImportance = new ImportanceHistogram(context, "note_importance_"); enqueueRate = new RateEstimator(mCreated); enqueueRate = new RateEstimator(); } public AggregatedStats getPrevious() { Loading
services/core/java/com/android/server/notification/RateEstimator.java +22 −9 Original line number Diff line number Diff line Loading @@ -25,30 +25,43 @@ package com.android.server.notification; public class RateEstimator { private static final double RATE_ALPHA = 0.8; private static final double MINIMUM_DT = 0.0005; private long mLastEventTime; private float mInterarrivalTime; private Long mLastEventTime; private Float mInterarrivalTime; public RateEstimator(long now) { mLastEventTime = now; } public RateEstimator() {} /** Update the estimate to account for an event that jsut happened. */ /** Update the estimate to account for an event that just happened. */ public float update(long now) { float rate; if (mLastEventTime == null) { // No last event time, rate is zero. rate = 0f; } else { // Calculate the new inter-arrival time based on last event time. mInterarrivalTime = (float) getInterarrivalEstimate(now); rate = (float) (1.0 / mInterarrivalTime); } mLastEventTime = now; return (float) (1.0 / mInterarrivalTime); return rate; } /** @return the estimated rate if there were a new event right now. */ public float getRate(long now) { if (mLastEventTime == null) { return 0f; } return (float) (1.0 / getInterarrivalEstimate(now)); } /** @return the average inter-arrival time if there were a new event right now. */ private double getInterarrivalEstimate(long now) { // a*iat_old + (1-a)*(t_now-t_last) double dt = ((double) (now - mLastEventTime)) / 1000.0; dt = Math.max(dt, MINIMUM_DT); if (mInterarrivalTime == null) { // No last inter-arrival time, return the new value directly. return dt; } // a*iat_old + (1-a)*(t_now-t_last) return (RATE_ALPHA * mInterarrivalTime + (1.0 - RATE_ALPHA) * dt); } }
services/tests/servicestests/src/com/android/server/notification/RateEstimatorTest.java +25 −7 Original line number Diff line number Diff line Loading @@ -26,18 +26,18 @@ public class RateEstimatorTest extends AndroidTestCase { @Override public void setUp() { mTestStartTime = 1225731600000L; mEstimator = new RateEstimator(mTestStartTime); mEstimator = new RateEstimator(); } @SmallTest public void testRunningTimeBackwardDoesntExplodeUpdate() throws Exception { final float rate = mEstimator.update(mTestStartTime - 1000L); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); assertUpdateTime(mTestStartTime); assertUpdateTime(mTestStartTime - 1000L); } @SmallTest public void testRunningTimeBackwardDoesntExplodeGet() throws Exception { assertUpdateTime(mTestStartTime); final float rate = mEstimator.getRate(mTestStartTime - 1000L); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); Loading @@ -45,13 +45,14 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testInstantaneousEventsDontExplodeUpdate() throws Exception { final float rate = mEstimator.update(mTestStartTime); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); assertUpdateTime(mTestStartTime); assertUpdateTime(mTestStartTime); } @SmallTest public void testInstantaneousEventsDontExplodeGet() throws Exception { assertUpdateTime(mTestStartTime); assertUpdateTime(mTestStartTime); final float rate = mEstimator.getRate(mTestStartTime); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); Loading @@ -59,6 +60,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testCompactBurstIsEstimatedUnderTwoPercent() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 1, 5); // five events at 1000Hz final float rate = mEstimator.getRate(nextEventTime); Loading @@ -67,6 +69,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testSustained1000HzBurstIsEstimatedOverNinetyPercent() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 1, 100); // one hundred events at 1000Hz final float rate = mEstimator.getRate(nextEventTime); Loading @@ -75,6 +78,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testSustained100HzBurstIsEstimatedOverNinetyPercent() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 10, 100); // one hundred events at 100Hz final float rate = mEstimator.getRate(nextEventTime); Loading @@ -84,6 +88,7 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testRecoverQuicklyAfterSustainedBurst() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 10, 1000); // one hundred events at 100Hz final float rate = mEstimator.getRate(nextEventTime + 5000L); // two seconds later Loading @@ -92,12 +97,19 @@ public class RateEstimatorTest extends AndroidTestCase { @SmallTest public void testEstimateShouldNotOvershoot() throws Exception { assertUpdateTime(mTestStartTime); long eventStart = mTestStartTime + 1000; // start event a long time after initialization long nextEventTime = postEvents(eventStart, 1, 1000); // one thousand events at 1000Hz final float rate = mEstimator.getRate(nextEventTime); assertLessThan("Rate", rate, 1000f); } @SmallTest public void testGetRateWithoutUpdate() throws Exception { final float rate = mEstimator.getRate(mTestStartTime); assertLessThan("Rate", rate, 0.1f); } private void assertLessThan(String label, float a, float b) { assertTrue(String.format("%s was %f, but should be less than %f", label, a, b), a < b); } Loading @@ -115,4 +127,10 @@ public class RateEstimatorTest extends AndroidTestCase { } return time; } private void assertUpdateTime(long time) { final float rate = mEstimator.update(time); assertFalse(Float.isInfinite(rate)); assertFalse(Float.isNaN(rate)); } }