1 package com.android.bluetooth.tests;
2 
3 import java.util.ArrayList;
4 
5 /**
6  * Class for collecting test results, and presenting them in different formats.
7  * @author cbonde
8  *
9  */
10 public class TestResultLogger implements IResultLogger {
11 
12     private ArrayList<Result> mResults;
13 
14     private class Result {
15         public long timeStamp; // ms precision Unix Time UTC.
16         public long receivedBytes;
Result(long t, long b)17         public Result(long t, long b) {
18             timeStamp = t;
19             receivedBytes = b;
20         }
21     }
22 
TestResultLogger()23     private TestResultLogger() {
24         mResults = new ArrayList<Result>(1000);
25     }
26 
createLogger()27     public static IResultLogger createLogger(){
28         return new TestResultLogger();
29     }
30 
31     @Override
addResult(long bytesTransfered)32     public void addResult(long bytesTransfered) {
33         mResults.add(new Result(System.currentTimeMillis(), bytesTransfered));
34     }
35 
36     @Override
getAverageSpeed()37     public int getAverageSpeed() {
38         if(mResults.size() < 1){
39             return 0;
40         }
41         Result first = mResults.get(0);
42         Result last = mResults.get(mResults.size()-1);
43         // Multiply by 1000 to convert from ms to sec without loss
44         // of precision.
45         return (int) ((1000*(last.receivedBytes + first.receivedBytes))/
46                 (last.timeStamp - first.timeStamp+1));
47     }
48 
49     /**
50      * Optimized to perform best when period is closest to the last
51      * result entry.
52      * If the period does not match a log entry, an estimate will be made
53      * to compensate.
54      * If the result log does not contain data to cover the entire period
55      * the resulting value will represent the average speed of the content
56      * in the log.
57      */
58     @Override
getAverageSpeed(long period)59     public int getAverageSpeed(long period) {
60         Result preFirst = null;
61         Result first = mResults.get(0);
62         int i = mResults.size()-1;
63         Result last = mResults.get(i--);
64         long firstTimeStamp = last.timeStamp - period;
65         if(first.timeStamp > firstTimeStamp || mResults.size() < 3) {
66             // Not enough data, use total average
67             return getAverageSpeed();
68         }
69         for(; i >= 0 ; i--) {
70             preFirst = mResults.get(i);
71             if(preFirst.timeStamp < firstTimeStamp) {
72                 first = mResults.get(i+1);
73                 break;
74             }
75         }
76         long timeError = period - (last.timeStamp-first.timeStamp);
77         long errorBytes = 0;
78         if(timeError > 0) {
79             // Find the amount of bytes to use for correction
80             errorBytes = (timeError*(preFirst.receivedBytes - first.receivedBytes))
81                             /(preFirst.timeStamp - first.timeStamp+1);
82         }
83         // Calculate the result
84         return (int) ((1000*(errorBytes+last.receivedBytes-first.receivedBytes))/period);
85     }
86 
87 
88 }
89