1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.net.impl; 6 7 import androidx.annotation.Nullable; 8 import androidx.annotation.VisibleForTesting; 9 10 import org.chromium.net.RequestFinishedInfo; 11 12 import java.util.Date; 13 14 /** Implementation of {@link RequestFinishedInfo.Metrics}. */ 15 @VisibleForTesting 16 public final class CronetMetrics extends RequestFinishedInfo.Metrics { 17 private final long mRequestStartMs; 18 private final long mDnsStartMs; 19 private final long mDnsEndMs; 20 private final long mConnectStartMs; 21 private final long mConnectEndMs; 22 private final long mSslStartMs; 23 private final long mSslEndMs; 24 private final long mSendingStartMs; 25 private final long mSendingEndMs; 26 private final long mPushStartMs; 27 private final long mPushEndMs; 28 private final long mResponseStartMs; 29 private final long mRequestEndMs; 30 private final boolean mSocketReused; 31 32 // TODO(mgersh): Delete after the switch to the new API http://crbug.com/629194 33 @Nullable private final Long mTtfbMs; 34 // TODO(mgersh): Delete after the switch to the new API http://crbug.com/629194 35 @Nullable private final Long mTotalTimeMs; 36 @Nullable private final Long mSentByteCount; 37 @Nullable private final Long mReceivedByteCount; 38 39 @Nullable toDate(long timestamp)40 private static Date toDate(long timestamp) { 41 if (timestamp != -1) { 42 return new Date(timestamp); 43 } 44 return null; 45 } 46 checkOrder(long start, long end)47 private static boolean checkOrder(long start, long end) { 48 // If end doesn't exist, start can be anything, including also not existing 49 // If end exists, start must also exist and be before end 50 return (end >= start && start != -1) || end == -1; 51 } 52 53 /** 54 * Old-style constructor 55 * TODO(mgersh): Delete after the switch to the new API http://crbug.com/629194 56 */ CronetMetrics( @ullable Long ttfbMs, @Nullable Long totalTimeMs, @Nullable Long sentByteCount, @Nullable Long receivedByteCount)57 public CronetMetrics( 58 @Nullable Long ttfbMs, 59 @Nullable Long totalTimeMs, 60 @Nullable Long sentByteCount, 61 @Nullable Long receivedByteCount) { 62 mTtfbMs = ttfbMs; 63 mTotalTimeMs = totalTimeMs; 64 mSentByteCount = sentByteCount; 65 mReceivedByteCount = receivedByteCount; 66 67 // Everything else is -1 (translates to null) for now 68 mRequestStartMs = -1; 69 mDnsStartMs = -1; 70 mDnsEndMs = -1; 71 mConnectStartMs = -1; 72 mConnectEndMs = -1; 73 mSslStartMs = -1; 74 mSslEndMs = -1; 75 mSendingStartMs = -1; 76 mSendingEndMs = -1; 77 mPushStartMs = -1; 78 mPushEndMs = -1; 79 mResponseStartMs = -1; 80 mRequestEndMs = -1; 81 mSocketReused = false; 82 } 83 84 /** New-style constructor */ CronetMetrics( long requestStartMs, long dnsStartMs, long dnsEndMs, long connectStartMs, long connectEndMs, long sslStartMs, long sslEndMs, long sendingStartMs, long sendingEndMs, long pushStartMs, long pushEndMs, long responseStartMs, long requestEndMs, boolean socketReused, long sentByteCount, long receivedByteCount)85 public CronetMetrics( 86 long requestStartMs, 87 long dnsStartMs, 88 long dnsEndMs, 89 long connectStartMs, 90 long connectEndMs, 91 long sslStartMs, 92 long sslEndMs, 93 long sendingStartMs, 94 long sendingEndMs, 95 long pushStartMs, 96 long pushEndMs, 97 long responseStartMs, 98 long requestEndMs, 99 boolean socketReused, 100 long sentByteCount, 101 long receivedByteCount) { 102 // Check that no end times are before corresponding start times, 103 // or exist when start time doesn't. 104 assert checkOrder(dnsStartMs, dnsEndMs); 105 assert checkOrder(connectStartMs, connectEndMs); 106 assert checkOrder(sslStartMs, sslEndMs); 107 assert checkOrder(sendingStartMs, sendingEndMs); 108 assert checkOrder(pushStartMs, pushEndMs); 109 // requestEnd always exists, so just check that it's after start 110 assert requestEndMs >= responseStartMs; 111 // Spot-check some of the other orderings 112 assert dnsStartMs >= requestStartMs || dnsStartMs == -1; 113 assert sendingStartMs >= requestStartMs || sendingStartMs == -1; 114 assert sslStartMs >= connectStartMs || sslStartMs == -1; 115 assert responseStartMs >= sendingStartMs || responseStartMs == -1; 116 mRequestStartMs = requestStartMs; 117 mDnsStartMs = dnsStartMs; 118 mDnsEndMs = dnsEndMs; 119 mConnectStartMs = connectStartMs; 120 mConnectEndMs = connectEndMs; 121 mSslStartMs = sslStartMs; 122 mSslEndMs = sslEndMs; 123 mSendingStartMs = sendingStartMs; 124 mSendingEndMs = sendingEndMs; 125 mPushStartMs = pushStartMs; 126 mPushEndMs = pushEndMs; 127 mResponseStartMs = responseStartMs; 128 mRequestEndMs = requestEndMs; 129 mSocketReused = socketReused; 130 mSentByteCount = sentByteCount; 131 mReceivedByteCount = receivedByteCount; 132 133 // TODO(mgersh): delete these after embedders stop using them http://crbug.com/629194 134 if (requestStartMs != -1 && responseStartMs != -1) { 135 mTtfbMs = responseStartMs - requestStartMs; 136 } else { 137 mTtfbMs = null; 138 } 139 if (requestStartMs != -1 && requestEndMs != -1) { 140 mTotalTimeMs = requestEndMs - requestStartMs; 141 } else { 142 mTotalTimeMs = null; 143 } 144 } 145 146 @Nullable 147 @Override getRequestStart()148 public Date getRequestStart() { 149 return toDate(mRequestStartMs); 150 } 151 152 @Nullable 153 @Override getDnsStart()154 public Date getDnsStart() { 155 return toDate(mDnsStartMs); 156 } 157 158 @Nullable 159 @Override getDnsEnd()160 public Date getDnsEnd() { 161 return toDate(mDnsEndMs); 162 } 163 164 @Nullable 165 @Override getConnectStart()166 public Date getConnectStart() { 167 return toDate(mConnectStartMs); 168 } 169 170 @Nullable 171 @Override getConnectEnd()172 public Date getConnectEnd() { 173 return toDate(mConnectEndMs); 174 } 175 176 @Nullable 177 @Override getSslStart()178 public Date getSslStart() { 179 return toDate(mSslStartMs); 180 } 181 182 @Nullable 183 @Override getSslEnd()184 public Date getSslEnd() { 185 return toDate(mSslEndMs); 186 } 187 188 @Nullable 189 @Override getSendingStart()190 public Date getSendingStart() { 191 return toDate(mSendingStartMs); 192 } 193 194 @Nullable 195 @Override getSendingEnd()196 public Date getSendingEnd() { 197 return toDate(mSendingEndMs); 198 } 199 200 @Nullable 201 @Override getPushStart()202 public Date getPushStart() { 203 return toDate(mPushStartMs); 204 } 205 206 @Nullable 207 @Override getPushEnd()208 public Date getPushEnd() { 209 return toDate(mPushEndMs); 210 } 211 212 @Nullable 213 @Override getResponseStart()214 public Date getResponseStart() { 215 return toDate(mResponseStartMs); 216 } 217 218 @Nullable 219 @Override getRequestEnd()220 public Date getRequestEnd() { 221 return toDate(mRequestEndMs); 222 } 223 224 @Override getSocketReused()225 public boolean getSocketReused() { 226 return mSocketReused; 227 } 228 229 @Nullable 230 @Override getTtfbMs()231 public Long getTtfbMs() { 232 return mTtfbMs; 233 } 234 235 @Nullable 236 @Override getTotalTimeMs()237 public Long getTotalTimeMs() { 238 return mTotalTimeMs; 239 } 240 241 @Nullable 242 @Override getSentByteCount()243 public Long getSentByteCount() { 244 return mSentByteCount; 245 } 246 247 @Nullable 248 @Override getReceivedByteCount()249 public Long getReceivedByteCount() { 250 return mReceivedByteCount; 251 } 252 } 253