|
|
DescriptionInitial implementation of Cronet Async API.
BUG=409926
Committed: https://crrev.com/d190710e56c9399e0bc1e9a88b26093190974c4d
Cr-Commit-Position: refs/heads/master@{#303252}
Patch Set 1 #
Total comments: 30
Patch Set 2 : Address clm's comments. #Patch Set 3 : Add and pass simple async unit test. #Patch Set 4 : Address clm's comments, populate ResponseInfo. #
Total comments: 27
Patch Set 5 : SYnc #Patch Set 6 : Address review comments. #Patch Set 7 : Remove spurious change to ChromiumUrlRequest. #Patch Set 8 : Make UrlRequestFactory into a class that can create factories. #
Total comments: 17
Patch Set 9 : Address clm's comments, fix legacy unit test. #Patch Set 10 : Sync #Patch Set 11 : Move userAgent into config, introduce ExtendedResponseInfo. #
Total comments: 36
Patch Set 12 : Address Matt's comments. #
Total comments: 36
Patch Set 13 : Address review comments. #
Total comments: 67
Patch Set 14 : Moar tests. #Patch Set 15 : Address Matt's comments. #Patch Set 16 : Sync #Patch Set 17 : Added ReportMockErrorFromQuery to URLRequestMockHTTPJob. #
Total comments: 10
Patch Set 18 : Address review comments, add mock errors to CronetUrlRequestTest. #
Total comments: 55
Patch Set 19 : Address review comments, add cancel tests. #Patch Set 20 : Added GetMockUrlWithFailure method and add tests to cancel outside of listener. #Patch Set 21 : Sync #
Total comments: 52
Patch Set 22 : Renamed UrlRequestFactory into UrlRequestContext, addressed some comments. #
Total comments: 21
Patch Set 23 : Addressed more comments. #Patch Set 24 : Sync #Patch Set 25 : More tests, more comments, more cancel. #
Total comments: 102
Patch Set 26 : Address more comments. #
Total comments: 36
Patch Set 27 : Better cancel and destroy. #Patch Set 28 : Moar tests and comments. #
Total comments: 20
Patch Set 29 : Address Helen's comments, add CronetUrlRequestContextTest. #
Total comments: 2
Patch Set 30 : Added mUrlRequestAdapterLock, don't create request adapter until start. #Patch Set 31 : Sync #
Total comments: 28
Patch Set 32 : Address review comments. #
Total comments: 51
Patch Set 33 : Sync. #Patch Set 34 : Address review comments. #Patch Set 35 : Delete network thread from java thread, adjust urlchain, check for bad http method. #
Total comments: 16
Patch Set 36 : Address comments, add more shutdown tests. #
Total comments: 137
Patch Set 37 : Extract TestUrlRequestListener, address review comments. #
Total comments: 26
Patch Set 38 : Address comments, moar scoped pointers. #
Total comments: 32
Patch Set 39 : UPPERCASE enum names. #
Total comments: 57
Patch Set 40 : Address more comments. #Patch Set 41 : Added more tests, removed CronetUrlRequestPriority enum. #Patch Set 42 : Sync #
Total comments: 134
Patch Set 43 : Address review comments. #
Total comments: 32
Patch Set 44 : Address more comments. #
Total comments: 7
Patch Set 45 : Last comments. #Patch Set 46 : Sync #Messages
Total messages: 131 (6 generated)
mef@chromium.org changed reviewers: + clm@google.com, mmenke@chromium.org, xunjieli@chromium.org
Hi, this is very early work in progress, but I would like to confirm that I'm working in the right direction. :) Interesting stuff is in CronetUrlRequest.java and cronet_url_request[_adapter].cc/h. The threading is currently split as follows: - JNI methods are called on any thread - CronetURLRequestAdapter posts to network thread as needed. - CronetURLRequestContextAdapterDelegate is called on network thread and calls CronetUrlRequest @OnCalledByNative callbacks on network thread. - OnCalledByNative callbacks post URLRequestListener using executor passed by embedder, and upon return call JNI methods on that executor. - etc. Does it make sense?
https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:24: public class CronetUrlRequest implements UrlRequest { Final? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:37: class NativeResponseInfo implements ResponseInfo { Final https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:64: public boolean wasFetchedOverSPDY() { I actually prefer getting the negotiated protocol string. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:95: mRequestContext.getCronetUrlRequestContextAdapter(), These params all fit on one line https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:119: public void start() { These methods should have threading policy attached to them, so that they throw if they're called on the wrong thread. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:177: private void onCalledByNativeException(Exception e) { Needs @CalledByNative annotation https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:185: } catch (Exception cancel_exception) { Use java style naming of exception https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:255: Runnable task = new Runnable() { Is there any way to avoid allocating this every time onDataRecieved is called? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:302: onCalledByNativeException(e); Given that this is happening on the other thread, do we need the Exception catching? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (left): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:9: * Note: All methods must be called on the Executor passed in during creation. You should enforce this by checking the calling thread ID https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:46: public void onDataReceived(UrlRequest request, final ByteBuffer byteBuffer); That doesn't do anything, java doesn't do references like c++ does.
Thanks, so I guess overall threading looks ok? Do we care about thread-pooling and other interesting executors? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:24: public class CronetUrlRequest implements UrlRequest { On 2014/09/20 00:47:34, Charles wrote: > Final? Done. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:37: class NativeResponseInfo implements ResponseInfo { On 2014/09/20 00:47:34, Charles wrote: > Final Done. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:64: public boolean wasFetchedOverSPDY() { On 2014/09/20 00:47:34, Charles wrote: > I actually prefer getting the negotiated protocol string. sgtm https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:95: mRequestContext.getCronetUrlRequestContextAdapter(), On 2014/09/20 00:47:34, Charles wrote: > These params all fit on one line Acknowledged. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:119: public void start() { On 2014/09/20 00:47:33, Charles wrote: > These methods should have threading policy attached to them, so that they throw > if they're called on the wrong thread. Is there some way to formally declare threading policy via annotations or something? Also, I was thinking that "start" could get called from arbitrary thread and posts to network thread internally. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:177: private void onCalledByNativeException(Exception e) { On 2014/09/20 00:47:34, Charles wrote: > Needs @CalledByNative annotation It is not called by native, it merely handles exceptions caught in @CalledByNative methods. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:185: } catch (Exception cancel_exception) { On 2014/09/20 00:47:33, Charles wrote: > Use java style naming of exception Done. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:255: Runnable task = new Runnable() { On 2014/09/20 00:47:34, Charles wrote: > Is there any way to avoid allocating this every time onDataRecieved is called? I guess I can keep onDataReceivedRunnable as a member of CronetUrlRequest and just pass new byte buffer to it. Is this what you mean? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:302: onCalledByNativeException(e); On 2014/09/20 00:47:34, Charles wrote: > Given that this is happening on the other thread, do we need the Exception > catching? Good question. What should happen if listener throws an exception? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:306: mExecutor.execute(task); Should we execute it inside of try...catch to handle bad executors? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (left): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:9: * Note: All methods must be called on the Executor passed in during creation. On 2014/09/20 00:47:34, Charles wrote: > You should enforce this by checking the calling thread ID Hmm, about executor, it doesn't seem to require thread affinity, does it? Do we need to somehow limit that? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:46: public void onDataReceived(UrlRequest request, final ByteBuffer byteBuffer); On 2014/09/20 00:47:34, Charles wrote: > That doesn't do anything, java doesn't do references like c++ does. Done.
https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:119: public void start() { On 2014/09/22 17:12:12, mef wrote: > On 2014/09/20 00:47:33, Charles wrote: > > These methods should have threading policy attached to them, so that they > throw > > if they're called on the wrong thread. > > Is there some way to formally declare threading policy via annotations or > something? > Also, I was thinking that "start" could get called from arbitrary thread and > posts to network thread internally. There is, but it's not standard and the compiler doesn't enforce it. Checking currentThread() and throwing exceptions is the way to go. Also, while start() should be able to be called from other threads, it should be called from the same thread as the setup of the request. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:255: Runnable task = new Runnable() { That would work. On 2014/09/22 17:12:12, mef wrote: > On 2014/09/20 00:47:34, Charles wrote: > > Is there any way to avoid allocating this every time onDataRecieved is called? > I guess I can keep onDataReceivedRunnable as a member of CronetUrlRequest and > just pass new byte buffer to it. Is this what you mean? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:302: onCalledByNativeException(e); I think the current behavior is correct, except that if cancel() is called from the executor thread then you'll be racing the state of mCancelled and the native destruction of the request. The cancel() method should cause a post to the network thread. On 2014/09/22 17:12:12, mef wrote: > On 2014/09/20 00:47:34, Charles wrote: > > Given that this is happening on the other thread, do we need the Exception > > catching? > Good question. What should happen if listener throws an exception? https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (left): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:9: * Note: All methods must be called on the Executor passed in during creation. On 2014/09/22 17:12:13, mef wrote: > On 2014/09/20 00:47:34, Charles wrote: > > You should enforce this by checking the calling thread ID > Hmm, about executor, it doesn't seem to require thread affinity, does it? Do we > need to somehow limit that? You can make sure that it's executing on the thread that the current callback is being executed on, or pre-start that the object was constructed on. As I understand it, the network stack guarantees that no two callbacks will ever run concurrently.
Thanks! I got basic unit test to pass, and will proceed with completeness and correctness. :) https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:95: mRequestContext.getCronetUrlRequestContextAdapter(), On 2014/09/22 17:12:13, mef wrote: > On 2014/09/20 00:47:34, Charles wrote: > > These params all fit on one line > > Acknowledged. Actually, they don't fit into 80 chars, which is our self-imposed limit due to rietveld ui. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:255: Runnable task = new Runnable() { On 2014/09/22 21:22:53, Charles wrote: > That would work. > > On 2014/09/22 17:12:12, mef wrote: > > On 2014/09/20 00:47:34, Charles wrote: > > > Is there any way to avoid allocating this every time onDataRecieved is > called? > > I guess I can keep onDataReceivedRunnable as a member of CronetUrlRequest and > > just pass new byte buffer to it. Is this what you mean? > Done. https://codereview.chromium.org/586143002/diff/1/components/cronet/android/ja... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:302: onCalledByNativeException(e); On 2014/09/22 21:22:53, Charles wrote: > I think the current behavior is correct, except that if cancel() is called from > the executor thread then you'll be racing the state of mCancelled and the native > destruction of the request. The cancel() method should cause a post to the > network thread. > > On 2014/09/22 17:12:12, mef wrote: > > On 2014/09/20 00:47:34, Charles wrote: > > > Given that this is happening on the other thread, do we need the Exception > > > catching? > > Good question. What should happen if listener throws an exception? Done.
https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:227: mResponseInfo.mUrlChain.add(0, newLocation); It looks like your mUrlChain will append the original url to the end, while add the redirects to the front of the array. This is different from your docs on getUrlChain(). Is that intended? I might have missed something..
I don't actually see any way to get the response body from a CronetUrlRequest. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:24: public final class CronetUrlRequest implements UrlRequest { Should this class be package-private? https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:38: final class OnDataReceivedRunnable implements Runnable { I see how this could be trivially extended to work with Channels, but is there a reason we didn't just use WritableByteChannel for something that only exists to write bytes? Will we add API to do that? https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:51: final class NativeResponseInfo implements ResponseInfo { Can we make these fields final and populate them all in the constructor? https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:145: public boolean isCanceled() { Thread safe? Sometimes we check mCanceled, sometimes we use the method. We should be consistent. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:160: public void resume() { throw new UnsupportedOperationException("Not implemented yet") https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:270: * valid only for the duration of the callback. Or if the callback This isn't true any more, the bytebuffer should be valid until the received method is called. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:286: * Called when request is complete, no callbacks will be called afterwards. We should propagate all this javadoc onto the listener, and update the javadoc here. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:295: mListener.onComplete(CronetUrlRequest.this); You're giving the listener a reference to the request, but there's aren't any methods in the UrlRequest interface that are useful for the listener to call during onComplete. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:33: public CronetUrlRequestContext(Context context, String userAgent, String config) { silly 80 char limit violation https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:14: public abstract interface ResponseInfo { abstract interface is redundant
https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:295: mListener.onComplete(CronetUrlRequest.this); On 2014/09/23 22:33:12, Charles wrote: > You're giving the listener a reference to the request, but there's aren't any > methods in the UrlRequest interface that are useful for the listener to call > during onComplete. This allows one listener to handle multiple requests. I don't think it will be the usual use case, but doesn't seem to be much cost to making an interface that allows it.
https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:295: mListener.onComplete(CronetUrlRequest.this); On 2014/09/23 22:38:22, mmenke wrote: > On 2014/09/23 22:33:12, Charles wrote: > > You're giving the listener a reference to the request, but there's aren't any > > methods in the UrlRequest interface that are useful for the listener to call > > during onComplete. > > This allows one listener to handle multiple requests. I don't think it will be > the usual use case, but doesn't seem to be much cost to making an interface that > allows it. Exposing the request object allows a listener to bring it out of scope, which is a problem since the object is no longer valid after the call completes. I don't think having a single listener for multiple requests is all that important, and you can do that anyway if the URLs are unique by passing a result object.
mef@chromium.org changed reviewers: + ebravo@google.com
Thanks! I have one more question - ebravo@ asked to get information about over the wire size of the response, and it seems to be fairly well matched by net::UrlRequest::GetTotalReceivedBytes(). So, what's a good way to expose it - via ResponseInfo (but then it has to be passed to OnDataReceived) or as an additional argument to OnDataReceived (but it seems of little interest to most embedders)? https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:24: public final class CronetUrlRequest implements UrlRequest { On 2014/09/23 22:33:12, Charles wrote: > Should this class be package-private? Done. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:38: final class OnDataReceivedRunnable implements Runnable { On 2014/09/23 22:33:12, Charles wrote: > I see how this could be trivially extended to work with Channels, but is there a > reason we didn't just use WritableByteChannel for something that only exists to > write bytes? Will we add API to do that? I think we could, but should we? What was the consensus on net-dev@ discussion? https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:51: final class NativeResponseInfo implements ResponseInfo { On 2014/09/23 22:33:12, Charles wrote: > Can we make these fields final and populate them all in the constructor? Done. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:145: public boolean isCanceled() { On 2014/09/23 22:33:12, Charles wrote: > Thread safe? Sometimes we check mCanceled, sometimes we use the method. We > should be consistent. Hmm, I don't see where we check mCanceled. I've removed mCanceled = true; from cancel, so it is only set in OnComplete. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:160: public void resume() { On 2014/09/23 22:33:12, Charles wrote: > throw new UnsupportedOperationException("Not implemented yet") Done. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:227: mResponseInfo.mUrlChain.add(0, newLocation); On 2014/09/23 20:53:24, xunjieli wrote: > It looks like your mUrlChain will append the original url to the end, while add > the redirects to the front of the array. This is different from your docs on > getUrlChain(). Is that intended? I might have missed something.. Done. Good catch, thanks! https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:270: * valid only for the duration of the callback. Or if the callback On 2014/09/23 22:33:12, Charles wrote: > This isn't true any more, the bytebuffer should be valid until the received > method is called. Done. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:286: * Called when request is complete, no callbacks will be called afterwards. On 2014/09/23 22:33:12, Charles wrote: > We should propagate all this javadoc onto the listener, and update the javadoc > here. The javadoc here actually came from the listener. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:295: mListener.onComplete(CronetUrlRequest.this); On 2014/09/23 22:50:51, Charles wrote: > On 2014/09/23 22:38:22, mmenke wrote: > > On 2014/09/23 22:33:12, Charles wrote: > > > You're giving the listener a reference to the request, but there's aren't > any > > > methods in the UrlRequest interface that are useful for the listener to call > > > during onComplete. > > > > This allows one listener to handle multiple requests. I don't think it will > be > > the usual use case, but doesn't seem to be much cost to making an interface > that > > allows it. > > Exposing the request object allows a listener to bring it out of scope, which is > a problem since the object is no longer valid after the call completes. I don't > think having a single listener for multiple requests is all that important, and > you can do that anyway if the URLs are unique by passing a result object. Well, listener could bring UrlRequest out of scope by storing it from any other callback as well, so IMHO passing it explicitly to all callbacks doesn't hurt. I don't see how URLs could be expected to be unique. It could make sense to make ResponseInfo available after request completion, so for example, caller could check http status, etc. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:33: public CronetUrlRequestContext(Context context, String userAgent, String config) { On 2014/09/23 22:33:13, Charles wrote: > silly 80 char limit violation Done. https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:14: public abstract interface ResponseInfo { On 2014/09/23 22:33:13, Charles wrote: > abstract interface is redundant Done.
https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:38: final class OnDataReceivedRunnable implements Runnable { On 2014/09/24 18:56:26, mef wrote: > On 2014/09/23 22:33:12, Charles wrote: > > I see how this could be trivially extended to work with Channels, but is there > a > > reason we didn't just use WritableByteChannel for something that only exists > to > > write bytes? Will we add API to do that? > > I think we could, but should we? What was the consensus on net-dev@ discussion? WriteableByteChannel adds a copy, doesn't it? It's also a blocking API. I'm not really sure just what you have in mind here - do we use one internally for our own purposes, or are you thinking having the embedder give us one? Then we'd...what, tell the embedder when bytes are available, and how many, then write to those bytes to the channel, and hope the implementation is such that if you write n bytes, the reader will always be able to reach all n bytes, without some sort of hidden buffering without a timeout? That seems like a much uglier API.
Patchset #7 (id:120001) has been deleted
https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:38: final class OnDataReceivedRunnable implements Runnable { On 2014/09/24 19:04:14, mmenke wrote: > On 2014/09/24 18:56:26, mef wrote: > > On 2014/09/23 22:33:12, Charles wrote: > > > I see how this could be trivially extended to work with Channels, but is > there > > a > > > reason we didn't just use WritableByteChannel for something that only exists > > to > > > write bytes? Will we add API to do that? > > > > I think we could, but should we? What was the consensus on net-dev@ > discussion? > > WriteableByteChannel adds a copy, doesn't it? It's also a blocking API. > > I'm not really sure just what you have in mind here - do we use one internally > for our own purposes, or are you thinking having the embedder give us one? Then > we'd...what, tell the embedder when bytes are available, and how many, then > write to those bytes to the channel, and hope the implementation is such that if > you write n bytes, the reader will always be able to reach all n bytes, without > some sort of hidden buffering without a timeout? > > That seems like a much uglier API. Per chat with clm@ WriteableByteChannel is just an interface, and its 'write(ByteBuffer src)' method seems to closely match onDataReceived callback. We did agree though that it could be easily done through simple listener wrapper. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:36: String userAgent, HttpUrlRequestFactoryConfig config) { I wonder whether |userAgent| should be a separate argument or part of the |config|?
https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/60001/components/cronet/androi... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:38: final class OnDataReceivedRunnable implements Runnable { On 2014/09/24 19:04:14, mmenke wrote: > On 2014/09/24 18:56:26, mef wrote: > > On 2014/09/23 22:33:12, Charles wrote: > > > I see how this could be trivially extended to work with Channels, but is > there > > a > > > reason we didn't just use WritableByteChannel for something that only exists > > to > > > write bytes? Will we add API to do that? > > > > I think we could, but should we? What was the consensus on net-dev@ > discussion? > > WriteableByteChannel adds a copy, doesn't it? It's also a blocking API. > > I'm not really sure just what you have in mind here - do we use one internally > for our own purposes, or are you thinking having the embedder give us one? Then > we'd...what, tell the embedder when bytes are available, and how many, then > write to those bytes to the channel, and hope the implementation is such that if > you write n bytes, the reader will always be able to reach all n bytes, without > some sort of hidden buffering without a timeout? > > That seems like a much uglier API. What? No. I'm just remarking that the use case of onDataReceived is remarkably similar to that of WriteableByteChannel.write(ByteBuffer b). Yes, it's blocking, but that's OK because we're running on the executor that's off the network thread. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:59: private long mTotalReceivedBytes = 0; Final? And where is this being populated? https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:57: long getTotalReceivedBytes(); Does this include uploaded bytes? I think getTotalBytesTransferred() or similar might more clearly state that it's not bytes delivered, it's bytes sent over the wire. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:36: String userAgent, HttpUrlRequestFactoryConfig config) { On 2014/09/26 19:23:52, mef wrote: > I wonder whether |userAgent| should be a separate argument or part of the > |config|? I vote for config. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ResponseInfo info); Do we still need to pass the UrlRequest? Why not just the ResponseInfo?
https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:59: private long mTotalReceivedBytes = 0; On 2014/09/26 22:52:26, Charles wrote: > Final? And where is this being populated? Not Final as it is now updated in OnComplete(). I don't particularly like this, so if there is a better pattern I'm open for suggestions. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:57: long getTotalReceivedBytes(); On 2014/09/26 22:52:26, Charles wrote: > Does this include uploaded bytes? I think getTotalBytesTransferred() or similar > might more clearly state that it's not bytes delivered, it's bytes sent over the > wire. Judging by the name it is just number of received bytes (excluding SSL and proxy overhead, but before gzip decompression). https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:36: String userAgent, HttpUrlRequestFactoryConfig config) { On 2014/09/26 22:52:26, Charles wrote: > On 2014/09/26 19:23:52, mef wrote: > > I wonder whether |userAgent| should be a separate argument or part of the > > |config|? > > I vote for config. SGTM, will do. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ResponseInfo info); On 2014/09/26 22:52:26, Charles wrote: > Do we still need to pass the UrlRequest? Why not just the ResponseInfo? I've chatted with Matt and we've agreed to keep it there for consistency.
https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:59: private long mTotalReceivedBytes = 0; On 2014/09/29 17:57:36, mef wrote: > On 2014/09/26 22:52:26, Charles wrote: > > Final? And where is this being populated? > > Not Final as it is now updated in OnComplete(). > I don't particularly like this, so if there is a better pattern I'm open for > suggestions. Split ResponseInfo into two interfaces, make this implement both, then define the interface that you can actually use in the callback method. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ResponseInfo info); On 2014/09/29 17:57:37, mef wrote: > On 2014/09/26 22:52:26, Charles wrote: > > Do we still need to pass the UrlRequest? Why not just the ResponseInfo? > > I've chatted with Matt and we've agreed to keep it there for consistency. I don't understand. There are no methods that could possibly be called on it, it provides absolutely no value to the embedder. All it does is add confusion and the possibility for leaking a dead object. Consistency is only of value when it lets the consumer of the API intuit the behavior of some API based on their knowledge of the rest, which this doesn't do - the intuition of the embedder will lead them to do the wrong thing, like cancelling the request in onError when it's already done for you. Adding a parameter that you can't/shouldn't touch is confusing and unnecessary.
https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ResponseInfo info); On 2014/09/29 18:10:34, Charles wrote: > On 2014/09/29 17:57:37, mef wrote: > > On 2014/09/26 22:52:26, Charles wrote: > > > Do we still need to pass the UrlRequest? Why not just the ResponseInfo? > > > > I've chatted with Matt and we've agreed to keep it there for consistency. > > I don't understand. There are no methods that could possibly be called on it, it > provides absolutely no value to the embedder. All it does is add confusion and > the possibility for leaking a dead object. Consistency is only of value when it > lets the consumer of the API intuit the behavior of some API based on their > knowledge of the rest, which this doesn't do - the intuition of the embedder > will lead them to do the wrong thing, like cancelling the request in onError > when it's already done for you. Adding a parameter that you can't/shouldn't > touch is confusing and unnecessary. The embedder should be able to uniquely identify the request a response came from, unless we want to force the embedder to use a separate listener for every request. The only way to do this is either through the use of a request ID (Which we could either provide, or take from the embedder), or passing the UrlRequest for pointer comparison. The URL is insufficient, as there may be multiple requests for a single URL (Particularly for POSTs - Knowing the URL was "https://www.googleapis.com/rpc", for instance, isn't terribly useful, since it's quite possible we have a bunch of POSTs to different services that all use the same URL).
https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ResponseInfo info); On 2014/09/29 19:26:46, mmenke wrote: > On 2014/09/29 18:10:34, Charles wrote: > > On 2014/09/29 17:57:37, mef wrote: > > > On 2014/09/26 22:52:26, Charles wrote: > > > > Do we still need to pass the UrlRequest? Why not just the ResponseInfo? > > > > > > I've chatted with Matt and we've agreed to keep it there for consistency. > > > > I don't understand. There are no methods that could possibly be called on it, > it > > provides absolutely no value to the embedder. All it does is add confusion and > > the possibility for leaking a dead object. Consistency is only of value when > it > > lets the consumer of the API intuit the behavior of some API based on their > > knowledge of the rest, which this doesn't do - the intuition of the embedder > > will lead them to do the wrong thing, like cancelling the request in onError > > when it's already done for you. Adding a parameter that you can't/shouldn't > > touch is confusing and unnecessary. > > The embedder should be able to uniquely identify the request a response came > from, unless we want to force the embedder to use a separate listener for every > request. The only way to do this is either through the use of a request ID > (Which we could either provide, or take from the embedder), or passing the > UrlRequest for pointer comparison. > > The URL is insufficient, as there may be multiple requests for a single URL > (Particularly for POSTs - Knowing the URL was "https://www.googleapis.com/rpc", > for instance, isn't terribly useful, since it's quite possible we have a bunch > of POSTs to different services that all use the same URL). Oh, and I should add, if we do want to force the embedder to use one listener per request, I think we should get rid of the UrlRequest parameter completely - the embedder created the request and set up the listener, so seems reasonable to expect them to track it as well.
https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ResponseInfo info); On 2014/09/29 19:28:36, mmenke wrote: > On 2014/09/29 19:26:46, mmenke wrote: > > On 2014/09/29 18:10:34, Charles wrote: > > > On 2014/09/29 17:57:37, mef wrote: > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > Do we still need to pass the UrlRequest? Why not just the ResponseInfo? > > > > > > > > I've chatted with Matt and we've agreed to keep it there for consistency. > > > > > > I don't understand. There are no methods that could possibly be called on > it, > > it > > > provides absolutely no value to the embedder. All it does is add confusion > and > > > the possibility for leaking a dead object. Consistency is only of value when > > it > > > lets the consumer of the API intuit the behavior of some API based on their > > > knowledge of the rest, which this doesn't do - the intuition of the embedder > > > will lead them to do the wrong thing, like cancelling the request in onError > > > when it's already done for you. Adding a parameter that you can't/shouldn't > > > touch is confusing and unnecessary. > > > > The embedder should be able to uniquely identify the request a response came > > from, unless we want to force the embedder to use a separate listener for > every > > request. The only way to do this is either through the use of a request ID > > (Which we could either provide, or take from the embedder), or passing the > > UrlRequest for pointer comparison. > > > > The URL is insufficient, as there may be multiple requests for a single URL > > (Particularly for POSTs - Knowing the URL was > "https://www.googleapis.com/rpc", > > for instance, isn't terribly useful, since it's quite possible we have a bunch > > of POSTs to different services that all use the same URL). > > Oh, and I should add, if we do want to force the embedder to use one listener > per request, I think we should get rid of the UrlRequest parameter completely - > the embedder created the request and set up the listener, so seems reasonable to > expect them to track it as well. What is the use case where multiple listeners are useful? Anywhere you want the request body you're going to need a listener per request, so that limits this to posts. Where are we doing a whole bunch of concurrent posts? Are you envisioning the listener maintaining a map of UrlRequests -> success stats?
On 2014/09/29 19:52:50, Charles wrote: > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java > (right): > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: > public void onComplete(UrlRequest request, ResponseInfo info); > On 2014/09/29 19:28:36, mmenke wrote: > > On 2014/09/29 19:26:46, mmenke wrote: > > > On 2014/09/29 18:10:34, Charles wrote: > > > > On 2014/09/29 17:57:37, mef wrote: > > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > > Do we still need to pass the UrlRequest? Why not just the > ResponseInfo? > > > > > > > > > > I've chatted with Matt and we've agreed to keep it there for > consistency. > > > > > > > > I don't understand. There are no methods that could possibly be called on > > it, > > > it > > > > provides absolutely no value to the embedder. All it does is add confusion > > and > > > > the possibility for leaking a dead object. Consistency is only of value > when > > > it > > > > lets the consumer of the API intuit the behavior of some API based on > their > > > > knowledge of the rest, which this doesn't do - the intuition of the > embedder > > > > will lead them to do the wrong thing, like cancelling the request in > onError > > > > when it's already done for you. Adding a parameter that you > can't/shouldn't > > > > touch is confusing and unnecessary. > > > > > > The embedder should be able to uniquely identify the request a response came > > > from, unless we want to force the embedder to use a separate listener for > > every > > > request. The only way to do this is either through the use of a request ID > > > (Which we could either provide, or take from the embedder), or passing the > > > UrlRequest for pointer comparison. > > > > > > The URL is insufficient, as there may be multiple requests for a single URL > > > (Particularly for POSTs - Knowing the URL was > > "https://www.googleapis.com/rpc", > > > for instance, isn't terribly useful, since it's quite possible we have a > bunch > > > of POSTs to different services that all use the same URL). > > > > Oh, and I should add, if we do want to force the embedder to use one listener > > per request, I think we should get rid of the UrlRequest parameter completely > - > > the embedder created the request and set up the listener, so seems reasonable > to > > expect them to track it as well. > > What is the use case where multiple listeners are useful? Anywhere you want the > request body you're going to need a listener per request, so that limits this to > posts. Where are we doing a whole bunch of concurrent posts? Are you envisioning > the listener maintaining a map of UrlRequests -> success stats? Yes - I'm not sure if anyone would want to do it in practice, but I am indeed imagining a map of UrlRequests to information. We do it a lot in Chrome, actually - admittedly, Chrome's loading code is just a wee bit more complicated than the average embedder, but quite a number of components like to maintain per-request information, and use maps to do so - these generally aren't the primary consumer/owner of the request, but hangers on that may want to muck with them at some point. I suspect here it would mostly be useful if you're POSTing data and don't care about anything other than whether the requests succeeded or failed. I'm fine not supporting that use case (An embedder could pretty trivially make an adapter that adds support, if needed), though then I'd argue it's simpler to never pass in the UrlRequest. Misha: Any thoughts?
On 2014/09/29 20:03:05, mmenke wrote: > On 2014/09/29 19:52:50, Charles wrote: > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > File > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java > > (right): > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: > > public void onComplete(UrlRequest request, ResponseInfo info); > > On 2014/09/29 19:28:36, mmenke wrote: > > > On 2014/09/29 19:26:46, mmenke wrote: > > > > On 2014/09/29 18:10:34, Charles wrote: > > > > > On 2014/09/29 17:57:37, mef wrote: > > > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > > > Do we still need to pass the UrlRequest? Why not just the > > ResponseInfo? > > > > > > > > > > > > I've chatted with Matt and we've agreed to keep it there for > > consistency. > > > > > > > > > > I don't understand. There are no methods that could possibly be called > on > > > it, > > > > it > > > > > provides absolutely no value to the embedder. All it does is add > confusion > > > and > > > > > the possibility for leaking a dead object. Consistency is only of value > > when > > > > it > > > > > lets the consumer of the API intuit the behavior of some API based on > > their > > > > > knowledge of the rest, which this doesn't do - the intuition of the > > embedder > > > > > will lead them to do the wrong thing, like cancelling the request in > > onError > > > > > when it's already done for you. Adding a parameter that you > > can't/shouldn't > > > > > touch is confusing and unnecessary. > > > > > > > > The embedder should be able to uniquely identify the request a response > came > > > > from, unless we want to force the embedder to use a separate listener for > > > every > > > > request. The only way to do this is either through the use of a request > ID > > > > (Which we could either provide, or take from the embedder), or passing the > > > > UrlRequest for pointer comparison. > > > > > > > > The URL is insufficient, as there may be multiple requests for a single > URL > > > > (Particularly for POSTs - Knowing the URL was > > > "https://www.googleapis.com/rpc", > > > > for instance, isn't terribly useful, since it's quite possible we have a > > bunch > > > > of POSTs to different services that all use the same URL). > > > > > > Oh, and I should add, if we do want to force the embedder to use one > listener > > > per request, I think we should get rid of the UrlRequest parameter > completely > > - > > > the embedder created the request and set up the listener, so seems > reasonable > > to > > > expect them to track it as well. > > > > What is the use case where multiple listeners are useful? Anywhere you want > the > > request body you're going to need a listener per request, so that limits this > to > > posts. Where are we doing a whole bunch of concurrent posts? Are you > envisioning > > the listener maintaining a map of UrlRequests -> success stats? > > Yes - I'm not sure if anyone would want to do it in practice, but I am indeed > imagining a map of UrlRequests to information. We do it a lot in Chrome, > actually - admittedly, Chrome's loading code is just a wee bit more complicated > than the average embedder, but quite a number of components like to maintain > per-request information, and use maps to do so - these generally aren't the > primary consumer/owner of the request, but hangers on that may want to muck with > them at some point. > > I suspect here it would mostly be useful if you're POSTing data and don't care > about anything other than whether the requests succeeded or failed. > > I'm fine not supporting that use case (An embedder could pretty trivially make > an adapter that adds support, if needed), though then I'd argue it's simpler to > never pass in the UrlRequest. Misha: Any thoughts? Hmm, if we never pass in UrlRequest to listener callbacks, then listener must explicitly hold on to it, and at some point it could end up with some semi-destroyed object. This doesn't seem nice.
On 2014/09/29 20:16:30, mef wrote: > On 2014/09/29 20:03:05, mmenke wrote: > > On 2014/09/29 19:52:50, Charles wrote: > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > File > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java > > > (right): > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: > > > public void onComplete(UrlRequest request, ResponseInfo info); > > > On 2014/09/29 19:28:36, mmenke wrote: > > > > On 2014/09/29 19:26:46, mmenke wrote: > > > > > On 2014/09/29 18:10:34, Charles wrote: > > > > > > On 2014/09/29 17:57:37, mef wrote: > > > > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > > > > Do we still need to pass the UrlRequest? Why not just the > > > ResponseInfo? > > > > > > > > > > > > > > I've chatted with Matt and we've agreed to keep it there for > > > consistency. > > > > > > > > > > > > I don't understand. There are no methods that could possibly be called > > on > > > > it, > > > > > it > > > > > > provides absolutely no value to the embedder. All it does is add > > confusion > > > > and > > > > > > the possibility for leaking a dead object. Consistency is only of > value > > > when > > > > > it > > > > > > lets the consumer of the API intuit the behavior of some API based on > > > their > > > > > > knowledge of the rest, which this doesn't do - the intuition of the > > > embedder > > > > > > will lead them to do the wrong thing, like cancelling the request in > > > onError > > > > > > when it's already done for you. Adding a parameter that you > > > can't/shouldn't > > > > > > touch is confusing and unnecessary. > > > > > > > > > > The embedder should be able to uniquely identify the request a response > > came > > > > > from, unless we want to force the embedder to use a separate listener > for > > > > every > > > > > request. The only way to do this is either through the use of a request > > ID > > > > > (Which we could either provide, or take from the embedder), or passing > the > > > > > UrlRequest for pointer comparison. > > > > > > > > > > The URL is insufficient, as there may be multiple requests for a single > > URL > > > > > (Particularly for POSTs - Knowing the URL was > > > > "https://www.googleapis.com/rpc", > > > > > for instance, isn't terribly useful, since it's quite possible we have a > > > bunch > > > > > of POSTs to different services that all use the same URL). > > > > > > > > Oh, and I should add, if we do want to force the embedder to use one > > listener > > > > per request, I think we should get rid of the UrlRequest parameter > > completely > > > - > > > > the embedder created the request and set up the listener, so seems > > reasonable > > > to > > > > expect them to track it as well. > > > > > > What is the use case where multiple listeners are useful? Anywhere you want > > the > > > request body you're going to need a listener per request, so that limits > this > > to > > > posts. Where are we doing a whole bunch of concurrent posts? Are you > > envisioning > > > the listener maintaining a map of UrlRequests -> success stats? > > > > Yes - I'm not sure if anyone would want to do it in practice, but I am indeed > > imagining a map of UrlRequests to information. We do it a lot in Chrome, > > actually - admittedly, Chrome's loading code is just a wee bit more > complicated > > than the average embedder, but quite a number of components like to maintain > > per-request information, and use maps to do so - these generally aren't the > > primary consumer/owner of the request, but hangers on that may want to muck > with > > them at some point. > > > > I suspect here it would mostly be useful if you're POSTing data and don't care > > about anything other than whether the requests succeeded or failed. > > > > I'm fine not supporting that use case (An embedder could pretty trivially make > > an adapter that adds support, if needed), though then I'd argue it's simpler > to > > never pass in the UrlRequest. Misha: Any thoughts? > > Hmm, if we never pass in UrlRequest to listener callbacks, then listener must > explicitly hold on to it, > and at some point it could end up with some semi-destroyed object. > This doesn't seem nice. If you ever want to be able cancel a request without waiting to get data from it, you actually have to hold onto a reference to it.
On 2014/09/29 20:50:56, mmenke wrote: > On 2014/09/29 20:16:30, mef wrote: > > On 2014/09/29 20:03:05, mmenke wrote: > > > On 2014/09/29 19:52:50, Charles wrote: > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > File > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java > > > > (right): > > > > > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: > > > > public void onComplete(UrlRequest request, ResponseInfo info); > > > > On 2014/09/29 19:28:36, mmenke wrote: > > > > > On 2014/09/29 19:26:46, mmenke wrote: > > > > > > On 2014/09/29 18:10:34, Charles wrote: > > > > > > > On 2014/09/29 17:57:37, mef wrote: > > > > > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > > > > > Do we still need to pass the UrlRequest? Why not just the > > > > ResponseInfo? > > > > > > > > > > > > > > > > I've chatted with Matt and we've agreed to keep it there for > > > > consistency. > > > > > > > > > > > > > > I don't understand. There are no methods that could possibly be > called > > > on > > > > > it, > > > > > > it > > > > > > > provides absolutely no value to the embedder. All it does is add > > > confusion > > > > > and > > > > > > > the possibility for leaking a dead object. Consistency is only of > > value > > > > when > > > > > > it > > > > > > > lets the consumer of the API intuit the behavior of some API based > on > > > > their > > > > > > > knowledge of the rest, which this doesn't do - the intuition of the > > > > embedder > > > > > > > will lead them to do the wrong thing, like cancelling the request in > > > > onError > > > > > > > when it's already done for you. Adding a parameter that you > > > > can't/shouldn't > > > > > > > touch is confusing and unnecessary. > > > > > > > > > > > > The embedder should be able to uniquely identify the request a > response > > > came > > > > > > from, unless we want to force the embedder to use a separate listener > > for > > > > > every > > > > > > request. The only way to do this is either through the use of a > request > > > ID > > > > > > (Which we could either provide, or take from the embedder), or passing > > the > > > > > > UrlRequest for pointer comparison. > > > > > > > > > > > > The URL is insufficient, as there may be multiple requests for a > single > > > URL > > > > > > (Particularly for POSTs - Knowing the URL was > > > > > "https://www.googleapis.com/rpc", > > > > > > for instance, isn't terribly useful, since it's quite possible we have > a > > > > bunch > > > > > > of POSTs to different services that all use the same URL). > > > > > > > > > > Oh, and I should add, if we do want to force the embedder to use one > > > listener > > > > > per request, I think we should get rid of the UrlRequest parameter > > > completely > > > > - > > > > > the embedder created the request and set up the listener, so seems > > > reasonable > > > > to > > > > > expect them to track it as well. > > > > > > > > What is the use case where multiple listeners are useful? Anywhere you > want > > > the > > > > request body you're going to need a listener per request, so that limits > > this > > > to > > > > posts. Where are we doing a whole bunch of concurrent posts? Are you > > > envisioning > > > > the listener maintaining a map of UrlRequests -> success stats? > > > > > > Yes - I'm not sure if anyone would want to do it in practice, but I am > indeed > > > imagining a map of UrlRequests to information. We do it a lot in Chrome, > > > actually - admittedly, Chrome's loading code is just a wee bit more > > complicated > > > than the average embedder, but quite a number of components like to maintain > > > per-request information, and use maps to do so - these generally aren't the > > > primary consumer/owner of the request, but hangers on that may want to muck > > with > > > them at some point. > > > > > > I suspect here it would mostly be useful if you're POSTing data and don't > care > > > about anything other than whether the requests succeeded or failed. > > > > > > I'm fine not supporting that use case (An embedder could pretty trivially > make > > > an adapter that adds support, if needed), though then I'd argue it's simpler > > to > > > never pass in the UrlRequest. Misha: Any thoughts? > > > > Hmm, if we never pass in UrlRequest to listener callbacks, then listener must > > explicitly hold on to it, > > and at some point it could end up with some semi-destroyed object. > > This doesn't seem nice. > > If you ever want to be able cancel a request without waiting to get data from > it, you actually have to hold onto a reference to it. That's true, but It still feels like unnecessary limitation. I can imagine current API allowing some kind of 'tracing listener' - one that logs callbacks prior to forwarding them to specific listener. If we remove URLRequest that would not be possible. FWIW fnk@ has previously pointed to jetty interface example, and it also explicitly passes request to callback: http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/client/a...
On 2014/09/29 21:01:24, mef wrote: > On 2014/09/29 20:50:56, mmenke wrote: > > On 2014/09/29 20:16:30, mef wrote: > > > On 2014/09/29 20:03:05, mmenke wrote: > > > > On 2014/09/29 19:52:50, Charles wrote: > > > > > > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > File > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java > > > > > (right): > > > > > > > > > > > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > > > > > > > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: > > > > > public void onComplete(UrlRequest request, ResponseInfo info); > > > > > On 2014/09/29 19:28:36, mmenke wrote: > > > > > > On 2014/09/29 19:26:46, mmenke wrote: > > > > > > > On 2014/09/29 18:10:34, Charles wrote: > > > > > > > > On 2014/09/29 17:57:37, mef wrote: > > > > > > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > > > > > > Do we still need to pass the UrlRequest? Why not just the > > > > > ResponseInfo? > > > > > > > > > > > > > > > > > > I've chatted with Matt and we've agreed to keep it there for > > > > > consistency. > > > > > > > > > > > > > > > > I don't understand. There are no methods that could possibly be > > called > > > > on > > > > > > it, > > > > > > > it > > > > > > > > provides absolutely no value to the embedder. All it does is add > > > > confusion > > > > > > and > > > > > > > > the possibility for leaking a dead object. Consistency is only of > > > value > > > > > when > > > > > > > it > > > > > > > > lets the consumer of the API intuit the behavior of some API based > > on > > > > > their > > > > > > > > knowledge of the rest, which this doesn't do - the intuition of > the > > > > > embedder > > > > > > > > will lead them to do the wrong thing, like cancelling the request > in > > > > > onError > > > > > > > > when it's already done for you. Adding a parameter that you > > > > > can't/shouldn't > > > > > > > > touch is confusing and unnecessary. > > > > > > > > > > > > > > The embedder should be able to uniquely identify the request a > > response > > > > came > > > > > > > from, unless we want to force the embedder to use a separate > listener > > > for > > > > > > every > > > > > > > request. The only way to do this is either through the use of a > > request > > > > ID > > > > > > > (Which we could either provide, or take from the embedder), or > passing > > > the > > > > > > > UrlRequest for pointer comparison. > > > > > > > > > > > > > > The URL is insufficient, as there may be multiple requests for a > > single > > > > URL > > > > > > > (Particularly for POSTs - Knowing the URL was > > > > > > "https://www.googleapis.com/rpc", > > > > > > > for instance, isn't terribly useful, since it's quite possible we > have > > a > > > > > bunch > > > > > > > of POSTs to different services that all use the same URL). > > > > > > > > > > > > Oh, and I should add, if we do want to force the embedder to use one > > > > listener > > > > > > per request, I think we should get rid of the UrlRequest parameter > > > > completely > > > > > - > > > > > > the embedder created the request and set up the listener, so seems > > > > reasonable > > > > > to > > > > > > expect them to track it as well. > > > > > > > > > > What is the use case where multiple listeners are useful? Anywhere you > > want > > > > the > > > > > request body you're going to need a listener per request, so that limits > > > this > > > > to > > > > > posts. Where are we doing a whole bunch of concurrent posts? Are you > > > > envisioning > > > > > the listener maintaining a map of UrlRequests -> success stats? > > > > > > > > Yes - I'm not sure if anyone would want to do it in practice, but I am > > indeed > > > > imagining a map of UrlRequests to information. We do it a lot in Chrome, > > > > actually - admittedly, Chrome's loading code is just a wee bit more > > > complicated > > > > than the average embedder, but quite a number of components like to > maintain > > > > per-request information, and use maps to do so - these generally aren't > the > > > > primary consumer/owner of the request, but hangers on that may want to > muck > > > with > > > > them at some point. > > > > > > > > I suspect here it would mostly be useful if you're POSTing data and don't > > care > > > > about anything other than whether the requests succeeded or failed. > > > > > > > > I'm fine not supporting that use case (An embedder could pretty trivially > > make > > > > an adapter that adds support, if needed), though then I'd argue it's > simpler > > > to > > > > never pass in the UrlRequest. Misha: Any thoughts? > > > > > > Hmm, if we never pass in UrlRequest to listener callbacks, then listener > must > > > explicitly hold on to it, > > > and at some point it could end up with some semi-destroyed object. > > > This doesn't seem nice. > > > > If you ever want to be able cancel a request without waiting to get data from > > it, you actually have to hold onto a reference to it. > > That's true, but It still feels like unnecessary limitation. I can imagine > current API allowing some kind of 'tracing listener' - > one that logs callbacks prior to forwarding them to specific listener. > > If we remove URLRequest that would not be possible. > FWIW fnk@ has previously pointed to jetty interface example, and it also > explicitly passes request to callback: > http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/client/a... Yes, that's true. However, that's a rare case - cancelling http requests without getting headers is pretty strange, and vanilla HTTP's cancel kills a connection. The only circumstance I could see where cancelling with no data makes sense is if you're racing GETs. As for jetty, their request object 1. participates in the regular java GC cycle and 2. has methods like getParams, which is the sort of thing we put on the responseinfo.
On 2014/09/29 21:09:56, Charles wrote: > On 2014/09/29 21:01:24, mef wrote: > > On 2014/09/29 20:50:56, mmenke wrote: > > > On 2014/09/29 20:16:30, mef wrote: > > > > On 2014/09/29 20:03:05, mmenke wrote: > > > > > On 2014/09/29 19:52:50, Charles wrote: > > > > > > > > > > > > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > > File > > > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java > > > > > > (right): > > > > > > > > > > > > > > > > > > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > > > > > > > > > > > > > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: > > > > > > public void onComplete(UrlRequest request, ResponseInfo info); > > > > > > On 2014/09/29 19:28:36, mmenke wrote: > > > > > > > On 2014/09/29 19:26:46, mmenke wrote: > > > > > > > > On 2014/09/29 18:10:34, Charles wrote: > > > > > > > > > On 2014/09/29 17:57:37, mef wrote: > > > > > > > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > > > > > > > Do we still need to pass the UrlRequest? Why not just the > > > > > > ResponseInfo? > > > > > > > > > > > > > > > > > > > > I've chatted with Matt and we've agreed to keep it there for > > > > > > consistency. > > > > > > > > > > > > > > > > > > I don't understand. There are no methods that could possibly be > > > called > > > > > on > > > > > > > it, > > > > > > > > it > > > > > > > > > provides absolutely no value to the embedder. All it does is add > > > > > confusion > > > > > > > and > > > > > > > > > the possibility for leaking a dead object. Consistency is only > of > > > > value > > > > > > when > > > > > > > > it > > > > > > > > > lets the consumer of the API intuit the behavior of some API > based > > > on > > > > > > their > > > > > > > > > knowledge of the rest, which this doesn't do - the intuition of > > the > > > > > > embedder > > > > > > > > > will lead them to do the wrong thing, like cancelling the > request > > in > > > > > > onError > > > > > > > > > when it's already done for you. Adding a parameter that you > > > > > > can't/shouldn't > > > > > > > > > touch is confusing and unnecessary. > > > > > > > > > > > > > > > > The embedder should be able to uniquely identify the request a > > > response > > > > > came > > > > > > > > from, unless we want to force the embedder to use a separate > > listener > > > > for > > > > > > > every > > > > > > > > request. The only way to do this is either through the use of a > > > request > > > > > ID > > > > > > > > (Which we could either provide, or take from the embedder), or > > passing > > > > the > > > > > > > > UrlRequest for pointer comparison. > > > > > > > > > > > > > > > > The URL is insufficient, as there may be multiple requests for a > > > single > > > > > URL > > > > > > > > (Particularly for POSTs - Knowing the URL was > > > > > > > "https://www.googleapis.com/rpc", > > > > > > > > for instance, isn't terribly useful, since it's quite possible we > > have > > > a > > > > > > bunch > > > > > > > > of POSTs to different services that all use the same URL). > > > > > > > > > > > > > > Oh, and I should add, if we do want to force the embedder to use one > > > > > listener > > > > > > > per request, I think we should get rid of the UrlRequest parameter > > > > > completely > > > > > > - > > > > > > > the embedder created the request and set up the listener, so seems > > > > > reasonable > > > > > > to > > > > > > > expect them to track it as well. > > > > > > > > > > > > What is the use case where multiple listeners are useful? Anywhere you > > > want > > > > > the > > > > > > request body you're going to need a listener per request, so that > limits > > > > this > > > > > to > > > > > > posts. Where are we doing a whole bunch of concurrent posts? Are you > > > > > envisioning > > > > > > the listener maintaining a map of UrlRequests -> success stats? > > > > > > > > > > Yes - I'm not sure if anyone would want to do it in practice, but I am > > > indeed > > > > > imagining a map of UrlRequests to information. We do it a lot in > Chrome, > > > > > actually - admittedly, Chrome's loading code is just a wee bit more > > > > complicated > > > > > than the average embedder, but quite a number of components like to > > maintain > > > > > per-request information, and use maps to do so - these generally aren't > > the > > > > > primary consumer/owner of the request, but hangers on that may want to > > muck > > > > with > > > > > them at some point. > > > > > > > > > > I suspect here it would mostly be useful if you're POSTing data and > don't > > > care > > > > > about anything other than whether the requests succeeded or failed. > > > > > > > > > > I'm fine not supporting that use case (An embedder could pretty > trivially > > > make > > > > > an adapter that adds support, if needed), though then I'd argue it's > > simpler > > > > to > > > > > never pass in the UrlRequest. Misha: Any thoughts? > > > > > > > > Hmm, if we never pass in UrlRequest to listener callbacks, then listener > > must > > > > explicitly hold on to it, > > > > and at some point it could end up with some semi-destroyed object. > > > > This doesn't seem nice. > > > > > > If you ever want to be able cancel a request without waiting to get data > from > > > it, you actually have to hold onto a reference to it. > > > > That's true, but It still feels like unnecessary limitation. I can imagine > > current API allowing some kind of 'tracing listener' - > > one that logs callbacks prior to forwarding them to specific listener. > > > > If we remove URLRequest that would not be possible. > > FWIW fnk@ has previously pointed to jetty interface example, and it also > > explicitly passes request to callback: > > > http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/client/a... > > Yes, that's true. However, that's a rare case - cancelling http requests without > getting headers is pretty strange, and vanilla HTTP's cancel kills a connection. > The only circumstance I could see where cancelling with no data makes sense is > if you're racing GETs. As for jetty, their request object 1. participates in the > regular java GC cycle and 2. has methods like getParams, which is the sort of > thing we put on the responseinfo. Is it really that rare? Just think about shutdown / suspend, or the user navigating to another view / video / whatever, or timing out requests.
On 2014/09/29 21:14:32, mmenke wrote: > On 2014/09/29 21:09:56, Charles wrote: > > On 2014/09/29 21:01:24, mef wrote: > > > On 2014/09/29 20:50:56, mmenke wrote: > > > > On 2014/09/29 20:16:30, mef wrote: > > > > > On 2014/09/29 20:03:05, mmenke wrote: > > > > > > On 2014/09/29 19:52:50, Charles wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > > > File > > > > > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java > > > > > > > (right): > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > > > > > > > > > > > > > > > > > > > > > > > > > > > > components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: > > > > > > > public void onComplete(UrlRequest request, ResponseInfo info); > > > > > > > On 2014/09/29 19:28:36, mmenke wrote: > > > > > > > > On 2014/09/29 19:26:46, mmenke wrote: > > > > > > > > > On 2014/09/29 18:10:34, Charles wrote: > > > > > > > > > > On 2014/09/29 17:57:37, mef wrote: > > > > > > > > > > > On 2014/09/26 22:52:26, Charles wrote: > > > > > > > > > > > > Do we still need to pass the UrlRequest? Why not just the > > > > > > > ResponseInfo? > > > > > > > > > > > > > > > > > > > > > > I've chatted with Matt and we've agreed to keep it there for > > > > > > > consistency. > > > > > > > > > > > > > > > > > > > > I don't understand. There are no methods that could possibly > be > > > > called > > > > > > on > > > > > > > > it, > > > > > > > > > it > > > > > > > > > > provides absolutely no value to the embedder. All it does is > add > > > > > > confusion > > > > > > > > and > > > > > > > > > > the possibility for leaking a dead object. Consistency is only > > of > > > > > value > > > > > > > when > > > > > > > > > it > > > > > > > > > > lets the consumer of the API intuit the behavior of some API > > based > > > > on > > > > > > > their > > > > > > > > > > knowledge of the rest, which this doesn't do - the intuition > of > > > the > > > > > > > embedder > > > > > > > > > > will lead them to do the wrong thing, like cancelling the > > request > > > in > > > > > > > onError > > > > > > > > > > when it's already done for you. Adding a parameter that you > > > > > > > can't/shouldn't > > > > > > > > > > touch is confusing and unnecessary. > > > > > > > > > > > > > > > > > > The embedder should be able to uniquely identify the request a > > > > response > > > > > > came > > > > > > > > > from, unless we want to force the embedder to use a separate > > > listener > > > > > for > > > > > > > > every > > > > > > > > > request. The only way to do this is either through the use of a > > > > request > > > > > > ID > > > > > > > > > (Which we could either provide, or take from the embedder), or > > > passing > > > > > the > > > > > > > > > UrlRequest for pointer comparison. > > > > > > > > > > > > > > > > > > The URL is insufficient, as there may be multiple requests for a > > > > single > > > > > > URL > > > > > > > > > (Particularly for POSTs - Knowing the URL was > > > > > > > > "https://www.googleapis.com/rpc", > > > > > > > > > for instance, isn't terribly useful, since it's quite possible > we > > > have > > > > a > > > > > > > bunch > > > > > > > > > of POSTs to different services that all use the same URL). > > > > > > > > > > > > > > > > Oh, and I should add, if we do want to force the embedder to use > one > > > > > > listener > > > > > > > > per request, I think we should get rid of the UrlRequest parameter > > > > > > completely > > > > > > > - > > > > > > > > the embedder created the request and set up the listener, so seems > > > > > > reasonable > > > > > > > to > > > > > > > > expect them to track it as well. > > > > > > > > > > > > > > What is the use case where multiple listeners are useful? Anywhere > you > > > > want > > > > > > the > > > > > > > request body you're going to need a listener per request, so that > > limits > > > > > this > > > > > > to > > > > > > > posts. Where are we doing a whole bunch of concurrent posts? Are you > > > > > > envisioning > > > > > > > the listener maintaining a map of UrlRequests -> success stats? > > > > > > > > > > > > Yes - I'm not sure if anyone would want to do it in practice, but I am > > > > indeed > > > > > > imagining a map of UrlRequests to information. We do it a lot in > > Chrome, > > > > > > actually - admittedly, Chrome's loading code is just a wee bit more > > > > > complicated > > > > > > than the average embedder, but quite a number of components like to > > > maintain > > > > > > per-request information, and use maps to do so - these generally > aren't > > > the > > > > > > primary consumer/owner of the request, but hangers on that may want to > > > muck > > > > > with > > > > > > them at some point. > > > > > > > > > > > > I suspect here it would mostly be useful if you're POSTing data and > > don't > > > > care > > > > > > about anything other than whether the requests succeeded or failed. > > > > > > > > > > > > I'm fine not supporting that use case (An embedder could pretty > > trivially > > > > make > > > > > > an adapter that adds support, if needed), though then I'd argue it's > > > simpler > > > > > to > > > > > > never pass in the UrlRequest. Misha: Any thoughts? > > > > > > > > > > Hmm, if we never pass in UrlRequest to listener callbacks, then listener > > > must > > > > > explicitly hold on to it, > > > > > and at some point it could end up with some semi-destroyed object. > > > > > This doesn't seem nice. > > > > > > > > If you ever want to be able cancel a request without waiting to get data > > from > > > > it, you actually have to hold onto a reference to it. > > > > > > That's true, but It still feels like unnecessary limitation. I can imagine > > > current API allowing some kind of 'tracing listener' - > > > one that logs callbacks prior to forwarding them to specific listener. > > > > > > If we remove URLRequest that would not be possible. > > > FWIW fnk@ has previously pointed to jetty interface example, and it also > > > explicitly passes request to callback: > > > > > > http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/client/a... > > > > Yes, that's true. However, that's a rare case - cancelling http requests > without > > getting headers is pretty strange, and vanilla HTTP's cancel kills a > connection. > > The only circumstance I could see where cancelling with no data makes sense is > > if you're racing GETs. As for jetty, their request object 1. participates in > the > > regular java GC cycle and 2. has methods like getParams, which is the sort of > > thing we put on the responseinfo. > > Is it really that rare? Just think about shutdown / suspend, or the user > navigating to another view / video / whatever, or timing out requests. G+ never cancels requests. I think it's worth making the cancel() method idempotent, and just be a no-op after the request finishes.
https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:59: private long mTotalReceivedBytes = 0; On 2014/09/29 18:10:34, Charles wrote: > On 2014/09/29 17:57:36, mef wrote: > > On 2014/09/26 22:52:26, Charles wrote: > > > Final? And where is this being populated? > > > > Not Final as it is now updated in OnComplete(). > > I don't particularly like this, so if there is a better pattern I'm open for > > suggestions. > > Split ResponseInfo into two interfaces, make this implement both, then define > the interface that you can actually use in the callback method. sgtm, so everything except onComplete will get basic ResponseInfo and OnComplete will get ResponseInfoWithTotalReceivedBytes, but what about 'final'?
On 2014/09/29 21:18:21, mef wrote: > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java > (right): > > https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... > components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:59: > private long mTotalReceivedBytes = 0; > On 2014/09/29 18:10:34, Charles wrote: > > On 2014/09/29 17:57:36, mef wrote: > > > On 2014/09/26 22:52:26, Charles wrote: > > > > Final? And where is this being populated? > > > > > > Not Final as it is now updated in OnComplete(). > > > I don't particularly like this, so if there is a better pattern I'm open for > > > suggestions. > > > > Split ResponseInfo into two interfaces, make this implement both, then define > > the interface that you can actually use in the callback method. > > sgtm, so everything except onComplete will get basic ResponseInfo and OnComplete > will get ResponseInfoWithTotalReceivedBytes, but what about 'final'? onError doesn't need a request either, I think. Final we can live without, as long as people can't call the method before it's populated. My suggestion of dual interfaces solves that.
Thanks, PTAL. Per conversation with Matt I've kept UrlRequestListener request parameters. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:59: private long mTotalReceivedBytes = 0; On 2014/09/29 21:18:21, mef wrote: > On 2014/09/29 18:10:34, Charles wrote: > > On 2014/09/29 17:57:36, mef wrote: > > > On 2014/09/26 22:52:26, Charles wrote: > > > > Final? And where is this being populated? > > > > > > Not Final as it is now updated in OnComplete(). > > > I don't particularly like this, so if there is a better pattern I'm open for > > > suggestions. > > > > Split ResponseInfo into two interfaces, make this implement both, then define > > the interface that you can actually use in the callback method. > > sgtm, so everything except onComplete will get basic ResponseInfo and OnComplete > will get ResponseInfoWithTotalReceivedBytes, but what about 'final'? Done. https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/160001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:36: String userAgent, HttpUrlRequestFactoryConfig config) { On 2014/09/29 17:57:37, mef wrote: > On 2014/09/26 22:52:26, Charles wrote: > > On 2014/09/26 19:23:52, mef wrote: > > > I wonder whether |userAgent| should be a separate argument or part of the > > > |config|? > > > > I vote for config. > > SGTM, will do. Done.
lgtm
lgtm
On 2014/09/30 20:27:11, Charles wrote: > lgtm woot! Thanks!
https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:86: base::android::InitApplicationContext(env, scoped_context); Just curious. Will embedders create multiple request adapters inside a single application? "base::android::InitApplicationContext" is only supposed to be invoked once though. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:108: DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); nit: include "base/macros.h".
https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:86: base::android::InitApplicationContext(env, scoped_context); On 2014/10/01 14:40:37, xunjieli wrote: > Just curious. Will embedders create multiple request adapters inside a single > application? I think that is possible. > "base::android::InitApplicationContext" is only supposed to be > invoked once though. It seems that it is Ok to do it multiple times as long as it is the same context:https://code.google.com/p/chromium/codesearch#chromium/src/base/android/jni_android.cc&l=116 We can't do it in JNI_OnLoad as it doesn't get the context, but I'm open to better ideas. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:108: DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); On 2014/10/01 14:40:37, xunjieli wrote: > nit: include "base/macros.h". Hmm, I think it is not necessary as long as it is included in matching .h file.
On 2014/10/01 20:41:31, mef wrote: > https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... > File components/cronet/android/cronet_url_request_context.cc (right): > > https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... > components/cronet/android/cronet_url_request_context.cc:86: > base::android::InitApplicationContext(env, scoped_context); > On 2014/10/01 14:40:37, xunjieli wrote: > > Just curious. Will embedders create multiple request adapters inside a single > > application? > I think that is possible. > > > "base::android::InitApplicationContext" is only supposed to be > > invoked once though. > It seems that it is Ok to do it multiple times as long as it is the same > context:https://code.google.com/p/chromium/codesearch#chromium/src/base/android/jni_android.cc&l=116 > > We can't do it in JNI_OnLoad as it doesn't get the context, but I'm open to > better ideas. > > https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... > File components/cronet/android/cronet_url_request_context_adapter.cc (right): > > https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... > components/cronet/android/cronet_url_request_context_adapter.cc:108: > DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); > On 2014/10/01 14:40:37, xunjieli wrote: > > nit: include "base/macros.h". > > Hmm, I think it is not necessary as long as it is included in matching .h file. Thanks for explaining! lgtm
Sorry for the long delay - finally started reviewing this yesterday, hope to get back to you later today.
Partial comments...One is a fairly significant refactor, which is what I'm sending them now. Also, we need more tests, to make sure we're reading the URLRequest's state machine properly - it's a weird interface, so very easy to get things wrong. Best to just copy content/browser/loader/resource_loader's logic exactly, for what's success and what's a failure. Have to check request->status() a lot. * Request fails before receiving headers (Synchronous and asynchronously, if sync failures are possible). * Request fails while reading body (Synchronous and asynchronously, if sync failures are possible - ResourceLoader certainly handles them) * Request cancelled before receiving headers. * Request cancelled when headers received. * Request cancelled while reading body (Body during a callback, and between callbacks). * Request without a body. * Head request with a non-zero content-length (Body shouldn't be read). https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:58: cronet::Java_CronetUrlRequest_onResponseStarted(env, owner_); Should check if request->status().is_success() is true. If not, should call onError. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:64: if (bytes_read >= 0) { "&& request_->status().is_success()" https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:102: jlong urlRequestContextAdapter, We should probably be using C++ style guide style for all arguments. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:153: /* synchronized */ None of these are synchronized, are they? https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:187: } nit: --braces. (Goes for all the one-line if statements) https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:117: } nit: Preferred style seems to be not to use braces on one-line if statements. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:159: } nit: Preferred style seems to be not to use braces on one-line if statements. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:31: class CronetURLRequestAdapter : public net::URLRequest::Delegate { I think we should make the JniCronetURLRequestAdapterDelegate the URLRequest::Delegate. It makes life much simpler to have all knowledge of how the URLRequest talks to the delegate in one place, and also limits what the adapter does on the network thread. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:27: */ Android style guide is unclear when "//" comments are allowed (Guide only uses them for TODOs), but it does use "/** blah */" style a lot, for single-line comments. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:30: private final String mUrl; Maybe mInitialUrl, with a comment that it's before any redirects are followed? https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:21: public class CronetUrlRequestContext extends UrlRequestFactory { Think we should be consistent here, use Factory for both, or Context for both. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:33: */ nit: Fix indent. Also, does this comment really add anything? https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ExtendedResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ExtendedResponseInfo.java:11: public interface ExtendedResponseInfo extends ResponseInfo { Maybe ResponseCompleteInfo? https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:53: * Returns true if the factory is enabled. "@return True if..." https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:53: * Returns true if the factory is enabled. What does it mean for a factory to be enabled? https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:58: * Returns a human-readable name of the factory. @return
Thanks, Matt! I'll add more tests and appropriate logic from url_request_loader in the next rev. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:58: cronet::Java_CronetUrlRequest_onResponseStarted(env, owner_); On 2014/10/02 15:24:09, mmenke wrote: > Should check if request->status().is_success() is true. If not, should call > onError. Per discussion moved status checks to cronet_url_request_adapter.cc (also below). https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:64: if (bytes_read >= 0) { On 2014/10/02 15:24:09, mmenke wrote: > "&& request_->status().is_success()" Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:102: jlong urlRequestContextAdapter, On 2014/10/02 15:24:09, mmenke wrote: > We should probably be using C++ style guide style for all arguments. Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:153: /* synchronized */ On 2014/10/02 15:24:09, mmenke wrote: > None of these are synchronized, are they? Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:187: } On 2014/10/02 15:24:08, mmenke wrote: > nit: --braces. (Goes for all the one-line if statements) Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:22: static const size_t kBufferSizeIncrement = 8192; should the buffer size be controllable by embedder? Maybe via config? https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:117: } On 2014/10/02 15:24:09, mmenke wrote: > nit: Preferred style seems to be not to use braces on one-line if statements. Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:159: } On 2014/10/02 15:24:09, mmenke wrote: > nit: Preferred style seems to be not to use braces on one-line if statements. Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:31: class CronetURLRequestAdapter : public net::URLRequest::Delegate { On 2014/10/02 15:24:09, mmenke wrote: > I think we should make the JniCronetURLRequestAdapterDelegate the > URLRequest::Delegate. It makes life much simpler to have all knowledge of how > the URLRequest talks to the delegate in one place, and also limits what the > adapter does on the network thread. Acknowledged. Per conversation we've agreed to have CronetURLRequestAdapter contain all the knowledge and CronetURLRequestAdapterDelegate just provide JNI glue for that. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:27: */ On 2014/10/02 15:24:09, mmenke wrote: > Android style guide is unclear when "//" comments are allowed (Guide only uses > them for TODOs), but it does use "/** blah */" style a lot, for single-line > comments. Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:30: private final String mUrl; On 2014/10/02 15:24:09, mmenke wrote: > Maybe mInitialUrl, with a comment that it's before any redirects are followed? Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:21: public class CronetUrlRequestContext extends UrlRequestFactory { On 2014/10/02 15:24:09, mmenke wrote: > Think we should be consistent here, use Factory for both, or Context for both. I agree, but I'm thorn. 'Context' matches //net, but Factory seems to be popular Java concept. :) https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:33: */ On 2014/10/02 15:24:09, mmenke wrote: > nit: Fix indent. Also, does this comment really add anything? Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ExtendedResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ExtendedResponseInfo.java:11: public interface ExtendedResponseInfo extends ResponseInfo { On 2014/10/02 15:24:09, mmenke wrote: > Maybe ResponseCompleteInfo? Maybe. I was weaseling my way out in the case if we may want to pass it prior to completion, e.g. onDataReceived. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:53: * Returns true if the factory is enabled. On 2014/10/02 15:24:09, mmenke wrote: > "@return True if..." Done. https://codereview.chromium.org/586143002/diff/220001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:58: * Returns a human-readable name of the factory. On 2014/10/02 15:24:09, mmenke wrote: > @return Done.
Misha: This isn't really a full pass, just what I have at the moment. Feel free to wait for me to finish on Monday. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:7: #include <string.h> Are we using any functions from string.h? https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:12: #include "base/strings/string_number_conversions.h" Are we using things header? https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:16: #include "net/base/upload_bytes_element_reader.h" I don't believe we're currently using either of these upload classes. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:22: static const size_t kBufferSizeIncrement = 8192; On 2014/10/02 22:07:43, mef wrote: > should the buffer size be controllable by embedder? Maybe via config? Think we should start with a fixed size, for now. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:22: static const size_t kBufferSizeIncrement = 8192; Should we use 32k? That's what Chromium uses. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:136: delegate_->OnRedirect(this, redirect_info.new_url); We should probably be exposing the redirect's status code, too. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:208: bool CronetURLRequestAdapter::CheckStatus(net::URLRequest* request) { DCHECK_NE(net::URLRequestStatus::IO_PENDING, url_request_->status().status())? https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:209: DCHECK(request == url_request_); DCHECK_EQ https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:214: url_request_->Cancel(); No need to cancel a failed request. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:207: const std::string& file_name) { These should actually be run on the network thread (Could create the NetLog on the UI thread instead, and then pass it into the context, but that seems beyond the scope of this CL). So StopNetLog should also be on the other thread as well. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:228: } // namespace cronet nit: Blank line before end of namespace. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:17: #include "net/url_request/url_request_context.h" Can we just forward declare this? https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:53: virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() Need to forward declare this. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:196: return; All of these values change after every redirect, so caching like this doesn't really work. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:238: mResponseInfo.mUrlChain.add(newLocation); Is it safe to update this structure? If the embedder keeps it around, it's not safe for them to access the read-only structure on another thread while we're modifying it. Also kinda weird to change stuff out from underneath them as well.
some style nits. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:195: if (mResponseInfo != null) It is recommended on http://source.android.com/source/code-style.html, section "Use Standard Brace Style", that single line if statement like this should still have brackets. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:34: if (mUrlRequestContextAdapter == 0) nit: brackets according to http://source.android.com/source/code-style.html . https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:38: if (config.userAgent().isEmpty()) nit: brackets according to http://source.android.com/source/code-style.html .
Thanks, PTAL. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:7: #include <string.h> On 2014/10/03 20:45:59, mmenke wrote: > Are we using any functions from string.h? Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:12: #include "base/strings/string_number_conversions.h" On 2014/10/03 20:45:58, mmenke wrote: > Are we using things header? Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:16: #include "net/base/upload_bytes_element_reader.h" On 2014/10/03 20:45:58, mmenke wrote: > I don't believe we're currently using either of these upload classes. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:22: static const size_t kBufferSizeIncrement = 8192; On 2014/10/03 20:45:59, mmenke wrote: > Should we use 32k? That's what Chromium uses. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:22: static const size_t kBufferSizeIncrement = 8192; On 2014/10/03 20:45:59, mmenke wrote: > On 2014/10/02 22:07:43, mef wrote: > > should the buffer size be controllable by embedder? Maybe via config? > > Think we should start with a fixed size, for now. Acknowledged. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:136: delegate_->OnRedirect(this, redirect_info.new_url); On 2014/10/03 20:45:58, mmenke wrote: > We should probably be exposing the redirect's status code, too. Done. ResponseInfo contains httpStatusCode and is now regenerated on each redirect. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:208: bool CronetURLRequestAdapter::CheckStatus(net::URLRequest* request) { On 2014/10/03 20:45:58, mmenke wrote: > DCHECK_NE(net::URLRequestStatus::IO_PENDING, url_request_->status().status())? Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:209: DCHECK(request == url_request_); On 2014/10/03 20:45:59, mmenke wrote: > DCHECK_EQ Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:214: url_request_->Cancel(); On 2014/10/03 20:45:59, mmenke wrote: > No need to cancel a failed request. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:207: const std::string& file_name) { On 2014/10/03 20:45:59, mmenke wrote: > These should actually be run on the network thread (Could create the NetLog on > the UI thread instead, and then pass it into the context, but that seems beyond > the scope of this CL). > > So StopNetLog should also be on the other thread as well. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:228: } // namespace cronet On 2014/10/03 20:45:59, mmenke wrote: > nit: Blank line before end of namespace. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:17: #include "net/url_request/url_request_context.h" On 2014/10/03 20:45:59, mmenke wrote: > Can we just forward declare this? Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:53: virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() On 2014/10/03 20:45:59, mmenke wrote: > Need to forward declare this. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:195: if (mResponseInfo != null) On 2014/10/03 20:58:39, xunjieli wrote: > It is recommended on http://source.android.com/source/code-style.html, section > "Use Standard Brace Style", that single line if statement like this should still > have brackets. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:196: return; On 2014/10/03 20:45:59, mmenke wrote: > All of these values change after every redirect, so caching like this doesn't > really work. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:238: mResponseInfo.mUrlChain.add(newLocation); On 2014/10/03 20:45:59, mmenke wrote: > Is it safe to update this structure? If the embedder keeps it around, it's not > safe for them to access the read-only structure on another thread while we're > modifying it. Also kinda weird to change stuff out from underneath them as > well. Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:34: if (mUrlRequestContextAdapter == 0) On 2014/10/03 20:58:39, xunjieli wrote: > nit: brackets according to http://source.android.com/source/code-style.html . Done. https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/240001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:38: if (config.userAgent().isEmpty()) On 2014/10/03 20:58:39, xunjieli wrote: > nit: brackets according to http://source.android.com/source/code-style.html . Done.
Patchset #14 (id:280001) has been deleted
Patchset #13 (id:260001) has been deleted
https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:37: } nit: Blank line after function. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:109: DCHECK(context != NULL); Can this be DCHECK_NE(nullptr, context); now? https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:134: if (request != NULL) Can this happen when the request is NULL? It doesn't look like it to me. If it can't happen, should use DCHECKs instead. If it can happen, since lifetimes are managed Java-side, should probably have the logic to handle the case in Java, too, and throw an exception if it happens instead of handling it here. Same goes for most of the next methods as well. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:197: if (request == NULL) None of these accessors can be called when the request is NULL, since they're called on the network thread in response to network events for the request itself. Should just place these tests with DCHECKs, and make a DCHECK that we're on the network thread as well. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:43: CHECK(url_request_ == NULL); CHECK_NE(nullptr, url_request_);? Though since we delete the adapter jsut before the request, can we just delete the request here, too? See other comment. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:113: canceled_ = true; Suggest setting this on the network thread instead, and then not calling into the delegate at all if it's true. Would have to check it on the network thread, too, in that case. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:124: base::Bind(&CronetURLRequestAdapter::DestroyOnNetworkThread, this)); Can we just use DeleteSoon and get rid of DestroyOnNetworkThread? Doesn't exactly save us much, but since we have a method to do it already.... https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:132: if (!CheckStatus(request)) Not needed. Can actually just have a DCHECK(request->status().is_success()); here https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:156: void CronetURLRequestAdapter::StartOnNetworkThread() { Could we add DCHECKs to all of these that should be called on the network thread? And maybe DCHECKs on the ones call solely by the embedder that they're *not* called on the network thread? (Since the embedder can't call into us there - those ones are more about documentation, and making it clear they're not called on the network thread, than enforcing that they aren't). https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:157: if (canceled_) Checking this on the network thread isn't threadsafe, unless it's set there as well. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:220: self->url_request_.reset(); Can we just do this in the destructor? https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:83: int error_code() const { return error_code_; } Not used. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:89: int64 content_length() const { return expected_size_; } Can tear this out, all the way up through nativeGetContentLength. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:92: std::string content_type() const { return content_type_; } Can tear this out, all the way up through nativeGetContentType. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:95: std::string GetHeader(const std::string& name) const; Not used. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:101: size_t bytes_read() const { return bytes_read_; } Not used https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:141: net::HttpRequestHeaders headers_; Suggest renaming this, and associated functions, to use request_headers_, to make it clear they're not the response headers. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:145: int total_bytes_read_; These two are not used. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:146: int error_code_; Not used. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:148: std::string content_type_; Not used. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:132: public void setHttpMethod(String method) { Should we throw some exception on these setters if Start() has been called already? https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:153: public void cancel() { I suggest two cancels: One for errors, which calls back into the Listener with an error, and one for external use, which prevents all subsequent callbacks into the Listener (We can check it Java-side on all callbacks, so we have a guarantee that if it's called on the executor thread, we won't call into the Listener afterwards). https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:159: return mCanceled; mCanceled should only be read and set on one thread. Currently, it's set on the net thread, and read here by the embedder on the executor thread. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:290: mOnDataReceivedTask = new OnDataReceivedRunnable(); Do we save much by reusing this task? Seems cleaner just to create a new one. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:291: mOnDataReceivedTask.mByteBuffer = byteBuffer; Should we check if this is NULL? If you opt not to reuse the task per earlier comment, that's fine as well. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:399: nit: Remove extra blank lines. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:40: /** True if the response came from the cache. Requests that were Move first sentence down to next line. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:42: * considered cached. Add something along the lines of "When a resource is retrieved from the cache (Whether it was revalidated or not), getHttpStatusCode returns the original status code." Suggest putting it here rather than above getHttpStatusCode so that if other fields have the same property, can list them all here - should figure out what getAllHeaders returns in that case, too (Old headers, new, or old with new cache expiration into). https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:49: * Returns empty when using plain http or https. Add a TODO about figuring out what this returns in the cached case, both with and without a revalidation request. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:35: public static UrlRequestFactory createFactory(Context context, Should have a comment here. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:35: public static UrlRequestFactory createFactory(Context context, Don't think we really get anything by having two functions here. My suggestion is to merge them, particularly since the both have logic to create the wrapper. i.e. if (config.legacyMode()) { try { ... if (cronetFactory.isEnabled()) { factory = cronetFactory; } } catch... } if (!factory) { // Try to create wrapper here. } Log.i(...); return factory; Alternatively, move the legacyMode check and all creation logic into createCronetFactory. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:79: // Leave as null nit: +. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:79: // Leave as null Should we even have this case for now, or just throw an exception? Think the exception means failure can be handled consistently, as opposed to needing a null check before we've implemented a wrapper around HttpURLConnection, and catching an exception afterwards. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:23: nit: Remove extra blank line
Thanks! I've addressed most of the comments. I would like to better understand usage of two request 'Cancel' methods and your proposal of factory changes. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:37: } On 2014/10/06 18:28:43, mmenke wrote: > nit: Blank line after function. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:109: DCHECK(context != NULL); On 2014/10/06 18:28:44, mmenke wrote: > Can this be DCHECK_NE(nullptr, context); now? Probably. Is there something special that's required for nullptr? I'm getting strange compilation errors. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:134: if (request != NULL) On 2014/10/06 18:28:44, mmenke wrote: > Can this happen when the request is NULL? It doesn't look like it to me. If it > can't happen, should use DCHECKs instead. If it can happen, since lifetimes are > managed Java-side, should probably have the logic to handle the case in Java, > too, and throw an exception if it happens instead of handling it here. > > Same goes for most of the next methods as well. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:197: if (request == NULL) On 2014/10/06 18:28:43, mmenke wrote: > None of these accessors can be called when the request is NULL, since they're > called on the network thread in response to network events for the request > itself. Should just place these tests with DCHECKs, and make a DCHECK that > we're on the network thread as well. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:43: CHECK(url_request_ == NULL); On 2014/10/06 18:28:44, mmenke wrote: > CHECK_NE(nullptr, url_request_);? Though since we delete the adapter jsut > before the request, can we just delete the request here, too? See other > comment. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:113: canceled_ = true; On 2014/10/06 18:28:44, mmenke wrote: > Suggest setting this on the network thread instead, and then not calling into > the delegate at all if it's true. Would have to check it on the network thread, > too, in that case. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:124: base::Bind(&CronetURLRequestAdapter::DestroyOnNetworkThread, this)); On 2014/10/06 18:28:44, mmenke wrote: > Can we just use DeleteSoon and get rid of DestroyOnNetworkThread? Doesn't > exactly save us much, but since we have a method to do it already.... Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:132: if (!CheckStatus(request)) On 2014/10/06 18:28:44, mmenke wrote: > Not needed. Can actually just have a DCHECK(request->status().is_success()); > here Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:156: void CronetURLRequestAdapter::StartOnNetworkThread() { On 2014/10/06 18:28:44, mmenke wrote: > Could we add DCHECKs to all of these that should be called on the network > thread? > > And maybe DCHECKs on the ones call solely by the embedder that they're *not* > called on the network thread? (Since the embedder can't call into us there - > those ones are more about documentation, and making it clear they're not called > on the network thread, than enforcing that they aren't). Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:157: if (canceled_) On 2014/10/06 18:28:44, mmenke wrote: > Checking this on the network thread isn't threadsafe, unless it's set there as > well. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:220: self->url_request_.reset(); On 2014/10/06 18:28:44, mmenke wrote: > Can we just do this in the destructor? Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:83: int error_code() const { return error_code_; } On 2014/10/06 18:28:44, mmenke wrote: > Not used. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:89: int64 content_length() const { return expected_size_; } On 2014/10/06 18:28:44, mmenke wrote: > Can tear this out, all the way up through nativeGetContentLength. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:92: std::string content_type() const { return content_type_; } On 2014/10/06 18:28:44, mmenke wrote: > Can tear this out, all the way up through nativeGetContentType. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:95: std::string GetHeader(const std::string& name) const; On 2014/10/06 18:28:44, mmenke wrote: > Not used. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:101: size_t bytes_read() const { return bytes_read_; } On 2014/10/06 18:28:44, mmenke wrote: > Not used Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:141: net::HttpRequestHeaders headers_; On 2014/10/06 18:28:44, mmenke wrote: > Suggest renaming this, and associated functions, to use request_headers_, to > make it clear they're not the response headers. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:145: int total_bytes_read_; On 2014/10/06 18:28:44, mmenke wrote: > These two are not used. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:146: int error_code_; On 2014/10/06 18:28:44, mmenke wrote: > Not used. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:148: std::string content_type_; On 2014/10/06 18:28:44, mmenke wrote: > Not used. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:132: public void setHttpMethod(String method) { On 2014/10/06 18:28:45, mmenke wrote: > Should we throw some exception on these setters if Start() has been called > already? Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:159: return mCanceled; On 2014/10/06 18:28:44, mmenke wrote: > mCanceled should only be read and set on one thread. Currently, it's set on the > net thread, and read here by the embedder on the executor thread. Done. Moved setter to executor thread. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:290: mOnDataReceivedTask = new OnDataReceivedRunnable(); On 2014/10/06 18:28:45, mmenke wrote: > Do we save much by reusing this task? Seems cleaner just to create a new one. I agree, but clm@ has pointed out possible memory thrashing. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:291: mOnDataReceivedTask.mByteBuffer = byteBuffer; On 2014/10/06 18:28:45, mmenke wrote: > Should we check if this is NULL? If you opt not to reuse the task per earlier > comment, that's fine as well. Umm, could you elaborate, what do you mean by 'this'? :) https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:399: On 2014/10/06 18:28:44, mmenke wrote: > nit: Remove extra blank lines. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:40: /** True if the response came from the cache. Requests that were On 2014/10/06 18:28:45, mmenke wrote: > Move first sentence down to next line. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:42: * considered cached. On 2014/10/06 18:28:45, mmenke wrote: > Add something along the lines of "When a resource is retrieved from the cache > (Whether it was revalidated or not), getHttpStatusCode returns the original > status code." > > Suggest putting it here rather than above getHttpStatusCode so that if other > fields have the same property, can list them all here - should figure out what > getAllHeaders returns in that case, too (Old headers, new, or old with new cache > expiration into). Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:49: * Returns empty when using plain http or https. On 2014/10/06 18:28:45, mmenke wrote: > Add a TODO about figuring out what this returns in the cached case, both with > and without a revalidation request. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:35: public static UrlRequestFactory createFactory(Context context, On 2014/10/06 18:28:45, mmenke wrote: > Should have a comment here. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:23: On 2014/10/06 18:28:45, mmenke wrote: > nit: Remove extra blank line Done.
I think this looks pretty reasonable. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.cc (right): https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:167: return false; Hrm...I don't think this makes any sense. For errors/hangs "on" redirects, should redirect to another URL, and have that one hang/fail on start. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:192: void URLRequestMockHTTPJob::GetRawHeaders(std::string raw_headers) { While you're here, think this should probably be renamed - maybe just SetHeadersAndStart? And also make the argument a "const std::string&" https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:199: return; Hrm...wonder if we should set the headers or not in this case... I'd say not, unless we discover we need them later (Some errors do come with headers, I suppose). https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.h (right): https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.h:62: static GURL GetMockUrl(const base::FilePath& path); Suggest adding GetMockUrlWithFailure(const base::FilePath& path, Phase phase, int net_error); (Adding a phase enum to this class) And mentioning that ERR_IO_PENDING results in a hung request. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.h:85: bool ReportMockErrorFromQuery(const std::string& step); Think this function name is a little weird. Maybe: MaybeReportErrorOnStep. Should also document it here, and its dependence on the URL's query string..
Matt, thanks! I've tweaked the mock http job, added tests to match, and will appreciate your comments. In the meanwhile I'll split the 'cancel' and add tests for that. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.cc (right): https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:167: return false; On 2014/10/16 16:39:34, mmenke wrote: > Hrm...I don't think this makes any sense. For errors/hangs "on" redirects, > should redirect to another URL, and have that one hang/fail on start. Done. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:192: void URLRequestMockHTTPJob::GetRawHeaders(std::string raw_headers) { On 2014/10/16 16:39:34, mmenke wrote: > While you're here, think this should probably be renamed - maybe just > SetHeadersAndStart? > > And also make the argument a "const std::string&" Done. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:199: return; On 2014/10/16 16:39:34, mmenke wrote: > Hrm...wonder if we should set the headers or not in this case... I'd say not, > unless we discover we need them later (Some errors do come with headers, I > suppose). Done. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.h (right): https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.h:62: static GURL GetMockUrl(const base::FilePath& path); On 2014/10/16 16:39:34, mmenke wrote: > Suggest adding GetMockUrlWithFailure(const base::FilePath& path, Phase phase, > int net_error); (Adding a phase enum to this class) > > And mentioning that ERR_IO_PENDING results in a hung request. Done.
Some style nits from me. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:103: jlong url_request_context_adapter, nit: I learned from eroman@, that for arguments of native functions called by Java side, we should use a "j" prefix. For instance, here we will have jenv, jobject, jurl_request_context_adapter, jurl_string, etc to emphasize the fact these arguments are passed from the java side. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:121: return reinterpret_cast<jlong>(adapter); nit: I find the naming is a little confusing. Here we have CronetURLRequestAdapter as "adapter", later in the code we have it as "request". What about we rename those to "request_adapter"? Then, there won't be any ambiguity. Also I find the fact that we call the ContextAdapter by "context" a little misleading too. What about renaming to "context_adapter"? https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:217: if (headers == NULL) nit: I think it is recommended for new code, nullptr should be used in place of NULL. http://chromium-cpp.appspot.com/ https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:20: class SingleThreadTaskRunner; nit: new line before ending a namespace. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object and the Chromium |URLRequest| nit: s/and/to ? https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:41: virtual void OnRedirect(CronetURLRequestAdapter* request, nit: I find using a longer name might improve the readability, eg. "request_adapter". https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (left): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:112: // tasks, nit: formatting. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:133: jlong urlRequestContextAdapter, nit: c_style_naming with a "j" prefix. eg. jurl_request_context_adapter https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:93: CronetURLRequestContextAdapter* adapter = new CronetURLRequestContextAdapter( nit: There are two types of adapter, one is for the request, the other one is for the context. Can we rename |adapter| to |context_adapter| to make it clearer? https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (left): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:140: DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()); nit: suggest adding DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()) to *OnNetworkThread() methods. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:40: CronetURLRequestContextAdapter* context) = 0; nit: s/context/context_adapter? https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:73: // Initializes |context_| on the Network thread. The reason I suggested renaming is that I always confuse the |context| in the argument with this member variable |context_|. The former is an adapter, while the latter is context. But they have the same name. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:44: if (!isCanceled()) nit: brackets. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:215: // Private methods called by native library. nit: this piece of code is technically a part of the library. Maybe change the comment to say "Private methods called by the native code."? Also this comment should be moved below |onCalledByNativeException|, since |onCalledByNativeException| is not called by native code. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:241: * @param info Response information. nit: stale param. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:254: if (!isCanceled()) nit: brackets. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:268: * @param info Response information. nit: stale param. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:279: if (!isCanceled()) nit: brackets. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:300: if (mOnDataReceivedTask == null) nit: brackets. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:307: * Called when request is complete, no callbacks will be called afterwards. nit: param |canceled| missing from the doc. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:329: * Called when error has occured, no callbacks will be called afterwards. nit: |error| missing from doc. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:19: String getUrl(); Does the Url string contain the scheme? Might be useful to add one line about the format here. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:40: public int httpResponseDataLength = 0; nit: mmenke@ once suggested to use "m" prefix for all member variables including public ones. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:55: URL newLocation) { nit: indent. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:205: MOCK_CRONET_TEST_SUCCESS_URL + "?readasync=-5"); indent: +4. https://codereview.chromium.org/586143002/diff/400001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.h (right): https://codereview.chromium.org/586143002/diff/400001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.h:44: virtual bool ReadRawData(IOBuffer* buf, nit: remove virtual.
Thanks, PTAL! https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:153: public void cancel() { On 2014/10/06 18:28:44, mmenke wrote: > I suggest two cancels: One for errors, which calls back into the Listener with > an error, and one for external use, which prevents all subsequent callbacks into > the Listener (We can check it Java-side on all callbacks, so we have a guarantee > that if it's called on the executor thread, we won't call into the Listener > afterwards). Done. https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.h (right): https://codereview.chromium.org/586143002/diff/380001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.h:85: bool ReportMockErrorFromQuery(const std::string& step); On 2014/10/16 16:39:34, mmenke wrote: > Think this function name is a little weird. Maybe: MaybeReportErrorOnStep. > Should also document it here, and its dependence on the URL's query string.. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:103: jlong url_request_context_adapter, On 2014/10/17 00:31:34, xunjieli wrote: > nit: I learned from eroman@, that for arguments of native functions called by > Java side, we should use a "j" prefix. For instance, here we will have jenv, > jobject, jurl_request_context_adapter, jurl_string, etc to emphasize the fact > these arguments are passed from the java side. Ah, nice to know! Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:121: return reinterpret_cast<jlong>(adapter); On 2014/10/17 00:31:34, xunjieli wrote: > nit: I find the naming is a little confusing. Here we have > CronetURLRequestAdapter as "adapter", later in the code we have it as "request". > What about we rename those to "request_adapter"? Then, there won't be any > ambiguity. Also I find the fact that we call the ContextAdapter by "context" a > little misleading too. What about renaming to "context_adapter"? sgtm, done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:217: if (headers == NULL) On 2014/10/17 00:31:34, xunjieli wrote: > nit: I think it is recommended for new code, nullptr should be used in place of > NULL. http://chromium-cpp.appspot.com/ Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:20: class SingleThreadTaskRunner; On 2014/10/17 00:31:34, xunjieli wrote: > nit: new line before ending a namespace. Done. Although it looks funny. Should there be a newline after beginning of namespace? https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object and the Chromium |URLRequest| On 2014/10/17 00:31:34, xunjieli wrote: > nit: s/and/to ? Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:41: virtual void OnRedirect(CronetURLRequestAdapter* request, On 2014/10/17 00:31:34, xunjieli wrote: > nit: I find using a longer name might improve the readability, eg. > "request_adapter". Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (left): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:112: // tasks, On 2014/10/17 00:31:34, xunjieli wrote: > nit: formatting. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:133: jlong urlRequestContextAdapter, On 2014/10/17 00:31:35, xunjieli wrote: > nit: c_style_naming with a "j" prefix. eg. jurl_request_context_adapter Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:93: CronetURLRequestContextAdapter* adapter = new CronetURLRequestContextAdapter( On 2014/10/17 00:31:34, xunjieli wrote: > nit: There are two types of adapter, one is for the request, the other one is > for the context. Can we rename |adapter| to |context_adapter| to make it > clearer? Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (left): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:140: DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()); On 2014/10/17 00:31:35, xunjieli wrote: > nit: suggest adding DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()) to > *OnNetworkThread() methods. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:40: CronetURLRequestContextAdapter* context) = 0; On 2014/10/17 00:31:35, xunjieli wrote: > nit: s/context/context_adapter? Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:73: // Initializes |context_| on the Network thread. On 2014/10/17 00:31:35, xunjieli wrote: > The reason I suggested renaming is that I always confuse the |context| in the > argument with this member variable |context_|. The former is an adapter, while > the latter is context. But they have the same name. Acknowledged. Should we rename |context_| into |request_context_|? https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:44: if (!isCanceled()) On 2014/10/17 00:31:35, xunjieli wrote: > nit: brackets. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:215: // Private methods called by native library. On 2014/10/17 00:31:35, xunjieli wrote: > nit: this piece of code is technically a part of the library. Maybe change the > comment to say "Private methods called by the native code."? > Also this comment should be moved below |onCalledByNativeException|, since > |onCalledByNativeException| is not called by native code. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:241: * @param info Response information. On 2014/10/17 00:31:35, xunjieli wrote: > nit: stale param. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:254: if (!isCanceled()) On 2014/10/17 00:31:35, xunjieli wrote: > nit: brackets. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:268: * @param info Response information. On 2014/10/17 00:31:35, xunjieli wrote: > nit: stale param. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:279: if (!isCanceled()) On 2014/10/17 00:31:35, xunjieli wrote: > nit: brackets. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:300: if (mOnDataReceivedTask == null) On 2014/10/17 00:31:35, xunjieli wrote: > nit: brackets. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:307: * Called when request is complete, no callbacks will be called afterwards. On 2014/10/17 00:31:35, xunjieli wrote: > nit: param |canceled| missing from the doc. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:329: * Called when error has occured, no callbacks will be called afterwards. On 2014/10/17 00:31:35, xunjieli wrote: > nit: |error| missing from doc. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:19: String getUrl(); On 2014/10/17 00:31:35, xunjieli wrote: > Does the Url string contain the scheme? Might be useful to add one line about > the format here. Done. I think. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:40: public int httpResponseDataLength = 0; On 2014/10/17 00:31:35, xunjieli wrote: > nit: mmenke@ once suggested to use "m" prefix for all member variables including > public ones. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:55: URL newLocation) { On 2014/10/17 00:31:35, xunjieli wrote: > nit: indent. Done. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:205: MOCK_CRONET_TEST_SUCCESS_URL + "?readasync=-5"); On 2014/10/17 00:31:35, xunjieli wrote: > indent: +4. Done. https://codereview.chromium.org/586143002/diff/400001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.h (right): https://codereview.chromium.org/586143002/diff/400001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.h:44: virtual bool ReadRawData(IOBuffer* buf, On 2014/10/17 00:31:35, xunjieli wrote: > nit: remove virtual. Done.
https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:20: class SingleThreadTaskRunner; On 2014/10/17 20:19:42, mef wrote: > On 2014/10/17 00:31:34, xunjieli wrote: > > nit: new line before ending a namespace. > > Done. Although it looks funny. Should there be a newline after beginning of > namespace? http://google-styleguide.googlecode.com/svn/trunk/cppguide.html?showone=Forwa... does not explicitly mention this rule. I learned this from mmenke@. not sure about the beginning of namespace. https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:73: // Initializes |context_| on the Network thread. On 2014/10/17 20:19:42, mef wrote: > On 2014/10/17 00:31:35, xunjieli wrote: > > The reason I suggested renaming is that I always confuse the |context| in the > > argument with this member variable |context_|. The former is an adapter, while > > the latter is context. But they have the same name. > > Acknowledged. Should we rename |context_| into |request_context_|? I think that is fine. Since we only have one context, so it must be the request context :)
https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/400001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:20: class SingleThreadTaskRunner; On 2014/10/17 20:32:22, xunjieli wrote: > On 2014/10/17 20:19:42, mef wrote: > > On 2014/10/17 00:31:34, xunjieli wrote: > > > nit: new line before ending a namespace. > > > > Done. Although it looks funny. Should there be a newline after beginning of > > namespace? > > http://google-styleguide.googlecode.com/svn/trunk/cppguide.html?showone=Forwa... > does not explicitly mention this rule. I learned this from mmenke@. not sure > about the beginning of namespace. This falls under the keep with prevailing style rule, rather than some specific google-wide rule. And actually, forward declarations generally don't have extra blank lines before their end/after their start. In other cases, namespaces generally do, however (Except nested namespace, where style varies).
PTAL, I've added GetMockUrlWithFailure method and tests to cancel outside of listener.
Not a full pass, mostly just looked at tests. Want to pick it up first thing tomorrow. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:97: jobject owner_; Can we just make this a ScopedJavaGlobalRef? https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:121: VLOG(1) << "New chromium network request_adapter: " include base/logging.h https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/cronet_url_request.h (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/cronet_url_request.h:14: enum CronetUrlRequestPriority { As a reminder, there's a new way to do this. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:40: // Executor for Cronet callbacks nit: +. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:45: ConditionVariable mComplete = new ConditionVariable(); nit: Suggest a blank line between public and non-public variables. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:45: ConditionVariable mComplete = new ConditionVariable(); +private? Without it, I'm not sure if the outer class can access the field or not. For top-level classes, it means anything in the same package has access, I believe. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:64: mOnRedirectCalled = true; Should check if request == the request we got when we created a request, on all of these. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:64: mOnRedirectCalled = true; Should keep a count here, or better, a list of the info/newLocation pairs we've received. Should also check that we have the right number of them, and that they're correctly populated. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:64: mOnRedirectCalled = true; Check that mOnResponseStartedCalled is false? (Since we aren't at the top level, I suggest just keeping a list of errors we've seen, as strings). Also suggest adding a bunch of state checks to all of these, for that reason - fine to have some inline in your tests, too, but having them here allows for more complete testing of ordering. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:100: public void resetComplete() { Not used. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:131: assertTrue(listener.mHttpResponseDataLength != 0); Should check all the fields of ResponseInfo, and the response body, and that onComplete was called, and that there was no redirect. Should do a similar level of testing for most of these. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:172: public void testMockFailed() throws Exception { I believe this effectively just tests the same case as testMockStartSyncError, right? https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:183: public void testMockStartSyncError() throws Exception { This is actually async. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:242: public boolean mCancelFromDataReceived = false; My suggestion: Use one bool to indicate sync vs async cancellation, and 3 bools to indicate the phase (Or better, an enum, and take them as constructor args). Then each branch would just look like: super.onRedirect(request, info, newLocation); if (mCancelFromRedirect) { CancelSyncOrAsync(); } Think that makes the code a bit simpler, and less redundant. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.cc (right): https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:31: const char* kFailurePhase[]{ nit: Space before "{" https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:34: "readsync", // READ_SYNC nit: -2 indent. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:134: int net_error) { Maybe DCHECK phase is in the correct range? https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:220: bool URLRequestMockHTTPJob::MaybeReportErrorOnPhase(FailurePhase phase) { nit: phase -> current_phase (To try and make it clearer that, despite being a FailurePhase, it's not the phase to fail on) https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:221: DCHECK(phase >= START && phase <= READ_SYNC); Suggest a DCHECK_GE and DCHECK_LE https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:250: } Think this could be a bit simpler as: if (phase == START || phase == READ_SYNC) { ... return true; } SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); if (phase == READ_ASYNC) { ... }
https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:62: private long mTotalReceivedBytes = 0; I'm still nervous about changing this out from under the embedder - I could see reasons they might want to cache this structure, or fool with it on a thread other than the executor thread, and in either case, modifying this can get us into trouble. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:137: public void setHttpMethod(String method) { Should test this, and add header, now that we have a way to do so. Should also check the default method. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:162: public void cancel() { Should assert that we're called on the executor thread, here and in isCanceled and pause. And maybe a test to make sure that fails correctly? https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:214: private void checkNotStarted() { Should have a test where this fails, and make sure an exception is thrown. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:247: // Private methods called by the native code. Suggest making this more noticeable, like: //////////////////////////////////////////////// // // Private methods called by native code. // //////////////////////////////////////////////// (Using "//" because I think "/*" may make Javadoc sad) https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:414: assertTrue(urlRequest.isCanceled()); Hrm...Is there some way to validate the request was really cancelled? May not be a simple way to do it, just want to make sure that's the case. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:415: } Since we're handling it, should have yet another set of tests where the listener throws exceptions, and make sure we get the same exceptions them back on the listener.
Matt, thanks! I'll address your comments tomorrow. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:97: jobject owner_; On 2014/10/20 21:07:29, mmenke wrote: > Can we just make this a ScopedJavaGlobalRef? Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:121: VLOG(1) << "New chromium network request_adapter: " On 2014/10/20 21:07:29, mmenke wrote: > include base/logging.h Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:162: public void cancel() { On 2014/10/20 21:23:04, mmenke wrote: > Should assert that we're called on the executor thread, here and in isCanceled > and pause. And maybe a test to make sure that fails correctly? It seems that Executors unlike loopers don't necessarily attach to a particular thread. For example one can create thread pool executor. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.cc (right): https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:31: const char* kFailurePhase[]{ On 2014/10/20 21:07:30, mmenke wrote: > nit: Space before "{" Done. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:34: "readsync", // READ_SYNC On 2014/10/20 21:07:29, mmenke wrote: > nit: -2 indent. Done. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:134: int net_error) { On 2014/10/20 21:07:30, mmenke wrote: > Maybe DCHECK phase is in the correct range? Done. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:220: bool URLRequestMockHTTPJob::MaybeReportErrorOnPhase(FailurePhase phase) { On 2014/10/20 21:07:30, mmenke wrote: > nit: phase -> current_phase (To try and make it clearer that, despite being a > FailurePhase, it's not the phase to fail on) Done. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:221: DCHECK(phase >= START && phase <= READ_SYNC); On 2014/10/20 21:07:30, mmenke wrote: > Suggest a DCHECK_GE and DCHECK_LE Done. https://codereview.chromium.org/586143002/diff/460001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:250: } On 2014/10/20 21:07:30, mmenke wrote: > Think this could be a bit simpler as: > > if (phase == START || phase == READ_SYNC) { > ... > return true; > } > > SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); > if (phase == READ_ASYNC) { > ... > } Done.
https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:162: public void cancel() { On 2014/10/20 22:30:09, mef wrote: > On 2014/10/20 21:23:04, mmenke wrote: > > Should assert that we're called on the executor thread, here and in isCanceled > > and pause. And maybe a test to make sure that fails correctly? > > It seems that Executors unlike loopers don't necessarily attach to a particular > thread. For example one can create thread pool executor. This is a problem - the code doesn't currently support that case. We should either require this not be the case with runtime checks and exceptions, or allow it, and add locks around all access to mCanceled (And mPaused once we add it).
https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/cronet_url_request.h (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/cronet_url_request.h:14: enum CronetUrlRequestPriority { On 2014/10/20 21:07:29, mmenke wrote: > As a reminder, there's a new way to do this. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:162: public void cancel() { On 2014/10/21 14:28:01, mmenke wrote: > On 2014/10/20 22:30:09, mef wrote: > > On 2014/10/20 21:23:04, mmenke wrote: > > > Should assert that we're called on the executor thread, here and in > isCanceled > > > and pause. And maybe a test to make sure that fails correctly? > > > > It seems that Executors unlike loopers don't necessarily attach to a > particular > > thread. For example one can create thread pool executor. > > This is a problem - the code doesn't currently support that case. We should > either require this not be the case with runtime checks and exceptions, or allow > it, and add locks around all access to mCanceled (And mPaused once we add it). Either that or switch to loopers. In my opinion adding locks around access to mLocked is not that bad as I don't expect any real contention there. WDYT?
https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:162: public void cancel() { On 2014/10/21 14:49:11, mef wrote: > On 2014/10/21 14:28:01, mmenke wrote: > > On 2014/10/20 22:30:09, mef wrote: > > > On 2014/10/20 21:23:04, mmenke wrote: > > > > Should assert that we're called on the executor thread, here and in > > isCanceled > > > > and pause. And maybe a test to make sure that fails correctly? > > > > > > It seems that Executors unlike loopers don't necessarily attach to a > > particular > > > thread. For example one can create thread pool executor. > > > > This is a problem - the code doesn't currently support that case. We should > > either require this not be the case with runtime checks and exceptions, or > allow > > it, and add locks around all access to mCanceled (And mPaused once we add it). > Either that or switch to loopers. In my opinion adding locks around access to > mLocked is not that bad as I don't expect any real contention there. WDYT? Per offline discussion, I'm not concerned about performance. my main concern with exector is correctness and giving strong guarantees that we won't call into the embedder after cancelation, without addind the potential for deadlock. I think Looper is the way to go, though there are tradeoffs.
A couple more comments. May get back to this later today, may not. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:143: DCHECK(!request_adapter->IsOnNetworkThread()); Check IsValidHeaderName and IsValidHeaderValue, and if not, return false and throw an exception? https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:219: static void GetAllHeaders(JNIEnv* jenv, optional: May want to rename this (All the other GetBlah functions return Blah, but this behaves a bit differently). Could just call it PopulateResponseHeaders or somesuch. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:245: // null key; in HTTP's case, this maps to the HTTP status line. Maybe get rid of this behavior, and make the status line separately accessible? As-is, this seems like a bit of a hack to me. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:138: checkNotStarted(); Should also check that we're not done (mUrlRequestAdapter is not 0) https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:162: public void cancel() { If already cancelled, should either do nothing or throw an exception. Same if done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:164: nativeCancel(mUrlRequestAdapter); Perhaps get rid of onCanceled and just destroy the adapter here instead? Could optionally even get rid of mCanceled, and just rely on whether the adapter is 0 or not. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:263: public void run() { If cancelled, should do nothing. Hrm...Suddenly occurs to me that the cancellation tests should try and catch that case, so perhaps my suggestion of using hung URL requests was a bad one. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:288: try { Check we aren't cancelled. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:314: mOnDataReceivedTask = new OnDataReceivedRunnable(); Why is this not inlined, but the others are? I'm fine either way, but should be consistent.
https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:143: DCHECK(!request_adapter->IsOnNetworkThread()); On 2014/10/21 16:17:53, mmenke wrote: > Check IsValidHeaderName and IsValidHeaderValue, and if not, return false and > throw an exception? Oh, and we should have tests for these (And most other cases where we throw exceptions as well - though checking that ever single method throws an exception if called after a request starts is probably a bit excessive)
https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ExtendedResponseInfo info); Oh, we only pass ExtendedResponseInfo on complete, not everywhere, so there isn't actually a threading concern here. However...I think it's a bit cleaner to make ExtendedResponseInfo wrap a ResponseInfo, and make both effectively constant. WDYT?
Matt, thanks! I've addressed some of your comments, but there are more tests to add... https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java (right): https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:35: public static UrlRequestFactory createFactory(Context context, On 2014/10/06 18:28:45, mmenke wrote: > Should have a comment here. Done. https://codereview.chromium.org/586143002/diff/300001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestFactory.java:79: // Leave as null On 2014/10/06 18:28:45, mmenke wrote: > nit: +. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:62: private long mTotalReceivedBytes = 0; On 2014/10/20 21:23:04, mmenke wrote: > I'm still nervous about changing this out from under the embedder - I could see > reasons they might want to cache this structure, or fool with it on a thread > other than the executor thread, and in either case, modifying this can get us > into trouble. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:247: // Private methods called by the native code. On 2014/10/20 21:23:04, mmenke wrote: > Suggest making this more noticeable, like: > > //////////////////////////////////////////////// > // > // Private methods called by native code. > // > //////////////////////////////////////////////// > > (Using "//" because I think "/*" may make Javadoc sad) Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:40: // Executor for Cronet callbacks On 2014/10/20 21:07:29, mmenke wrote: > nit: +. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:45: ConditionVariable mComplete = new ConditionVariable(); On 2014/10/20 21:07:29, mmenke wrote: > nit: Suggest a blank line between public and non-public variables. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:100: public void resetComplete() { On 2014/10/20 21:07:29, mmenke wrote: > Not used. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:242: public boolean mCancelFromDataReceived = false; On 2014/10/20 21:07:29, mmenke wrote: > My suggestion: Use one bool to indicate sync vs async cancellation, and 3 bools > to indicate the phase (Or better, an enum, and take them as constructor args). > Then each branch would just look like: > > super.onRedirect(request, info, newLocation); > if (mCancelFromRedirect) { > CancelSyncOrAsync(); > } > > Think that makes the code a bit simpler, and less redundant. Done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:143: DCHECK(!request_adapter->IsOnNetworkThread()); On 2014/10/21 16:17:53, mmenke wrote: > Check IsValidHeaderName and IsValidHeaderValue, and if not, return false and > throw an exception? Done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:219: static void GetAllHeaders(JNIEnv* jenv, On 2014/10/21 16:17:53, mmenke wrote: > optional: May want to rename this (All the other GetBlah functions return Blah, > but this behaves a bit differently). Could just call it PopulateResponseHeaders > or somesuch. Done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:245: // null key; in HTTP's case, this maps to the HTTP status line. On 2014/10/21 16:17:53, mmenke wrote: > Maybe get rid of this behavior, and make the status line separately accessible? > As-is, this seems like a bit of a hack to me. Acknowledged. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:138: checkNotStarted(); On 2014/10/21 16:17:54, mmenke wrote: > Should also check that we're not done (mUrlRequestAdapter is not 0) Done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:162: public void cancel() { On 2014/10/21 16:17:54, mmenke wrote: > If already cancelled, should either do nothing or throw an exception. Same if > done. Done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:164: nativeCancel(mUrlRequestAdapter); On 2014/10/21 16:17:53, mmenke wrote: > Perhaps get rid of onCanceled and just destroy the adapter here instead? > > Could optionally even get rid of mCanceled, and just rely on whether the adapter > is 0 or not. Per offline discussion we can't do that. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:263: public void run() { On 2014/10/21 16:17:53, mmenke wrote: > If cancelled, should do nothing. Hrm...Suddenly occurs to me that the > cancellation tests should try and catch that case, so perhaps my suggestion of > using hung URL requests was a bad one. Done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:288: try { On 2014/10/21 16:17:54, mmenke wrote: > Check we aren't cancelled. Done. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:314: mOnDataReceivedTask = new OnDataReceivedRunnable(); On 2014/10/21 16:17:54, mmenke wrote: > Why is this not inlined, but the others are? I'm fine either way, but should be > consistent. clm@ has expressed a concern that onDataReceived is called multiple times and would cause GC thrashing if we create a new instance on each callback. https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/480001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:56: public void onComplete(UrlRequest request, ExtendedResponseInfo info); On 2014/10/21 20:57:02, mmenke wrote: > Oh, we only pass ExtendedResponseInfo on complete, not everywhere, so there > isn't actually a threading concern here. However...I think it's a bit cleaner > to make ExtendedResponseInfo wrap a ResponseInfo, and make both effectively > constant. WDYT? Done.
PTAL, I believe I've addressed all comments and added more tests. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:137: public void setHttpMethod(String method) { On 2014/10/20 21:23:04, mmenke wrote: > Should test this, and add header, now that we have a way to do so. Should also > check the default method. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:214: private void checkNotStarted() { On 2014/10/20 21:23:04, mmenke wrote: > Should have a test where this fails, and make sure an exception is thrown. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:64: mOnRedirectCalled = true; On 2014/10/20 21:07:29, mmenke wrote: > Check that mOnResponseStartedCalled is false? (Since we aren't at the top > level, I suggest just keeping a list of errors we've seen, as strings). Also > suggest adding a bunch of state checks to all of these, for that reason - fine > to have some inline in your tests, too, but having them here allows for more > complete testing of ordering. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:172: public void testMockFailed() throws Exception { On 2014/10/20 21:07:29, mmenke wrote: > I believe this effectively just tests the same case as testMockStartSyncError, > right? Yes, but using different mock jobs. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:183: public void testMockStartSyncError() throws Exception { On 2014/10/20 21:07:29, mmenke wrote: > This is actually async. Done. https://codereview.chromium.org/586143002/diff/460001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:415: } On 2014/10/20 21:23:05, mmenke wrote: > Since we're handling it, should have yet another set of tests where the listener > throws exceptions, and make sure we get the same exceptions them back on the > listener. Done.
https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:74: void OnRequestCanceled(CronetURLRequestAdapter* request_adapter) override { unused request_adapter. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:79: void OnRequestFinished(CronetURLRequestAdapter* request_adapter) override { unused request_adapter https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:84: void OnError(CronetURLRequestAdapter* request_adapter, int error) override { unused request_adapter. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:31: cancel_soon_(false) { nit: Not exactly sure what cancel_soon_ does from its name. Could you add a comment in the header file? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:143: bool cancel_soon_; nit: should we initialize these booleans? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:60: jobject object, nit: "jobject jcaller" as it's the case in other methods in this file.
a few more comments from me. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:10: #include "base/compiler_specific.h" Is this include being used? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:32: // Fully configured |URLRequestContext|. nit: This comment does not make much sense to me. maybe consider rephrasing? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:68: scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; nit: I don't think this is being used. Suggest also remove the header file from includes. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:207: private void postAppTask(Runnable task) { nit: the name "postAppTask" sounds a little vague to me. Maybe add a java doc to this method? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:280: * Called before following redirects. The redirect will automatically be nit: there are two spaces after "." https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:56: long getCronetUrlRequestContextAdapter() { nit: is this method private or public? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:41: * @return True if the response came from the cache. Requests that were nit: there are two spaces after "." https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java:48: /** nit: +1 indent.
Sorry for the email spam. The CL is too big to review in one setting :P https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:29: private final List<String> mUrlChain = new ArrayList<String>(); mUrlChain is changed in onRedirect(). Is it okay to declare it as final? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:58: private final String[] mUrlChain; nit: this variable has the same name as the one in the outer class. Consider renaming to sth like mResponseInfoUrlChain. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:125: CronetUrlRequest(CronetUrlRequestContext requestContext, Just curious. Why is it that CronetUrlRequest constructor does not much a explicit public/private modifier? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:265: "Exception in CalledByNative method", e); nit: indent. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:271: "Exception trying to cancel request", cancelException); nit: indent. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:378: nativeGetTotalReceivedBytes(mUrlRequestAdapter)); nit: indent. nativeGetTotalReceivedBytes should be at the same indentation as mResponseInfo right? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:389: "Exception in onComplete method", e); nit: indent. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:48: ResponseInfo info, ByteBuffer byteBuffer); nit: indent. Should ResponseInfo be at the same indentation level as UrlRequest?
https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:69: jenv, jenv->NewDirectByteBuffer(request_adapter->Data(), bytes_read)); I think it makes more sense to pass in data, in addition to bytes_read. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:129: ConvertRequestPriority(jpriority)); I think the ownership story here is a little weird... This file creates the Delegate, but actually manages Adapters. I think it's more logical for this to manage the Delegate, which owns the adapter, then the other way around...Which makes me question the separation of the delegate and the adapter / these two files. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:266: return ConvertUTF8ToJavaString(jenv, negotiated_protocol.c_str()).Release(); I don't think c_str() is really needed here. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:132: http_status_code_ = request->GetResponseCode(); Think it's simpler to pass this in to the delegate instead - keep the number of accessors down a bit. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:17: #include "net/url_request/url_request.h" Need GURL header https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object to the Chromium |URLRequest| nit: Don't use || around class names, just variable names. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object to the Chromium |URLRequest| UrlRequest -> CronetUrlRequest? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object to the Chromium |URLRequest| +. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:39: : public base::RefCountedThreadSafe<CronetURLRequestAdapterDelegate> { Does this need to be refcounted? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:61: GURL url, const GURL& https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:63: virtual ~CronetURLRequestAdapter(); -virtual +override https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:65: // Sets the request_adapter method GET, POST etc request_adapter -> request? There is nothing here called request_adapter. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:65: // Sets the request_adapter method GET, POST etc nit: +. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:68: // Adds a header to the request_adapter ...to the request before it starts? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:68: // Adds a header to the request_adapter nit: +. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:71: // Starts the request_adapter. ->request? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:80: // Cancels the request_adapter. CAncels the request? Though we may be able to get rid of this anyways. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:88: GURL url() const { return url_; } const GURL& https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:100: std::string GetNegotiatedProtocol() const; const std::string& https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:138: net::HttpRequestHeaders request_headers_; Should prefix the above 4 variables (With the possible exception of priority) with something to indicate they were only for the original request, not the most recent request - may initial_[request_]blah / original_[request_]blah, or somesuch. Could even make the url_, method_, and priority_ const, if you make them constructor parameters, since we'll only be creating the adapter once we have them. Making request_headers_ const is probably more effort than it's worth. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:26: class JniCronetURLRequestContextAdapterDelegate Do we really need a delegate for this? This adds an unfortunate circular ownership. Can we just use a callback? And better - also avoid owning the CronetUrlRequestContext at all - we can either call a static java function, or if that's not possible, just use a runnable. No circular dependency, and avoids weird lifetime issues when we fix up shutdown/cleanup. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:89: // TODO(dplotnikov): set application context. ? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:106: // thread while running on that thread? No, we can't - we use pthread_join to terminate a thread, and a thread can't join itself. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:33: class CronetURLRequestContextAdapter : public net::URLRequestContextGetter { I don't think this works for cleanup - threads have to be destroyed on another thread, but the request context and other network stuff needs to be deleted on the network thread. While we could make sure we destroy the refcounted context getter on a Java thread, but the context on the network thread, the nature of being refcounted makes that difficult to do. So I think we should separate out the adapter and the getter into separate classes - we may well not even not need the getter, actually. On destruction of the adapter (On a java thread), we then post a task to stop the NetLogLogger and destroy the context on the network thread, and that's it - destroying the thread will call Thread.Stop(), which will wait until all pending tasks of the other thread have run, and we're done. That does not take care of the issue of deleting the adapter while other CronetUrlRequests are pending - we'll need more code for that. Maybe a Shutdown() function that throws an assertion if there are any pending URLRequests (We'd have to keep a mutex-protected counter and a isShutdown boolean in the context, Java-side, but I think that's not too bad). https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:53: const std::string& GetUserAgent(const GURL& url) const; Should get rid of this and just set it on the context builder. It has all the smarts to not override an explicitly set user agent on a request, so no need to duplicate that logic. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:88: long urlRequestContextAdapter); This is never called. Seems like we have two options: Call it on finalize, or make a Shutdown method - neither is great (And what happens to in-progress requests when Shutdown is called?)
https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:125: CronetUrlRequest(CronetUrlRequestContext requestContext, On 2014/10/23 15:51:22, xunjieli wrote: > Just curious. Why is it that CronetUrlRequest constructor does not much a > explicit public/private modifier? In Java, by default, methods and variables are scoped to the package. So anything in org.chromium.net can instantiate this class. I don't know Java well enough to know if anything in org.chromium.net.com (Can never have too many TLDs in a name) or org.chromium also has access. I'd guess not, but I'm not sure about that.
https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:125: CronetUrlRequest(CronetUrlRequestContext requestContext, On 2014/10/23 21:36:42, mmenke wrote: > On 2014/10/23 15:51:22, xunjieli wrote: > > Just curious. Why is it that CronetUrlRequest constructor does not much a > > explicit public/private modifier? > > In Java, by default, methods and variables are scoped to the package. So > anything in http://org.chromium.net can instantiate this class. I don't know Java well > enough to know if anything in http://org.chromium.net.com (Can never have too many TLDs > in a name) or org.chromium also has access. I'd guess not, but I'm not sure > about that. I see, so we want to force clients to create a request through the context. Thanks for the explanation!
Thanks, PTAL. I'll add tests for UserAgent and fix UrlRequestContext lifecycle in next patch. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:69: jenv, jenv->NewDirectByteBuffer(request_adapter->Data(), bytes_read)); On 2014/10/23 16:26:00, mmenke wrote: > I think it makes more sense to pass in data, in addition to bytes_read. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:74: void OnRequestCanceled(CronetURLRequestAdapter* request_adapter) override { On 2014/10/22 21:02:16, xunjieli wrote: > unused request_adapter. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:79: void OnRequestFinished(CronetURLRequestAdapter* request_adapter) override { On 2014/10/22 21:02:16, xunjieli wrote: > unused request_adapter Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:84: void OnError(CronetURLRequestAdapter* request_adapter, int error) override { On 2014/10/22 21:02:16, xunjieli wrote: > unused request_adapter. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:129: ConvertRequestPriority(jpriority)); On 2014/10/23 16:26:00, mmenke wrote: > I think the ownership story here is a little weird... This file creates the > Delegate, but actually manages Adapters. I think it's more logical for this to > manage the Delegate, which owns the adapter, then the other way around...Which > makes me question the separation of the delegate and the adapter / these two > files. Acknowledged. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:266: return ConvertUTF8ToJavaString(jenv, negotiated_protocol.c_str()).Release(); On 2014/10/23 16:26:00, mmenke wrote: > I don't think c_str() is really needed here. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:31: cancel_soon_(false) { On 2014/10/22 21:02:16, xunjieli wrote: > nit: Not exactly sure what cancel_soon_ does from its name. Could you add a > comment in the header file? Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:132: http_status_code_ = request->GetResponseCode(); On 2014/10/23 16:26:00, mmenke wrote: > Think it's simpler to pass this in to the delegate instead - keep the number of > accessors down a bit. Ack. Not sure how it helps, but I'll think about it. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:17: #include "net/url_request/url_request.h" On 2014/10/23 16:26:00, mmenke wrote: > Need GURL header Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object to the Chromium |URLRequest| On 2014/10/23 16:26:00, mmenke wrote: > +. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object to the Chromium |URLRequest| On 2014/10/23 16:26:00, mmenke wrote: > nit: Don't use || around class names, just variable names. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI |UrlRequest| object to the Chromium |URLRequest| On 2014/10/23 16:26:00, mmenke wrote: > +. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:61: GURL url, On 2014/10/23 16:26:01, mmenke wrote: > const GURL& Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:63: virtual ~CronetURLRequestAdapter(); On 2014/10/23 16:26:00, mmenke wrote: > -virtual +override Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:65: // Sets the request_adapter method GET, POST etc On 2014/10/23 16:26:01, mmenke wrote: > request_adapter -> request? There is nothing here called request_adapter. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:65: // Sets the request_adapter method GET, POST etc On 2014/10/23 16:26:01, mmenke wrote: > nit: +. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:68: // Adds a header to the request_adapter On 2014/10/23 16:26:00, mmenke wrote: > nit: +. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:68: // Adds a header to the request_adapter On 2014/10/23 16:26:01, mmenke wrote: > ...to the request before it starts? Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:71: // Starts the request_adapter. On 2014/10/23 16:26:00, mmenke wrote: > ->request? Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:80: // Cancels the request_adapter. On 2014/10/23 16:26:01, mmenke wrote: > CAncels the request? Though we may be able to get rid of this anyways. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:88: GURL url() const { return url_; } On 2014/10/23 16:26:01, mmenke wrote: > const GURL& Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:100: std::string GetNegotiatedProtocol() const; On 2014/10/23 16:26:00, mmenke wrote: > const std::string& It doesn't work right now as we return empty string if UrlRequest is NULL, but maybe that should never happen? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:138: net::HttpRequestHeaders request_headers_; On 2014/10/23 16:26:01, mmenke wrote: > Should prefix the above 4 variables (With the possible exception of priority) > with something to indicate they were only for the original request, not the most > recent request - may initial_[request_]blah / original_[request_]blah, or > somesuch. > > Could even make the url_, method_, and priority_ const, if you make them > constructor parameters, since we'll only be creating the adapter once we have > them. Making request_headers_ const is probably more effort than it's worth. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:143: bool cancel_soon_; On 2014/10/22 21:02:16, xunjieli wrote: > nit: should we initialize these booleans? Yes, they are initialized in constructor. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:26: class JniCronetURLRequestContextAdapterDelegate On 2014/10/23 16:26:01, mmenke wrote: > Do we really need a delegate for this? This adds an unfortunate circular > ownership. Can we just use a callback? And better - also avoid owning the > CronetUrlRequestContext at all - we can either call a static java function, or > if that's not possible, just use a runnable. No circular dependency, and avoids > weird lifetime issues when we fix up shutdown/cleanup. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:60: jobject object, On 2014/10/22 21:02:16, xunjieli wrote: > nit: "jobject jcaller" as it's the case in other methods in this file. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:89: // TODO(dplotnikov): set application context. On 2014/10/23 16:26:01, mmenke wrote: > ? Copy-paste. Removed. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:106: // thread while running on that thread? On 2014/10/23 16:26:01, mmenke wrote: > No, we can't - we use pthread_join to terminate a thread, and a thread can't > join itself. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:10: #include "base/compiler_specific.h" On 2014/10/23 14:04:33, xunjieli wrote: > Is this include being used? I think it used to define OVERRIDE, which is no longer needed. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:32: // Fully configured |URLRequestContext|. On 2014/10/23 14:04:33, xunjieli wrote: > nit: This comment does not make much sense to me. maybe consider rephrasing? Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:53: const std::string& GetUserAgent(const GURL& url) const; On 2014/10/23 16:26:01, mmenke wrote: > Should get rid of this and just set it on the context builder. It has all the > smarts to not override an explicitly set user agent on a request, so no need to > duplicate that logic. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:68: scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; On 2014/10/23 14:04:33, xunjieli wrote: > nit: I don't think this is being used. Suggest also remove the header file from > includes. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:29: private final List<String> mUrlChain = new ArrayList<String>(); On 2014/10/23 15:51:22, xunjieli wrote: > mUrlChain is changed in onRedirect(). Is it okay to declare it as final? Good question. Compiler doesn't complain, but I'm not sure whether this is acceptable by coding guidelines. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:58: private final String[] mUrlChain; On 2014/10/23 15:51:22, xunjieli wrote: > nit: this variable has the same name as the one in the outer class. Consider > renaming to sth like mResponseInfoUrlChain. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:125: CronetUrlRequest(CronetUrlRequestContext requestContext, On 2014/10/23 21:44:46, xunjieli wrote: > On 2014/10/23 21:36:42, mmenke wrote: > > On 2014/10/23 15:51:22, xunjieli wrote: > > > Just curious. Why is it that CronetUrlRequest constructor does not much a > > > explicit public/private modifier? > > > > In Java, by default, methods and variables are scoped to the package. So > > anything in http://org.chromium.net can instantiate this class. I don't know > Java well > > enough to know if anything in http://org.chromium.net.com (Can never have too > many TLDs > > in a name) or org.chromium also has access. I'd guess not, but I'm not sure > > about that. > > I see, so we want to force clients to create a request through the context. > Thanks for the explanation! Acknowledged. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:207: private void postAppTask(Runnable task) { On 2014/10/23 14:04:33, xunjieli wrote: > nit: the name "postAppTask" sounds a little vague to me. Maybe add a java doc to > this method? Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:265: "Exception in CalledByNative method", e); On 2014/10/23 15:51:22, xunjieli wrote: > nit: indent. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:271: "Exception trying to cancel request", cancelException); On 2014/10/23 15:51:21, xunjieli wrote: > nit: indent. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:280: * Called before following redirects. The redirect will automatically be On 2014/10/23 14:04:33, xunjieli wrote: > nit: there are two spaces after "." Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:378: nativeGetTotalReceivedBytes(mUrlRequestAdapter)); On 2014/10/23 15:51:22, xunjieli wrote: > nit: indent. nativeGetTotalReceivedBytes should be at the same indentation as > mResponseInfo right? Hmm, I'm not sure, it wouldn't fit there, would it? https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:389: "Exception in onComplete method", e); On 2014/10/23 15:51:22, xunjieli wrote: > nit: indent. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:56: long getCronetUrlRequestContextAdapter() { On 2014/10/23 14:04:33, xunjieli wrote: > nit: is this method private or public? Package as it needs to be accessed by CronetUrlRequest. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:88: long urlRequestContextAdapter); On 2014/10/23 16:26:01, mmenke wrote: > This is never called. > > Seems like we have two options: Call it on finalize, or make a Shutdown method > - neither is great (And what happens to in-progress requests when Shutdown is > called?) Previous interface did it in finalize, but I guess that's discouraged, so I've added an explicit 'shutdown' method. Should we track (number) of open requests on Java side and throw an exception on shutdown if that number is not 0, or should we cancel them when shutdown is called? Later behavior may make it easier to do bulk cancelation, but OTOH we don't notify listeners when request is canceled... https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/ResponseInfo.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/ResponseInfo.java:41: * @return True if the response came from the cache. Requests that were On 2014/10/23 14:04:33, xunjieli wrote: > nit: there are two spaces after "." Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java:48: /** On 2014/10/23 14:04:33, xunjieli wrote: > nit: +1 indent. Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:48: ResponseInfo info, ByteBuffer byteBuffer); On 2014/10/23 15:51:22, xunjieli wrote: > nit: indent. Should ResponseInfo be at the same indentation level as UrlRequest? Done.
quick responses https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:132: http_status_code_ = request->GetResponseCode(); On 2014/10/24 03:31:43, mef wrote: > On 2014/10/23 16:26:00, mmenke wrote: > > Think it's simpler to pass this in to the delegate instead - keep the number > of > > accessors down a bit. > Ack. Not sure how it helps, but I'll think about it. How it helps: One less accessor method, one less class variable with weird properties (It's the status code of the most recently received response - I'd really like to get rid of all variables in the adapter that do that, just a bit less complexity) https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:29: private final List<String> mUrlChain = new ArrayList<String>(); On 2014/10/24 03:31:45, mef wrote: > On 2014/10/23 15:51:22, xunjieli wrote: > > mUrlChain is changed in onRedirect(). Is it okay to declare it as final? > Good question. Compiler doesn't complain, but I'm not sure whether this is > acceptable by coding guidelines. Regardless of guidelines, I think it makes sense just to duplicate the list, to make it const and threadsafe for the embedder to hang on to it if it wants to do so, per our earlier conversations https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:88: long urlRequestContextAdapter); On 2014/10/24 03:31:45, mef wrote: > On 2014/10/23 16:26:01, mmenke wrote: > > This is never called. > > > > Seems like we have two options: Call it on finalize, or make a Shutdown > method > > - neither is great (And what happens to in-progress requests when Shutdown is > > called?) > Previous interface did it in finalize, but I guess that's discouraged, so I've > added an explicit 'shutdown' method. > > Should we track (number) of open requests on Java side and throw an exception on > shutdown if that number is not 0, > or should we cancel them when shutdown is called? Later behavior may make it > easier to do bulk cancelation, but OTOH we don't notify listeners when request > is canceled... > My suggestion is go with the exception, and if we need better behavior, can implement it later (Easy to go from throwing an exception to being nice, not so easy to go the other way around)
Just looked at the tests - want to wait for cancellation to be fixed up before getting back to the rest. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:207: * Post task to application Executor or Looper. Used for Listener callbacks Despite my whining, probably simplest to just always take an executor. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:41: ExecutorService mExecutor = Executors.newSingleThreadExecutor(); Can just use this as an Executor - don't think we get anything out of keeping it as an ExecutorService. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:60: nit: Blank line not needed. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:61: protected ConditionVariable mComplete = new ConditionVariable(); Optional: Should we get in the habit of putting less public variables last, to mimic C++ style-guide required ordering? https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:61: protected ConditionVariable mComplete = new ConditionVariable(); optional: Suggest making this private, and adding a protected method that calls mComplete.open() instead. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:83: assertEquals(LastCalled.Nothing, mLastCalled); Can have multiple redirects, though we aren't currently testing that. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:85: mOnRedirectCalled = true; We should store info somewhere, so we can check the initial response info, make sure we get the redirect response code, etc. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:101: mLastCalled == LastCalled.OnDataReceived); What happens if these assertions fail? Do we just end up at onError? https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:111: public void onComplete(UrlRequest request, ExtendedResponseInfo info) { Should also store the ExtendedResponseInfo. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:113: mLastCalled == LastCalled.OnDataReceived); Hrm...Perhaps we should catch onComplete exceptions, and call on error in that case... https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:159: assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); Should check all other methods of mResponseInfo here (getUrl, getUrlChain, wasCached, smellsOfEldeberry, tastesLikeChicken, etc). https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:170: String methodName = "head"; Using head here is weird (HEAD requests don't typically return bodies), so suggest something else - FOO or BEEF_JERKY or something. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:194: We never test that we get response headers (Should also check that we can get multiple instances of the same header name) https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:200: String headerValue = "header-value"; Should have a test where we add two values for the same name (Both should be sent, test server may need to be modified to return multiple headers). https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:257: public void testMockRedirect() throws Exception { Should also check the response info we get when following the redirect. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:289: public void testMockFailed() throws Exception { Still don't think we get anything from this test. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:295: assertEquals(-2, listener.mError.netError()); We should also be checking the strings (In fact, I'd argue that we probably want to minimize checking of the raw error code, just so the tests don't depend on magic numbers, unless we want to expose a net error to string map or enum in Java).
The new Async API does not explicitly load the native library (via System.load()). We probably would want to do that to be consistent with current API.
Thanks, PTAL, I've fixed cancellation and destruction of requests and context, and will add more tests next. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:33: class CronetURLRequestContextAdapter : public net::URLRequestContextGetter { On 2014/10/23 16:26:01, mmenke wrote: > I don't think this works for cleanup - threads have to be destroyed on another > thread, but the request context and other network stuff needs to be deleted on > the network thread. > > While we could make sure we destroy the refcounted context getter on a Java > thread, but the context on the network thread, the nature of being refcounted > makes that difficult to do. So I think we should separate out the adapter and > the getter into separate classes - we may well not even not need the getter, > actually. > > On destruction of the adapter (On a java thread), we then post a task to stop > the NetLogLogger and destroy the context on the network thread, and that's it - > destroying the thread will call Thread.Stop(), which will wait until all pending > tasks of the other thread have run, and we're done. > > That does not take care of the issue of deleting the adapter while other > CronetUrlRequests are pending - we'll need more code for that. Maybe a > Shutdown() function that throws an assertion if there are any pending > URLRequests (We'd have to keep a mutex-protected counter and a isShutdown > boolean in the context, Java-side, but I think that's not too bad). Done. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:88: long urlRequestContextAdapter); On 2014/10/24 03:46:19, mmenke wrote: > On 2014/10/24 03:31:45, mef wrote: > > On 2014/10/23 16:26:01, mmenke wrote: > > > This is never called. > > > > > > Seems like we have two options: Call it on finalize, or make a Shutdown > > method > > > - neither is great (And what happens to in-progress requests when Shutdown > is > > > called?) > > Previous interface did it in finalize, but I guess that's discouraged, so I've > > added an explicit 'shutdown' method. > > > > Should we track (number) of open requests on Java side and throw an exception > on > > shutdown if that number is not 0, > > or should we cancel them when shutdown is called? Later behavior may make it > > easier to do bulk cancelation, but OTOH we don't notify listeners when request > > is canceled... > > > > My suggestion is go with the exception, and if we need better behavior, can > implement it later (Easy to go from throwing an exception to being nice, not so > easy to go the other way around) Sounds good. We can also set a 'shutdown' flag, so new requests would not be created, but native release would only happen after all active requests are destroyed. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:207: * Post task to application Executor or Looper. Used for Listener callbacks On 2014/10/24 16:34:36, mmenke wrote: > Despite my whining, probably simplest to just always take an executor. lol https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:41: ExecutorService mExecutor = Executors.newSingleThreadExecutor(); On 2014/10/24 16:34:36, mmenke wrote: > Can just use this as an Executor - don't think we get anything out of keeping it > as an ExecutorService. Not really, as I'm using ExecutorService shutdown and waitForTerminate now. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:170: String methodName = "head"; On 2014/10/24 16:34:36, mmenke wrote: > Using head here is weird (HEAD requests don't typically return bodies), so > suggest something else - FOO or BEEF_JERKY or something. I've tried that, but our http server doesn't know how to handle "FOO".
https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:170: String methodName = "head"; On 2014/10/24 19:57:55, mef wrote: > On 2014/10/24 16:34:36, mmenke wrote: > > Using head here is weird (HEAD requests don't typically return bodies), so > > suggest something else - FOO or BEEF_JERKY or something. > > I've tried that, but our http server doesn't know how to handle "FOO". If you capitalized HEAD, do you get an empty body? I'm trying to figure out why this test passes there.
Misha: One other option, that may be a little simpler. We could make our own sequenced task runner on top of the executor, and make it a hidden detail. cancel() posts a task to that task runner (Could even post it to the *front* of the task runner, if there's already a queued task). We talked about something like this before, but exposing it to the embedder.
Thanks, PTAL, I believe that I've addressed all comments. https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/540001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:29: private final List<String> mUrlChain = new ArrayList<String>(); On 2014/10/24 03:46:19, mmenke wrote: > On 2014/10/24 03:31:45, mef wrote: > > On 2014/10/23 15:51:22, xunjieli wrote: > > > mUrlChain is changed in onRedirect(). Is it okay to declare it as final? > > Good question. Compiler doesn't complain, but I'm not sure whether this is > > acceptable by coding guidelines. > > Regardless of guidelines, I think it makes sense just to duplicate the list, to > make it const and threadsafe for the embedder to hang on to it if it wants to do > so, per our earlier conversations On a closer look we don't pass mUrlChain to listener, we create a copy using toArray() method. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:60: On 2014/10/24 16:34:36, mmenke wrote: > nit: Blank line not needed. Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:61: protected ConditionVariable mComplete = new ConditionVariable(); On 2014/10/24 16:34:36, mmenke wrote: > Optional: Should we get in the habit of putting less public variables last, to > mimic C++ style-guide required ordering? Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:61: protected ConditionVariable mComplete = new ConditionVariable(); On 2014/10/24 16:34:36, mmenke wrote: > optional: Suggest making this private, and adding a protected method that calls > mComplete.open() instead. Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:83: assertEquals(LastCalled.Nothing, mLastCalled); On 2014/10/24 16:34:36, mmenke wrote: > Can have multiple redirects, though we aren't currently testing that. Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:85: mOnRedirectCalled = true; On 2014/10/24 16:34:36, mmenke wrote: > We should store info somewhere, so we can check the initial response info, make > sure we get the redirect response code, etc. Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:101: mLastCalled == LastCalled.OnDataReceived); On 2014/10/24 16:34:36, mmenke wrote: > What happens if these assertions fail? Do we just end up at onError? I don't think they just throw. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:111: public void onComplete(UrlRequest request, ExtendedResponseInfo info) { On 2014/10/24 16:34:36, mmenke wrote: > Should also store the ExtendedResponseInfo. Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:113: mLastCalled == LastCalled.OnDataReceived); On 2014/10/24 16:34:36, mmenke wrote: > Hrm...Perhaps we should catch onComplete exceptions, and call on error in that > case... Um, with your example, embedder could've cleaned something in onComplete prior to throwing an exception, so onError call would be totally unexpected. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:159: assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); On 2014/10/24 16:34:36, mmenke wrote: > Should check all other methods of mResponseInfo here (getUrl, getUrlChain, > wasCached, smellsOfEldeberry, tastesLikeChicken, etc). Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:170: String methodName = "head"; On 2014/10/24 20:16:22, mmenke wrote: > On 2014/10/24 19:57:55, mef wrote: > > On 2014/10/24 16:34:36, mmenke wrote: > > > Using head here is weird (HEAD requests don't typically return bodies), so > > > suggest something else - FOO or BEEF_JERKY or something. > > > > I've tried that, but our http server doesn't know how to handle "FOO". > > If you capitalized HEAD, do you get an empty body? I'm trying to figure out why > this test passes there. Yes, Done https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:194: On 2014/10/24 16:34:36, mmenke wrote: > We never test that we get response headers (Should also check that we can get > multiple instances of the same header name) Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:200: String headerValue = "header-value"; On 2014/10/24 16:34:36, mmenke wrote: > Should have a test where we add two values for the same name (Both should be > sent, test server may need to be modified to return multiple headers). Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:257: public void testMockRedirect() throws Exception { On 2014/10/24 16:34:36, mmenke wrote: > Should also check the response info we get when following the redirect. Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:289: public void testMockFailed() throws Exception { On 2014/10/24 16:34:36, mmenke wrote: > Still don't think we get anything from this test. Done. https://codereview.chromium.org/586143002/diff/560001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:295: assertEquals(-2, listener.mError.netError()); On 2014/10/24 16:34:36, mmenke wrote: > We should also be checking the strings (In fact, I'd argue that we probably want > to minimize checking of the raw error code, just so the tests don't depend on > magic numbers, unless we want to expose a net error to string map or enum in > Java). Well, in these tests I'm actually checking that we are propagating arbitrary error all the way up to the embedder.
https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi File components/cronet.gypi (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... components/cronet.gypi:30: 'includes': [ '../build/android/java_cpp_enum.gypi' ], nit: indent. https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... components/cronet.gypi:124: 'cronet_url_request_java_enum', nit:indent. https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... components/cronet.gypi:234: 'cronet_url_request_java_enum', nit: indent. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:114: DCHECK(context_adapter != nullptr); Is it possible to do DCHECK(context_adapter)? https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:112: // net::URLRequest::Delegate overrides (called on network thread). Add a DCHECK in this method, since you expect it to be called on the network thread? https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:68: // Follow redirect. nit: probably we should use all third-person for consistency? eg. Follows instead of Follow, Reads instead of Read. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:128: bool called_to_delegate_; nit: maybe add a comment to this variable? Not sure what it means from the name. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:184: Log.e(CronetUrlRequestContext.LOG_TAG, "********* Cancel on Java "); Question: If an embedder cancel on a request, why do we always log error ? Should we use Log.d? I imagine it is not a bad thing if they use request.cancel(). https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:74: nit: two empty lines. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:84: nit: two empty lines.
Thanks, PTAL! https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi File components/cronet.gypi (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... components/cronet.gypi:30: 'includes': [ '../build/android/java_cpp_enum.gypi' ], On 2014/10/28 14:24:19, xunjieli wrote: > nit: indent. Done. https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... components/cronet.gypi:124: 'cronet_url_request_java_enum', On 2014/10/28 14:24:19, xunjieli wrote: > nit:indent. Done. https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... components/cronet.gypi:234: 'cronet_url_request_java_enum', On 2014/10/28 14:24:19, xunjieli wrote: > nit: indent. Done. Somehow I got tab characters into this file. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:114: DCHECK(context_adapter != nullptr); On 2014/10/28 14:24:19, xunjieli wrote: > Is it possible to do DCHECK(context_adapter)? Done. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:112: // net::URLRequest::Delegate overrides (called on network thread). On 2014/10/28 14:24:19, xunjieli wrote: > Add a DCHECK in this method, since you expect it to be called on the network > thread? Done. net::URLRequest::Delegate overrides are called from URLRequest, and that always happens on network thread. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:68: // Follow redirect. On 2014/10/28 14:24:19, xunjieli wrote: > nit: probably we should use all third-person for consistency? eg. Follows > instead of Follow, Reads instead of Read. Done. Great suggestion! https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:128: bool called_to_delegate_; On 2014/10/28 14:24:19, xunjieli wrote: > nit: maybe add a comment to this variable? Not sure what it means from the name. Done. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:184: Log.e(CronetUrlRequestContext.LOG_TAG, "********* Cancel on Java "); On 2014/10/28 14:24:19, xunjieli wrote: > Question: If an embedder cancel on a request, why do we always log error ? > Should we use Log.d? I imagine it is not a bad thing if they use > request.cancel(). Done. Leftovers from debugging. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:74: On 2014/10/28 14:24:20, xunjieli wrote: > nit: two empty lines. Done. https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:84: On 2014/10/28 14:24:20, xunjieli wrote: > nit: two empty lines. Done.
On 2014/10/28 16:29:01, mef wrote: > Thanks, PTAL! > > https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi > File components/cronet.gypi (right): > > https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... > components/cronet.gypi:30: 'includes': [ '../build/android/java_cpp_enum.gypi' > ], > On 2014/10/28 14:24:19, xunjieli wrote: > > nit: indent. > > Done. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... > components/cronet.gypi:124: 'cronet_url_request_java_enum', > On 2014/10/28 14:24:19, xunjieli wrote: > > nit:indent. > > Done. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet.gypi#... > components/cronet.gypi:234: 'cronet_url_request_java_enum', > On 2014/10/28 14:24:19, xunjieli wrote: > > nit: indent. > > Done. Somehow I got tab characters into this file. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > File components/cronet/android/cronet_url_request.cc (right): > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > components/cronet/android/cronet_url_request.cc:114: DCHECK(context_adapter != > nullptr); > On 2014/10/28 14:24:19, xunjieli wrote: > > Is it possible to do DCHECK(context_adapter)? > > Done. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > File components/cronet/android/cronet_url_request_adapter.cc (right): > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > components/cronet/android/cronet_url_request_adapter.cc:112: // > net::URLRequest::Delegate overrides (called on network thread). > On 2014/10/28 14:24:19, xunjieli wrote: > > Add a DCHECK in this method, since you expect it to be called on the network > > thread? > Done. net::URLRequest::Delegate overrides are called from URLRequest, and that > always happens on network thread. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > File components/cronet/android/cronet_url_request_adapter.h (right): > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > components/cronet/android/cronet_url_request_adapter.h:68: // Follow redirect. > On 2014/10/28 14:24:19, xunjieli wrote: > > nit: probably we should use all third-person for consistency? eg. Follows > > instead of Follow, Reads instead of Read. > > Done. Great suggestion! > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > components/cronet/android/cronet_url_request_adapter.h:128: bool > called_to_delegate_; > On 2014/10/28 14:24:19, xunjieli wrote: > > nit: maybe add a comment to this variable? Not sure what it means from the > name. > > Done. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java > (right): > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:184: > Log.e(CronetUrlRequestContext.LOG_TAG, "********* Cancel on Java "); > On 2014/10/28 14:24:19, xunjieli wrote: > > Question: If an embedder cancel on a request, why do we always log error ? > > Should we use Log.d? I imagine it is not a bad thing if they use > > request.cancel(). > > Done. Leftovers from debugging. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > File > components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java > (right): > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:74: > > On 2014/10/28 14:24:20, xunjieli wrote: > > nit: two empty lines. > > Done. > > https://codereview.chromium.org/586143002/diff/600001/components/cronet/andro... > components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:84: > > On 2014/10/28 14:24:20, xunjieli wrote: > > nit: two empty lines. > > Done. Achievement unlocked: This CL now has over 500 comments!
https://codereview.chromium.org/586143002/diff/620001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/620001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:257: nativeDestroyRequestAdapter(urlRequestAdapter); Per previous discussions, this isn't threadsafe. I'd really like to have this ironed out and implemented safely before doing another full pass.
PTAL. https://chromiumcodereview.appspot.com/586143002/diff/620001/components/crone... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://chromiumcodereview.appspot.com/586143002/diff/620001/components/crone... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:257: nativeDestroyRequestAdapter(urlRequestAdapter); On 2014/10/28 18:07:52, mmenke wrote: > Per previous discussions, this isn't threadsafe. I'd really like to have this > ironed out and implemented safely before doing another full pass. Done.
Plan to do another pass this afternoon. Really focused on thread safety Java-side on this pass. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:28: private final Object mUrlRequestAdapterLock = new Object(); Do we get anything from using a new object, instead of "synchronized(this)"? Just ensures that if the embedder uses synchronized(CronetUrlRequest), Bad Things won't happen? https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:38: private AtomicBoolean mCanceled = new AtomicBoolean(false); Having both an atomic and a lock seems a bit confusing here - it doesn't break anything, but you can be in a state where mCanceled is true, but mUrlRequestAdapter has not yet been NULLed out, and you're accessing mUrlRequestAdapter on another thread. My suggestion: Get rid of cancelled, and just grab the lock to check for cancellation. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:108: private long mTotalReceivedBytes = 0; Both these can be private final (And the "= 0" is not needed) https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:173: synchronized (mUrlRequestAdapterLock) { Should also check if we've been cancelled? https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:191: throw new IllegalArgumentException("Invalid header."); Should include the key/value in the error message. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:255: urlRequestAdapter = mUrlRequestAdapter; This could be 0. Could just put this entire function in a lock, and check if it's 0 first thing. If so, return null...and don't bother to run a task on the UI thread. Alternatively, could pass in a pointer from C++, and use that. Nice thing there is there's less redundant special case logic for the cancellation case. We do more work in that case, but doesn't matter - we only do it once per request, at most, and it's not a huge amount of work. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:269: if (mUrlRequestAdapter != 0) { We have no protection against being restarted after we delete the mUrlRequestAdapter. Suggest we add it, just as a precaution. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:277: if (mUrlRequestAdapter != 0) { optional: Suggest early return instead. That's more in keeping with Chrome style, and the other places you get this lock as well. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:304: mListener.onError(this, mResponseInfo, requestError); We may not be on the executor at this point. Should either make sure onCalledByNativeException is run on the executor, or post a task here. Also: We should have tests that make sure, when there's a single-threaded executor, all callbacks are executor on that executor. Since our current tests use just such an executor, I suggest just updating the current tests to all enforce that. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:304: mListener.onError(this, mResponseInfo, requestError); While we're on the topic... We really don't have any thread safety tests. No tests do anything on another thread. It's very difficult to adequately test thread safely, but we should have at least some tests that attempt to do so. For example: For the cancel during callback tests, we could have a variant where we cancel on another thread, while blocking the callback until the cancel task has been run. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:326: private void onRedirect(final String newLocation, int httpStatusCode) { Do we get anything out of the final here? We could declare a bunch of other values to be final, too (Like httpStatusCode). https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:339: nativeFollowDeferredRedirect(mUrlRequestAdapter); Have to check if mUrlRequestAdapterLock is NULL - onRedirect could have cancelled the request, or it could have been cancelled on another thread. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:366: nativeReceiveData(mUrlRequestAdapter); Have to check if mUrlRequestAdapterLock is NULL. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:403: nativeGetTotalReceivedBytes(mUrlRequestAdapter); Have to check if mUrlRequestAdapter is NULL here. Alternatively, could just ass it in to onComplete from native code.
https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:304: mListener.onError(this, mResponseInfo, requestError); On 2014/10/29 16:20:47, mmenke wrote: > While we're on the topic... We really don't have any thread safety tests. No > tests do anything on another thread. It's very difficult to adequately test > thread safely, but we should have at least some tests that attempt to do so. > > For example: For the cancel during callback tests, we could have a variant > where we cancel on another thread, while blocking the callback until the cancel > task has been run. On second thought, that really doesn't test much...Need to think if we can come up with something reasonable.
Thanks, PTAL. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:28: private final Object mUrlRequestAdapterLock = new Object(); On 2014/10/29 16:20:47, mmenke wrote: > Do we get anything from using a new object, instead of "synchronized(this)"? > Just ensures that if the embedder uses synchronized(CronetUrlRequest), Bad > Things won't happen? Yeah, chrome's findbugs script complains about synchronized(this). https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:38: private AtomicBoolean mCanceled = new AtomicBoolean(false); On 2014/10/29 16:20:47, mmenke wrote: > Having both an atomic and a lock seems a bit confusing here - it doesn't break > anything, but you can be in a state where mCanceled is true, but > mUrlRequestAdapter has not yet been NULLed out, and you're accessing > mUrlRequestAdapter on another thread. > > My suggestion: Get rid of cancelled, and just grab the lock to check for > cancellation. Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:108: private long mTotalReceivedBytes = 0; On 2014/10/29 16:20:48, mmenke wrote: > Both these can be private final (And the "= 0" is not needed) Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:173: synchronized (mUrlRequestAdapterLock) { On 2014/10/29 16:20:48, mmenke wrote: > Should also check if we've been cancelled? Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:191: throw new IllegalArgumentException("Invalid header."); On 2014/10/29 16:20:48, mmenke wrote: > Should include the key/value in the error message. Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:255: urlRequestAdapter = mUrlRequestAdapter; On 2014/10/29 16:20:47, mmenke wrote: > This could be 0. Could just put this entire function in a lock, and check if > it's 0 first thing. If so, return null...and don't bother to run a task on the > UI thread. Alternatively, could pass in a pointer from C++, and use that. Nice > thing there is there's less redundant special case logic for the cancellation > case. We do more work in that case, but doesn't matter - we only do it once per > request, at most, and it's not a huge amount of work. Done. C++ delegate doesn't get pointer to the adapter in the callbacks. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:269: if (mUrlRequestAdapter != 0) { On 2014/10/29 16:20:48, mmenke wrote: > We have no protection against being restarted after we delete the > mUrlRequestAdapter. Suggest we add it, just as a precaution. Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:277: if (mUrlRequestAdapter != 0) { On 2014/10/29 16:20:47, mmenke wrote: > optional: Suggest early return instead. That's more in keeping with Chrome > style, and the other places you get this lock as well. Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:304: mListener.onError(this, mResponseInfo, requestError); On 2014/10/29 16:20:47, mmenke wrote: > We may not be on the executor at this point. Should either make sure > onCalledByNativeException is run on the executor, or post a task here. > > Also: We should have tests that make sure, when there's a single-threaded > executor, all callbacks are executor on that executor. > > Since our current tests use just such an executor, I suggest just updating the > current tests to all enforce that. The only caller not on executor is onAppendResponseHeader, I've added post there. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:326: private void onRedirect(final String newLocation, int httpStatusCode) { On 2014/10/29 16:20:47, mmenke wrote: > Do we get anything out of the final here? We could declare a bunch of other > values to be final, too (Like httpStatusCode). Compiler complains about newLocation as it is accessed from the posted task. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:339: nativeFollowDeferredRedirect(mUrlRequestAdapter); On 2014/10/29 16:20:48, mmenke wrote: > Have to check if mUrlRequestAdapterLock is NULL - onRedirect could have > cancelled the request, or it could have been cancelled on another thread. Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:366: nativeReceiveData(mUrlRequestAdapter); On 2014/10/29 16:20:47, mmenke wrote: > Have to check if mUrlRequestAdapterLock is NULL. Done. https://codereview.chromium.org/586143002/diff/660001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:403: nativeGetTotalReceivedBytes(mUrlRequestAdapter); On 2014/10/29 16:20:48, mmenke wrote: > Have to check if mUrlRequestAdapter is NULL here. Alternatively, could just ass > it in to onComplete from native code. Done.
I think things are really shaping up. Need to do another pass over the C++ code, particularly, but barring any major bugs discovered late in the process, think we may be able to land this week. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:28: private final Object mUrlRequestAdapterLock = new Object(); Should mention what this protects access to - should probably also put mStarted and mCancelled up with mUrlRequestAdapter, since they're associated with each other (They're also all lock protected, currently). https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:144: String url, int priority, nit: Seems more consistent to either fit the arguments on fewer lines, or have one argument per line. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:171: if (method == null) { Should we check for an empty string, too? Wonder if we should do full validation on this (no spaces, all ASCII letters (Maybe numbers and a couple symbols are allowed?), non-zero length). We currently don't do any of that C++-side, in UrlRequest, at least. Not needed for this CL, just wondering for the future. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:208: + header.getKey() + "=" + header.getValue()); Binary operators should go on the end of the line (At least that's the preferred C++ style, and the Java style guide doesn't say anything on the topic). https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:213: mStarted = true; Should set mStarted to true before calling into nativeStart, I think - otherwise, we could be calling back into |this| from native while started is false. We don't actually check that anywhere, but seems best to be safe. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:295: if (mUrlRequestAdapter != 0 || mStarted) { Can we just check mStarted? https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:344: * followed, unless the request is paused or cancelled during this nit: Comments use canceled, code uses canceled. Both are valid, and I don't really care which we use (Canceled being the US preferred way, and Cancelled being the one preferred elsewhere), but should be consistent. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:354: mUrlChain.add(newLocation); If we want to mimic net's behavior, we should only add the new url to the chain after we decide to follow the redirect. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:364: new URL(newLocation)); Should we use URLs or Strings? We take in the initial URL as a string and mUrlChain uses Strings, but we pass in a URL to the embedder here. Should be consistent. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:26: import java.util.regex.Pattern; Should there be blank lines between imports based on the first component or the first two components? When I searched through the code, the latter two looked more common to me (You're also doing that up top, with the two android imports) https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:66: class SimpleUrlRequestListener implements UrlRequestListener { For these tests, we should make sure the SimpleUrlRequestListener is called on the correct thread. There are a couple ways to do it - we could create a ThreadPoolExecutor with our own ThreadFactory, and keep a pointer to the single thread it created, and make sure that matches the current thread whenever we call into this. Or we could create our own thread, and add an executor for it. Probably other ways, first is probably the simplest. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:66: class SimpleUrlRequestListener implements UrlRequestListener { Should describe what this class does https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:82: private ConditionVariable mComplete = new ConditionVariable(); Should describe what this class does. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:92: || mLastCalled == LastCalled.OnRedirect); nit: Put || on previous line (x3) https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:126: openComplete(); nit: complete's over's overloaded here - onComplete means on successful completion, but blockForComplete means until done. Suggest changing the test-only "completes" to "done" to make it clear they're different. As for the API maybe onComplete -> onSuccess (Updating the API as well)? Open to other ideas. Think a non-ambiguous name is preferable (See earlier confusion with old API if we called the completion function on error or not). https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:328: + listener.mResponseAsString, nit: Operator on previous line. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:335: public void testMockSuccess() throws Exception { Check RedirectResponseInfoList is empty? https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:352: public void testMockRedirect() throws Exception { Check RedirectResponseInfoList's length in all redirect tests? https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:397: firstRedirectResponseInfo.getUrlChain()[0]); Check URL chain length? https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:397: firstRedirectResponseInfo.getUrlChain()[0]); Check secondRedirectResponseInfo.getUrlChain()[1]? (Unless you follow my comment about not including it until after we follow the redirect) https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:411: secondRedirectResponseInfo.getUrlChain()[2]); Check URL chain length here, too https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:436: int arbitraryNetError = -3; Hrm...make these test constants final? We'd prefix them with k in C++, but I guess not here. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:484: class CancelingUrlRequestListener extends SimpleUrlRequestListener { Should describe what this class does https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:485: nit: Remove blank line.
Thanks, PTAL. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:28: private final Object mUrlRequestAdapterLock = new Object(); On 2014/10/29 21:40:29, mmenke wrote: > Should mention what this protects access to - should probably also put mStarted > and mCancelled up with mUrlRequestAdapter, since they're associated with each > other (They're also all lock protected, currently). Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:144: String url, int priority, On 2014/10/29 21:40:29, mmenke wrote: > nit: Seems more consistent to either fit the arguments on fewer lines, or have > one argument per line. Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:171: if (method == null) { On 2014/10/29 21:40:29, mmenke wrote: > Should we check for an empty string, too? Wonder if we should do full > validation on this (no spaces, all ASCII letters (Maybe numbers and a couple > symbols are allowed?), non-zero length). We currently don't do any of that > C++-side, in UrlRequest, at least. > > Not needed for this CL, just wondering for the future. Good question, rfc2616 says that 'extension-method' is a token, and rfc1945 says that token is token = 1*<any CHAR except CTLs or tspecials> tspecials = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT Apparently http header name is also a token, so maybe we can just apply the same check? https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:208: + header.getKey() + "=" + header.getValue()); On 2014/10/29 21:40:29, mmenke wrote: > Binary operators should go on the end of the line (At least that's the preferred > C++ style, and the Java style guide doesn't say anything on the topic). Yeah, that's what I thought and had, but new Java presubmit check convinced me otherwise. :( https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:213: mStarted = true; On 2014/10/29 21:40:29, mmenke wrote: > Should set mStarted to true before calling into nativeStart, I think - > otherwise, we could be calling back into |this| from native while started is > false. We don't actually check that anywhere, but seems best to be safe. Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:295: if (mUrlRequestAdapter != 0 || mStarted) { On 2014/10/29 21:40:29, mmenke wrote: > Can we just check mStarted? Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:344: * followed, unless the request is paused or cancelled during this On 2014/10/29 21:40:29, mmenke wrote: > nit: Comments use canceled, code uses canceled. Both are valid, and I don't > really care which we use (Canceled being the US preferred way, and Cancelled > being the one preferred elsewhere), but should be consistent. Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:354: mUrlChain.add(newLocation); On 2014/10/29 21:40:29, mmenke wrote: > If we want to mimic net's behavior, we should only add the new url to the chain > after we decide to follow the redirect. Interesting. This is a good place to add while we are on network thread. It is a bit weird to do that in task running on executor, but I guess it is ok as there will be no other accessors or modifiers until we call back into native code. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:364: new URL(newLocation)); On 2014/10/29 21:40:29, mmenke wrote: > Should we use URLs or Strings? We take in the initial URL as a string and > mUrlChain uses Strings, but we pass in a URL to the embedder here. Should be > consistent. Done. I'm voting for Strings as I suspect that constructing URL is not trivial resource wise and chances are that embedder doesn't really care much about it anyway. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:26: import java.util.regex.Pattern; On 2014/10/29 21:40:30, mmenke wrote: > Should there be blank lines between imports based on the first component or the > first two components? When I searched through the code, the latter two looked > more common to me (You're also doing that up top, with the two android imports) Good question. I'd say just first component, but I could be wrong. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:66: class SimpleUrlRequestListener implements UrlRequestListener { On 2014/10/29 21:40:29, mmenke wrote: > Should describe what this class does Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:66: class SimpleUrlRequestListener implements UrlRequestListener { On 2014/10/29 21:40:30, mmenke wrote: > For these tests, we should make sure the SimpleUrlRequestListener is called on > the correct thread. > > There are a couple ways to do it - we could create a ThreadPoolExecutor with our > own ThreadFactory, and keep a pointer to the single thread it created, and make > sure that matches the current thread whenever we call into this. Or we could > create our own thread, and add an executor for it. Probably other ways, first > is probably the simplest. Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:82: private ConditionVariable mComplete = new ConditionVariable(); On 2014/10/29 21:40:30, mmenke wrote: > Should describe what this class does. Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:92: || mLastCalled == LastCalled.OnRedirect); On 2014/10/29 21:40:30, mmenke wrote: > nit: Put || on previous line (x3) presubmit made me do it, I swear! https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:126: openComplete(); On 2014/10/29 21:40:29, mmenke wrote: > nit: complete's over's overloaded here - onComplete means on successful > completion, but blockForComplete means until done. > > Suggest changing the test-only "completes" to "done" to make it clear they're > different. > > As for the API maybe onComplete -> onSuccess (Updating the API as well)? Open > to other ideas. Think a non-ambiguous name is preferable (See earlier confusion > with old API if we called the completion function on error or not). Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:328: + listener.mResponseAsString, On 2014/10/29 21:40:30, mmenke wrote: > nit: Operator on previous line. Presubmit fails if so. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:335: public void testMockSuccess() throws Exception { On 2014/10/29 21:40:29, mmenke wrote: > Check RedirectResponseInfoList is empty? Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:352: public void testMockRedirect() throws Exception { On 2014/10/29 21:40:29, mmenke wrote: > Check RedirectResponseInfoList's length in all redirect tests? Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:397: firstRedirectResponseInfo.getUrlChain()[0]); On 2014/10/29 21:40:30, mmenke wrote: > Check URL chain length? Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:411: secondRedirectResponseInfo.getUrlChain()[2]); On 2014/10/29 21:40:29, mmenke wrote: > Check URL chain length here, too Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:436: int arbitraryNetError = -3; On 2014/10/29 21:40:29, mmenke wrote: > Hrm...make these test constants final? We'd prefix them with k in C++, but I > guess not here. Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:484: class CancelingUrlRequestListener extends SimpleUrlRequestListener { On 2014/10/29 21:40:29, mmenke wrote: > Should describe what this class does Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:485: On 2014/10/29 21:40:30, mmenke wrote: > nit: Remove blank line. Done.
https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:171: if (method == null) { On 2014/10/30 03:01:32, mef wrote: > On 2014/10/29 21:40:29, mmenke wrote: > > Should we check for an empty string, too? Wonder if we should do full > > validation on this (no spaces, all ASCII letters (Maybe numbers and a couple > > symbols are allowed?), non-zero length). We currently don't do any of that > > C++-side, in UrlRequest, at least. > > > > Not needed for this CL, just wondering for the future. > > Good question, rfc2616 says that 'extension-method' is a token, and rfc1945 says > that token is > > token = 1*<any CHAR except CTLs or tspecials> > > tspecials = "(" | ")" | "<" | ">" | "@" > | "," | ";" | ":" | "\" | <"> > | "/" | "[" | "]" | "?" | "=" > | "{" | "}" | SP | HT > > Apparently http header name is also a token, so maybe we can just apply the same > check? Done. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:354: mUrlChain.add(newLocation); On 2014/10/30 03:01:32, mef wrote: > On 2014/10/29 21:40:29, mmenke wrote: > > If we want to mimic net's behavior, we should only add the new url to the > chain > > after we decide to follow the redirect. > Interesting. This is a good place to add while we are on network thread. > It is a bit weird to do that in task running on executor, but I guess it is ok > as there will be no other accessors or modifiers until we call back into native > code. Done.
Note: I have a fair number of other reviews to do today, so probably won't get to this until this afternoon.
More comments, will get back to this tomorrow. https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:26: import java.util.regex.Pattern; On 2014/10/30 03:01:32, mef wrote: > On 2014/10/29 21:40:30, mmenke wrote: > > Should there be blank lines between imports based on the first component or > the > > first two components? When I searched through the code, the latter two looked > > more common to me (You're also doing that up top, with the two android > imports) > > Good question. I'd say just first component, but I could be wrong. Android style guide indicates it's just first component, so let's go with that unless we hear otherwise. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:465: destroyRequestAdapter(); Suggestion: Destroy the adapter first. Then onComplete can shutdown the context, if it so desires. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:492: destroyRequestAdapter(); Suggestion: Destroy the adapter first. Then onComplete can shutdown the context, if it so desires. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:494: onCalledByNativeException(e); If onError throws an exception, does it really make sense to call onError again? https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:57: public void onComplete(UrlRequest request, ExtendedResponseInfo info); What do you think of my suggestion to rename this to unambiguously indicate it's only called on success? My suggestion was onSuccess, but open to other ideas. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:79: openComplete(); Per earlier comments, should rename this stuff...or better, share the same UrlRequestListener between test fixtures. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:104: CronetTestActivity.CONFIG_KEY, config.toString() }; Unless it makes the Java style checker sad (In which case, I think we should stage a violent rebellion using the largest lobster forks we can find on Google Express), "};" should be on the next line. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:108: assertNotNull(mActivity); Can we just put this in "launchCronetTestAppWithUrlAndCommandLineArgs", if it's not there already? https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:146: mExecutor.awaitTermination(5, TimeUnit.SECONDS); I don't think we should force the embedder to wait for the executor to shut down before they can call shutdown on the context - as soon as all requests have completed, it should be safe for them to do so. To this end, I also suggest 2 more shutdown tests: One with an error, and with a cancel just before it.
Thanks, PTAL! https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:465: destroyRequestAdapter(); On 2014/10/30 21:47:56, mmenke wrote: > Suggestion: Destroy the adapter first. Then onComplete can shutdown the > context, if it so desires. Done. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:492: destroyRequestAdapter(); On 2014/10/30 21:47:56, mmenke wrote: > Suggestion: Destroy the adapter first. Then onComplete can shutdown the > context, if it so desires. Done. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:494: onCalledByNativeException(e); On 2014/10/30 21:47:56, mmenke wrote: > If onError throws an exception, does it really make sense to call onError again? Done. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:57: public void onComplete(UrlRequest request, ExtendedResponseInfo info); On 2014/10/30 21:47:56, mmenke wrote: > What do you think of my suggestion to rename this to unambiguously indicate it's > only called on success? My suggestion was onSuccess, but open to other ideas. I like that. I don't totally like onSuccess as it doesn't mention that it is complete. OTOH 'onCompleteSuccess' is a bit over the top. :) https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:79: openComplete(); On 2014/10/30 21:47:57, mmenke wrote: > Per earlier comments, should rename this stuff... Done. > or better, share the same UrlRequestListener between test fixtures. Agreed, in another CL? https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:104: CronetTestActivity.CONFIG_KEY, config.toString() }; On 2014/10/30 21:47:56, mmenke wrote: > Unless it makes the Java style checker sad (In which case, I think we should > stage a violent rebellion using the largest lobster forks we can find on Google > Express), "};" should be on the next line. Done. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:108: assertNotNull(mActivity); On 2014/10/30 21:47:56, mmenke wrote: > Can we just put this in "launchCronetTestAppWithUrlAndCommandLineArgs", if it's > not there already? Done. https://codereview.chromium.org/586143002/diff/730001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:146: mExecutor.awaitTermination(5, TimeUnit.SECONDS); On 2014/10/30 21:47:56, mmenke wrote: > I don't think we should force the embedder to wait for the executor to shut down > before they can call shutdown on the context - as soon as all requests have > completed, it should be safe for them to do so. > > To this end, I also suggest 2 more shutdown tests: One with an error, and with > a cancel just before it. Done.
Still reviewing, though I have a couple other reviews I need to do today, too. Suggest you also look for stuff in tests and C-side that could use some documentation, seems like we're a bit light there. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:68: logging::SetMinLogLevel(static_cast<int>(jlog_level)); Suggestion: Don't take this on context creation, make it a static method instead. Makes it clear its a global, and can have documentation that it affects existing contexts as well as new ones. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:72: base::Closure init_java_network_thread = base::Bind ( nit: Remove space before open paren. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:74: jenv->NewGlobalRef(jcaller)); Can we used a scoped java ref here? Does, admittedly, result in grabbing references twice, but prefer to avoid naked pointers and the Java equivalent to minimize the risk of leaks, particularly given the lack of testing we have for them. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:136: const base::Closure& init_java_network_thread) { optional: Maybe java_init_network_thread? (It's more of a C++ thread that we're initializing stuff on with a Java call, than a Java network thread we're initing stuff on). Or maybe init_network_thread_java... Alternatively, there's nothing in this class that really depends on java. Could just get rid of the java. Anyhow, up to you, don't feel strongly about this. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:194: StopNetLog(); StopNetLogOnNetworkThread() (And should test that) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:195: context_.reset(); Not needed, since it's in a scoped_ptr. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:16: #include "net/url_request/url_request_context_getter.h" Not used https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:31: // Adapter between Java CronetUrlRequestContext and URLRequestContextGetter. URLRequestContextGetter -> URLRequestContext https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:36: const base::Closure& init_java_network_thread); nit: suggest a linebreak above and below Initialize() declaration, for readability. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:40: // net::URLRequestContextGetter implementation: Not true. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:41: net::URLRequestContext* GetURLRequestContext(); Add line break after method. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:42: scoped_refptr<base::SingleThreadTaskRunner> Maybe const scoped_refptr<>&, to avoid an extra reference count increment/decrement at all call sites? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:48: virtual ~CronetURLRequestContextAdapter(); -virtual https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:51: scoped_ptr<net::URLRequestContext> context_; Should mention that the context_ and logger_ may only be accessed on the network thread. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:51: scoped_ptr<net::URLRequestContext> context_; Context should be last, after everything it depends on. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:52: base::Thread* network_thread_; Hrm...guess we can't put this into a scoped_ptr and then pop it out on destroy() because of all the thread correctness DCHECKs. Think we should comment on its ownership model here. Another option, which I think makes ownership clearer, is to split it into two classes: CronetURLRequestContextAdapter and CronetURLRequestContextAdaperCore (Or something like that - that is a bit unwieldy). Have the Core only dereferenced on the the network thread, and the adapter only dereferenced on Java threads. The adapter owns the core and the thread. For destruction, just posts a message to delete the core to the network thread, and then deletes itself. Not a huge improvement, but does make ownership a bit clearer. Even if we don't go with that architecture now, think we may well want to go in that direction longer term (And possibly for the request, too) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:56: void InitializeOnNetworkThread(scoped_ptr<URLRequestContextConfig> config, Fix indent (Either move config to the next line, or indent the other line to align with it) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:57: const base::Closure& init_java_network_thread); Should include callback.h https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:26: // URL used for base tests. unclear what a "base" test is. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:34: class BlockingUrlRequestListener implements UrlRequestListener { Should comment this class https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:37: public byte[] mLastDataReceivedAsBytes; nit: No need for this https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:43: public BlockingUrlRequestListener(boolean blockOnStarted) { Should have a comment about the argument. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:124: new BlockingUrlRequestListener(true); Should mention in the two tests that block for start why it's necessary. And kudos for realizing they both need it. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:138: mActivity.mUrlRequestContext.shutdown(); Actually, could we have the listener call shutdown instead in openDone, before mucking with the ConditionVariable in this test and the next? that way we make sure it's safe to call shutdown during destruction. Downside is that on failure, the tests would just hang, but the tests would be more robust against regression. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:75: /** Listener that tracks information from different callbacks nit: Put listener on next line (Typically no text is put on the "/**" line, except for some single line comments) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:76: * and opens conditional variable |mDone| when request is done. I don't think "mDone" should be mentioned explicitly. Maybe "and has a method to block until thread until the request completes on another thread?" https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:179: mExecutor.awaitTermination(5, TimeUnit.SECONDS); Does this have to go before context shutdown? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:180: mActivity.mUrlRequestContext.shutdown(); UploadTestServer.shutdownUploadTestServer? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:282: urlRequest.addHeader("headername", "bad header\r\nvalue"); I don't object, but does this add anything to the test? Maybe set this in another try block, on another request? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:336: public void testCustomUserAgent() throws Exception { Don't we already test this in the context test file? I'm fine testing it in either place, but doesn't seem like we should have two tests for it. Either way, should be in the same file as testDefaultUserAgent, presumably. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:417: assertEquals(200, mResponseInfo.getHttpStatusCode()); Maybe add something like "// Check final response (success.html)"? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:428: assertEquals(2, listener.mRedirectResponseInfoList.size()); Suggest checking the redirects first - chronological order just seems more intuitive. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:430: // Check First redirect (multiredirect.html -> redirect.html) First -> first https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:441: // Check Second redirect (redirect.html -> success.txt) Second -> second
More nits (Sorry for all the nits, but minor followup cleanups tend to be rarely done, except when somewhat related to new features or bugfixes) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:48: owner_.Reset(jenv, jowner); Can put owner_(jowner) in the initialized list instead. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:80: void OnError(int error) override { Suggest calling this net_error (And in CronetURLRequestAdapterDelegate, too) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:90: virtual ~JniCronetURLRequestAdapterDelegate() { -virtual +override https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:94: base::android::ScopedJavaGlobalRef<jobject> owner_; Should this be jowner_? I'm not sure, myself. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:153: jstring jmethod) { Fix indent https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:160: // Http Method is a token, just as Header name. nit: Method -> method. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.h:27: // Define request priority values like CRONET_REQUEST_ERROR_SUCCESS in a These aren't "request priority values"... More importantly, though, they aren't even used, so we can get rid of them. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:20: static const size_t kBufferSizeIncrement = 32768; nit: Maybe kReadBufferSize? We never increment the buffer size. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:20: static const size_t kBufferSizeIncrement = 32768; size_t -> int (IOBuffers use integer sizes - results are always ints, so can indicate we read any more than that, anyways) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:32: initial_priority_ = priority; These should all be in the initializer list (And most of them should probably be const) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:36: url_request_.reset(); Not needed - that's what scoped_ptrs are for. :) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:51: return NULL; Do we ever call any of these when the request is NULL? Since they're called from the adapter on the network thread during a callback from the url_request_, I don't think so, so none of these checks should be needed. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:110: // net::URLRequest::Delegate overrides (called on network thread). nit: This applies to multiple methods, so should add a blank line below it. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:186: url_request_->Cancel(); This isn't needed - requests call cancel on destruction, anyways (And don't call into their delegate). https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:191: bool CronetURLRequestAdapter::CheckStatus(net::URLRequest* request) { Maybe call this MaybeReportError (Or failure?) Not clear from the name that is actually does something if it detects an error. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:39: : public base::RefCountedThreadSafe<CronetURLRequestAdapterDelegate> { I don't think this needs to be refcounted now, does it? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:54: CronetURLRequestAdapterDelegate* delegate, The delegate should probably be passed as a const scoped_refptr<>& (Or as a scoped_ptr, if you make it no longer ref counted) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:60: void SetMethod(const std::string& method); nit: set_method + inline? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:88: std::string GetNegotiatedProtocol() const; const std::string&? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:103: nit: Remove blank line between overrides from same parent class. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:105: // Returns true if currently running on network thread. Add blank line before comment. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:112: void DestroyOnNetworkThread(); nit: Suggest blank line after DestroyOnNetworkThread. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:115: bool CheckStatus(net::URLRequest* request); nit: const https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:120: net::RequestPriority initial_priority_; A couple of these can be const. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:123: scoped_ptr<net::URLRequest> url_request_; The request should probably go last, since it depends on the read_buffer_ (The ref counting means it doesn't really matter, of course) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:123: scoped_ptr<net::URLRequest> url_request_; Can this be a "const scoped_ptr<net::URLRequest>" (Indicate the URLRequest pointer never changes)?
https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/680001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:208: + header.getKey() + "=" + header.getValue()); On 2014/10/30 03:01:31, mef wrote: > On 2014/10/29 21:40:29, mmenke wrote: > > Binary operators should go on the end of the line (At least that's the > preferred > > C++ style, and the Java style guide doesn't say anything on the topic). > > Yeah, that's what I thought and had, but new Java presubmit check convinced me > otherwise. :( It seems that google java style guide recommends breaking before non-assignment operators. See https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s4.5-line-w...
A couple more comments.Looks good! https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:257: * Post task to application Executor or Looper. Used for Listener callbacks mExecutor is an executor. Why does the comment also mention "Looper"? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:418: * Called whenever data is received. The ByteBuffer remains nit: two spaces after "." and on line 420. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestException.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestException.java:10: * Missing java doc. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:25: ResponseInfo info, Sorry my bad. Java uses +8 indentation for parameters. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:48: ResponseInfo info, Use +8 indentation instead. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:61: * called, no other functions can be called. UrlRequestException nit:It is unclear what "other functions" this comment refers to? Could you give an example in the comment as well? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:69: ResponseInfo info, Use +8 indentation instead. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:149: UrlRequestException error) { Why onError is not a part of LastCalled enum? Maybe this deserves a comment at the LastCalled enum.
Thanks! https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:48: owner_.Reset(jenv, jowner); On 2014/10/31 19:16:22, mmenke wrote: > Can put owner_(jowner) in the initialized list instead. Hmm, I get weird build errors. How do I express that? https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:80: void OnError(int error) override { On 2014/10/31 19:16:22, mmenke wrote: > Suggest calling this net_error (And in CronetURLRequestAdapterDelegate, too) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:90: virtual ~JniCronetURLRequestAdapterDelegate() { On 2014/10/31 19:16:22, mmenke wrote: > -virtual +override Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:94: base::android::ScopedJavaGlobalRef<jobject> owner_; On 2014/10/31 19:16:22, mmenke wrote: > Should this be jowner_? I'm not sure, myself. My understanding is that jxyz naming applies to parameters passed from java. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:153: jstring jmethod) { On 2014/10/31 19:16:22, mmenke wrote: > Fix indent Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:160: // Http Method is a token, just as Header name. On 2014/10/31 19:16:22, mmenke wrote: > nit: Method -> method. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.h:27: // Define request priority values like CRONET_REQUEST_ERROR_SUCCESS in a On 2014/10/31 19:16:22, mmenke wrote: > These aren't "request priority values"... More importantly, though, they aren't > even used, so we can get rid of them. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:20: static const size_t kBufferSizeIncrement = 32768; On 2014/10/31 19:16:22, mmenke wrote: > size_t -> int (IOBuffers use integer sizes - results are always ints, so can > indicate we read any more than that, anyways) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:20: static const size_t kBufferSizeIncrement = 32768; On 2014/10/31 19:16:22, mmenke wrote: > nit: Maybe kReadBufferSize? We never increment the buffer size. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:32: initial_priority_ = priority; On 2014/10/31 19:16:22, mmenke wrote: > These should all be in the initializer list (And most of them should probably be > const) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:36: url_request_.reset(); On 2014/10/31 19:16:22, mmenke wrote: > Not needed - that's what scoped_ptrs are for. :) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:51: return NULL; On 2014/10/31 19:16:22, mmenke wrote: > Do we ever call any of these when the request is NULL? Since they're called > from the adapter on the network thread during a callback from the url_request_, > I don't think so, so none of these checks should be needed. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:110: // net::URLRequest::Delegate overrides (called on network thread). On 2014/10/31 19:16:22, mmenke wrote: > nit: This applies to multiple methods, so should add a blank line below it. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:186: url_request_->Cancel(); On 2014/10/31 19:16:22, mmenke wrote: > This isn't needed - requests call cancel on destruction, anyways (And don't call > into their delegate). Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:191: bool CronetURLRequestAdapter::CheckStatus(net::URLRequest* request) { On 2014/10/31 19:16:22, mmenke wrote: > Maybe call this MaybeReportError (Or failure?) Not clear from the name that is > actually does something if it detects an error. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:60: void SetMethod(const std::string& method); On 2014/10/31 19:16:23, mmenke wrote: > nit: set_method + inline? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:88: std::string GetNegotiatedProtocol() const; On 2014/10/31 19:16:23, mmenke wrote: > const std::string&? It returns an empty string if |url_request_| is null. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:103: On 2014/10/31 19:16:23, mmenke wrote: > nit: Remove blank line between overrides from same parent class. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:105: // Returns true if currently running on network thread. On 2014/10/31 19:16:23, mmenke wrote: > Add blank line before comment. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:112: void DestroyOnNetworkThread(); On 2014/10/31 19:16:23, mmenke wrote: > nit: Suggest blank line after DestroyOnNetworkThread. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:115: bool CheckStatus(net::URLRequest* request); On 2014/10/31 19:16:22, mmenke wrote: > nit: const Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:120: net::RequestPriority initial_priority_; On 2014/10/31 19:16:22, mmenke wrote: > A couple of these can be const. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:123: scoped_ptr<net::URLRequest> url_request_; On 2014/10/31 19:16:22, mmenke wrote: > The request should probably go last, since it depends on the read_buffer_ (The > ref counting means it doesn't really matter, of course) Um, then how is it set for the first time (It is NOT created in constructor). https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:68: logging::SetMinLogLevel(static_cast<int>(jlog_level)); On 2014/10/31 15:49:22, mmenke wrote: > Suggestion: Don't take this on context creation, make it a static method > instead. Makes it clear its a global, and can have documentation that it > affects existing contexts as well as new ones. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:72: base::Closure init_java_network_thread = base::Bind ( On 2014/10/31 15:49:22, mmenke wrote: > nit: Remove space before open paren. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:74: jenv->NewGlobalRef(jcaller)); On 2014/10/31 15:49:22, mmenke wrote: > Can we used a scoped java ref here? Does, admittedly, result in grabbing > references twice, but prefer to avoid naked pointers and the Java equivalent to > minimize the risk of leaks, particularly given the lack of testing we have for > them. Acknowledged. We probably can, but I'm not sure how to pass it correctly. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:136: const base::Closure& init_java_network_thread) { On 2014/10/31 15:49:22, mmenke wrote: > optional: Maybe java_init_network_thread? (It's more of a C++ thread that > we're initializing stuff on with a Java call, than a Java network thread we're > initing stuff on). Or maybe init_network_thread_java... > > Alternatively, there's nothing in this class that really depends on java. Could > just get rid of the java. Anyhow, up to you, don't feel strongly about this. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:194: StopNetLog(); On 2014/10/31 15:49:22, mmenke wrote: > StopNetLogOnNetworkThread() (And should test that) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:195: context_.reset(); On 2014/10/31 15:49:22, mmenke wrote: > Not needed, since it's in a scoped_ptr. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:16: #include "net/url_request/url_request_context_getter.h" On 2014/10/31 15:49:22, mmenke wrote: > Not used Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:31: // Adapter between Java CronetUrlRequestContext and URLRequestContextGetter. On 2014/10/31 15:49:22, mmenke wrote: > URLRequestContextGetter -> URLRequestContext Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:36: const base::Closure& init_java_network_thread); On 2014/10/31 15:49:22, mmenke wrote: > nit: suggest a linebreak above and below Initialize() declaration, for > readability. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:40: // net::URLRequestContextGetter implementation: On 2014/10/31 15:49:22, mmenke wrote: > Not true. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:41: net::URLRequestContext* GetURLRequestContext(); On 2014/10/31 15:49:22, mmenke wrote: > Add line break after method. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:42: scoped_refptr<base::SingleThreadTaskRunner> On 2014/10/31 15:49:23, mmenke wrote: > Maybe const scoped_refptr<>&, to avoid an extra reference count > increment/decrement at all call sites? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:48: virtual ~CronetURLRequestContextAdapter(); On 2014/10/31 15:49:23, mmenke wrote: > -virtual Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:51: scoped_ptr<net::URLRequestContext> context_; On 2014/10/31 15:49:22, mmenke wrote: > Should mention that the context_ and logger_ may only be accessed on the network > thread. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:51: scoped_ptr<net::URLRequestContext> context_; On 2014/10/31 15:49:23, mmenke wrote: > Context should be last, after everything it depends on. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:52: base::Thread* network_thread_; On 2014/10/31 15:49:22, mmenke wrote: > Hrm...guess we can't put this into a scoped_ptr and then pop it out on destroy() > because of all the thread correctness DCHECKs. Think we should comment on its > ownership model here. > > Another option, which I think makes ownership clearer, is to split it into two > classes: CronetURLRequestContextAdapter and CronetURLRequestContextAdaperCore > (Or something like that - that is a bit unwieldy). Have the Core only > dereferenced on the the network thread, and the adapter only dereferenced on > Java threads. The adapter owns the core and the thread. For destruction, just > posts a message to delete the core to the network thread, and then deletes > itself. > > Not a huge improvement, but does make ownership a bit clearer. Even if we don't > go with that architecture now, think we may well want to go in that direction > longer term (And possibly for the request, too) Acknowledged. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:56: void InitializeOnNetworkThread(scoped_ptr<URLRequestContextConfig> config, On 2014/10/31 15:49:22, mmenke wrote: > Fix indent (Either move config to the next line, or indent the other line to > align with it) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:57: const base::Closure& init_java_network_thread); On 2014/10/31 15:49:22, mmenke wrote: > Should include callback.h Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:257: * Post task to application Executor or Looper. Used for Listener callbacks On 2014/10/31 19:57:21, xunjieli wrote: > mExecutor is an executor. Why does the comment also mention "Looper"? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:418: * Called whenever data is received. The ByteBuffer remains On 2014/10/31 19:57:21, xunjieli wrote: > nit: two spaces after "." and on line 420. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestException.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestException.java:10: * On 2014/10/31 19:57:21, xunjieli wrote: > Missing java doc. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:25: ResponseInfo info, On 2014/10/31 19:57:21, xunjieli wrote: > Sorry my bad. Java uses +8 indentation for parameters. No worries, it looks good and presubmit style checker is happy. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:26: // URL used for base tests. On 2014/10/31 15:49:23, mmenke wrote: > unclear what a "base" test is. Acknowledged. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:34: class BlockingUrlRequestListener implements UrlRequestListener { On 2014/10/31 15:49:23, mmenke wrote: > Should comment this class Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:37: public byte[] mLastDataReceivedAsBytes; On 2014/10/31 15:49:23, mmenke wrote: > nit: No need for this Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:43: public BlockingUrlRequestListener(boolean blockOnStarted) { On 2014/10/31 15:49:23, mmenke wrote: > Should have a comment about the argument. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:124: new BlockingUrlRequestListener(true); On 2014/10/31 15:49:23, mmenke wrote: > Should mention in the two tests that block for start why it's necessary. And > kudos for realizing they both need it. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:138: mActivity.mUrlRequestContext.shutdown(); On 2014/10/31 15:49:23, mmenke wrote: > Actually, could we have the listener call shutdown instead in openDone, before > mucking with the ConditionVariable in this test and the next? that way we make > sure it's safe to call shutdown during destruction. > > Downside is that on failure, the tests would just hang, but the tests would be > more robust against regression. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:75: /** Listener that tracks information from different callbacks On 2014/10/31 15:49:23, mmenke wrote: > nit: Put listener on next line (Typically no text is put on the "/**" line, > except for some single line comments) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:76: * and opens conditional variable |mDone| when request is done. On 2014/10/31 15:49:23, mmenke wrote: > I don't think "mDone" should be mentioned explicitly. Maybe "and has a method > to block until thread until the request completes on another thread?" Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:179: mExecutor.awaitTermination(5, TimeUnit.SECONDS); On 2014/10/31 15:49:23, mmenke wrote: > Does this have to go before context shutdown? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:180: mActivity.mUrlRequestContext.shutdown(); On 2014/10/31 15:49:23, mmenke wrote: > UploadTestServer.shutdownUploadTestServer? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:282: urlRequest.addHeader("headername", "bad header\r\nvalue"); On 2014/10/31 15:49:23, mmenke wrote: > I don't object, but does this add anything to the test? Maybe set this in > another try block, on another request? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:336: public void testCustomUserAgent() throws Exception { On 2014/10/31 15:49:23, mmenke wrote: > Don't we already test this in the context test file? I'm fine testing it in > either place, but doesn't seem like we should have two tests for it. Either > way, should be in the same file as testDefaultUserAgent, presumably. Context allows setting User-Agent globally via config, this test is for local override per request. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:417: assertEquals(200, mResponseInfo.getHttpStatusCode()); On 2014/10/31 15:49:23, mmenke wrote: > Maybe add something like "// Check final response (success.html)"? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:428: assertEquals(2, listener.mRedirectResponseInfoList.size()); On 2014/10/31 15:49:23, mmenke wrote: > Suggest checking the redirects first - chronological order just seems more > intuitive. Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:430: // Check First redirect (multiredirect.html -> redirect.html) On 2014/10/31 15:49:23, mmenke wrote: > First -> first Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:441: // Check Second redirect (redirect.html -> success.txt) On 2014/10/31 15:49:23, mmenke wrote: > Second -> second Done.
https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:176: bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest* request) const { nit: I often find "Maybe*" methods hard to reason about. Perhaps add a comment to this method? Sth along the line of "Returns whether |request| has an error, and propagates the error to the delegate if there is one." https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:260: private void postAppTask(Runnable task) { nit: maybe it makes sense to rename this method to sth like postTaskToExecutor(Runnable task) ? https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:48: ResponseInfo info, nit: use +8 indentation and on line 70. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetTestBase.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetTestBase.java:17: nit: extra blank line. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:31: * Listener that shutdowns the request context when request has Succeeded nit: lowercase "S" and "F". https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:43: ResponseInfo info, nit: +8 indentation. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:95: //mActivity.mUrlRequestContext.shutdown(); Remove stale code line 95 and 109. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:122: listener.getExecutor()); nit: this fits on the line above. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:27: * method to block until thread until the request completes on another thread. nit: there are two "until" https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:71: OnComplete Since onError is not a part of this enum, does it make sense to rename LastCalled to sth like FailureStep/FailureStage? https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:157: ResponseInfo info, nit: +8 indent.
Quick responses to your responses. I don't think we're going to make it to 1000 comments. Too bad. :) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:48: owner_.Reset(jenv, jowner); On 2014/10/31 20:39:14, mef wrote: > On 2014/10/31 19:16:22, mmenke wrote: > > Can put owner_(jowner) in the initialized list instead. > > Hmm, I get weird build errors. How do I express that? Oops...doesn't work. Only works with other ScopedJavaRefs (local or global). https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:88: std::string GetNegotiatedProtocol() const; On 2014/10/31 20:39:15, mef wrote: > On 2014/10/31 19:16:23, mmenke wrote: > > const std::string&? > > It returns an empty string if |url_request_| is null. Per earlier comment, that doesn't happen. :) https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:123: scoped_ptr<net::URLRequest> url_request_; On 2014/10/31 20:39:15, mef wrote: > On 2014/10/31 19:16:22, mmenke wrote: > > The request should probably go last, since it depends on the read_buffer_ (The > > ref counting means it doesn't really matter, of course) > > Um, then how is it set for the first time (It is NOT created in constructor). Oops. Good point. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:74: jenv->NewGlobalRef(jcaller)); On 2014/10/31 20:39:15, mef wrote: > On 2014/10/31 15:49:22, mmenke wrote: > > Can we used a scoped java ref here? Does, admittedly, result in grabbing > > references twice, but prefer to avoid naked pointers and the Java equivalent > to > > minimize the risk of leaks, particularly given the lack of testing we have for > > them. > > Acknowledged. We probably can, but I'm not sure how to pass it correctly. Think you just pass it as a ScopedJavaGlobalRef (Or const ScopedJavaGlobalRef&, to avoid an extra increment/decrements) So it'd look like: ScopedJavaGlobalRef blah; blah.Reset(env, jcaller); ...base::Bind(..., blah);
Oh, something else to test...What happens when we get weird characters in a header, both in the UTF-8 and non-unicode case. Fine with doing that in another CL.
Thanks, PTAL! https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:39: : public base::RefCountedThreadSafe<CronetURLRequestAdapterDelegate> { On 2014/10/31 19:16:23, mmenke wrote: > I don't think this needs to be refcounted now, does it? Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:54: CronetURLRequestAdapterDelegate* delegate, On 2014/10/31 19:16:22, mmenke wrote: > The delegate should probably be passed as a const scoped_refptr<>& (Or as a > scoped_ptr, if you make it no longer ref counted) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:88: std::string GetNegotiatedProtocol() const; On 2014/10/31 21:03:24, mmenke wrote: > On 2014/10/31 20:39:15, mef wrote: > > On 2014/10/31 19:16:23, mmenke wrote: > > > const std::string&? > > > > It returns an empty string if |url_request_| is null. > > Per earlier comment, that doesn't happen. :) Done. https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/750001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:74: jenv->NewGlobalRef(jcaller)); On 2014/10/31 21:03:24, mmenke wrote: > On 2014/10/31 20:39:15, mef wrote: > > On 2014/10/31 15:49:22, mmenke wrote: > > > Can we used a scoped java ref here? Does, admittedly, result in grabbing > > > references twice, but prefer to avoid naked pointers and the Java equivalent > > to > > > minimize the risk of leaks, particularly given the lack of testing we have > for > > > them. > > > > Acknowledged. We probably can, but I'm not sure how to pass it correctly. > > Think you just pass it as a ScopedJavaGlobalRef (Or const ScopedJavaGlobalRef&, > to avoid an extra increment/decrements) > > So it'd look like: > > ScopedJavaGlobalRef blah; > blah.Reset(env, jcaller); > > ...base::Bind(..., blah); Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:176: bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest* request) const { On 2014/10/31 21:01:51, xunjieli wrote: > nit: I often find "Maybe*" methods hard to reason about. Perhaps add a comment > to this method? Sth along the line of "Returns whether |request| has an error, > and propagates the error to the delegate if there is one." Acknowledged. There is a comment in the .h file, is it not clear enough? https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:260: private void postAppTask(Runnable task) { On 2014/10/31 21:01:51, xunjieli wrote: > nit: maybe it makes sense to rename this method to sth like > postTaskToExecutor(Runnable task) ? Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetTestBase.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetTestBase.java:17: On 2014/10/31 21:01:51, xunjieli wrote: > nit: extra blank line. Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:31: * Listener that shutdowns the request context when request has Succeeded On 2014/10/31 21:01:51, xunjieli wrote: > nit: lowercase "S" and "F". Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:43: ResponseInfo info, On 2014/10/31 21:01:51, xunjieli wrote: > nit: +8 indentation. Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:95: //mActivity.mUrlRequestContext.shutdown(); On 2014/10/31 21:01:51, xunjieli wrote: > Remove stale code line 95 and 109. Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:122: listener.getExecutor()); On 2014/10/31 21:01:51, xunjieli wrote: > nit: this fits on the line above. Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:27: * method to block until thread until the request completes on another thread. On 2014/10/31 21:01:51, xunjieli wrote: > nit: there are two "until" Done. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:71: OnComplete On 2014/10/31 21:01:51, xunjieli wrote: > Since onError is not a part of this enum, does it make sense to rename > LastCalled to sth like FailureStep/FailureStage? Hmm, it is also used in asserts below to verify correct order of callbacks. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:157: ResponseInfo info, On 2014/10/31 21:01:51, xunjieli wrote: > nit: +8 indent. Done. I don't like it though...
https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:176: bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest* request) const { On 2014/10/31 21:43:15, mef wrote: > On 2014/10/31 21:01:51, xunjieli wrote: > > nit: I often find "Maybe*" methods hard to reason about. Perhaps add a comment > > to this method? Sth along the line of "Returns whether |request| has an error, > > and propagates the error to the delegate if there is one." > > Acknowledged. There is a comment in the .h file, is it not clear enough? Sorry, I didn't see it. I don't like how c++ separates comments to header file, so hard to find. I don't think anyone reads header files except compilers :) okay thanks. https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:71: OnComplete On 2014/10/31 21:43:16, mef wrote: > On 2014/10/31 21:01:51, xunjieli wrote: > > Since onError is not a part of this enum, does it make sense to rename > > LastCalled to sth like FailureStep/FailureStage? > > Hmm, it is also used in asserts below to verify correct order of callbacks. I see. Another nit, Enum constants should be uppercase (https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s5.2.4-cons...). eg. public enum LastCalled { NONE, ON_REDIRECT, ON_RESPONSE_STARTED, ... } Same goes to "FailtureType" https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:157: ResponseInfo info, On 2014/10/31 21:43:16, mef wrote: > On 2014/10/31 21:01:51, xunjieli wrote: > > nit: +8 indent. > > Done. I don't like it though... I guess you could move "ResponseInfo info" to the first line. I agree this +8 indent for arguments guideline in java is not very intuitive :( But I guess at least we are consistent.
https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:176: bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest* request) const { On 2014/11/03 14:26:05, xunjieli wrote: > On 2014/10/31 21:43:15, mef wrote: > > On 2014/10/31 21:01:51, xunjieli wrote: > > > nit: I often find "Maybe*" methods hard to reason about. Perhaps add a > comment > > > to this method? Sth along the line of "Returns whether |request| has an > error, > > > and propagates the error to the delegate if there is one." > > > > Acknowledged. There is a comment in the .h file, is it not clear enough? > > Sorry, I didn't see it. I don't like how c++ separates comments to header file, > so hard to find. I don't think anyone reads header files except compilers :) > okay thanks. The style is for function level comments to go with function declarations. The theory is that that's where consumers should look - people that use an API should never have to open up the source files where it's actually implemented in order to use it.
https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/770001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:71: OnComplete On 2014/11/03 14:26:05, xunjieli wrote: > On 2014/10/31 21:43:16, mef wrote: > > On 2014/10/31 21:01:51, xunjieli wrote: > > > Since onError is not a part of this enum, does it make sense to rename > > > LastCalled to sth like FailureStep/FailureStage? > > > > Hmm, it is also used in asserts below to verify correct order of callbacks. > > I see. Another nit, Enum constants should be uppercase > (https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s5.2.4-cons...). > eg. > public enum LastCalled { > NONE, > ON_REDIRECT, > ON_RESPONSE_STARTED, > ... > } > Same goes to "FailtureType" Great point, done.
https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:36: CronetURLRequestAdapter::~CronetURLRequestAdapter() { DCHECK(IsOnNetworkThread()); https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:40: const std::string& value) { DCHECK(!IsOnNetworkThread());? https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:81: // Receive more data. Method level comments should be in headers. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:95: base::Unretained(this))); Get rid of DestroyOnNetworkThread and use context_->GetNetworkTaskRunner()->DeleteSoon instead? https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:155: // Reads all available data or starts an asynchronous read. Method level comments should only go in the headers. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:161: read_buffer_.get(), read_buffer_->size(), &bytes_read)) { Don't use the return value of URLRequest (Which has weird, undocumented behavior), just use the value url_request_->status() in all cases. I suggest just duplicating the ResourceLoader's logic in ResumeReading/StartReading and OnReadCompleted. https://code.google.com/p/chromium/codesearch#chromium/src/content/browser/lo... https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI CronetUrlRequest object to the Chromium URLRequest. Should mention threading model. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:36: // The delegate which is called when the request_adapter finishes. request_adapter -> CronetURLRequestAdapter or request adapter. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:44: virtual void OnError(int net_error) = 0; Should document these - when called, where called, what the embedder should do in response. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:78: const GURL& url() const { return initial_url_; } Not used https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:84: unsigned char* Data() const; Not used https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:230: destroyRequestAdapter(); BUG: Calling cancel on one thread while another thread is in a call to onDataReceived. We may delete the IOBuffer while the embedder is still reading from it. Unfortunately, our embedders seem to want that situation to Just Work(tm). https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:29: * @param executor Executor on which all callbacks will be called. Worth mentioning that Executor must not just run tasks on the thread its Run method is called on? We could actually mostly support that...except for shutdown(). https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:41: * @return a human-readable name of the context. name of -> version string for https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:43: public abstract String getName(); I think getVersionString is much clearer. "Name" generally implies uniqueness of some sort, but two UrlRequestContexts will share the same name.
Think we're getting to the bottom of the barrel now. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:43: // layer. Always called on Network Thread. nit: on -> on the https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:47: JniCronetURLRequestAdapterDelegate(JNIEnv* jenv, jobject jowner) { I don't believe this should actually be j prefixed - the API doesn't actually know if they directly come from Java. At least I believe that's the standard we discussed. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:52: JNIEnv* jenv = base::android::AttachCurrentThread(); env is the name pretty much always used for JNIEnv, except in NCN util, which should probably be changed to be consistent. Should search your code and fix all instances, rather than me pointing out all occurences. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:63: http_status_code); Fix indent https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:89: protected: Since nothing subclasses this class, this method should be public or private. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:94: base::android::ScopedJavaGlobalRef<jobject> owner_; This isn't quite accurately named (And again, I think our round-robin ownership is kinda weird here, and we get pretty much nothing from separating the Adapter and the delegate). Should have a comment that this actually owns the adapter. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:106: static jlong CreateRequestAdapter(JNIEnv* jenv, These, too, always use env. Looking over existing code, I find the j prefix to calls from Java pretty uncommon, but as long as we're consistent in cronet, I'm fine with them. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:138: if (!jurl_request_adapter) This can't happen. Fine to DCHECK on it. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:144: DCHECK(!request_adapter->IsOnNetworkThread()); DCHECKs on input state should generally go first. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:158: return JNI_FALSE; This can't happen. Fine to DCHECK on it. This goes for all the calls in this file, I believe - as long as we have the mutex when we call into C++, the adapter can not be NULL. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:162: DCHECK(!request_adapter->IsOnNetworkThread()); DCHECKs should go first, when they can. Goes for rest of file, too. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:32: read_buffer_(new net::IOBufferWithSize(kReadBufferSize)) { Suggest only initializing this before the first read, to reduce memory usage a little. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:33: Remove blank line. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:22: */ Thread safety model should be documented. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:32: private final List<String> mUrlChain = new ArrayList<String>(); Should say just what URLs this has in it (The URL currently being requested, and all URLs previously requested. New URLs are only added after it is decided a redirect will be followed) https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:37: private String mMethod; mInitialMethod? https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:40: private OnDataReceivedRunnable mOnDataReceivedTask; Suggest assing some whitespace here, or sorting these into groups (Those set by the embedder together, and before those having to do with the received response, etc). https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:54: public void run() { Blank line before function definition. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:150: } This can't happen, can it? Should we even check for it? https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:371: if (mUrlRequestAdapter == 0) { I wonder about the overhead of just calling isCancelled here instead - we do have to grab the mutex again (Which works, in Java), but I think it's a lot clearer than using isCanceled for the first check, and mUrlRequestAdapter == 0 for the second. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:375: // thread as request is waiting to follow redirect. as request -> as the request https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:458: destroyRequestAdapter(); Worth mentioning why this has to be done first. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:20: public static final int REQUEST_PRIORITY_HIGHEST = 4; Doesn't cronet_url_request.h generate a CronetUrlRequestPriority.java file (Or something like that) with all of these in it? https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.cc (right): https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:35: }; COMPILE_ASSERT(arraysize(kFailurePhase) == MAX_FAILURE_PHASE, SomeRandomText_using_some_random_style);? (And add MAX_FAILURE_PHASE, and whatever header COMPILE_ASSERT comes frome) https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:228: std::string value; nit: phase_[net_]error_string, maybe? https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:251: << phase_key; I don't think we need all this logging.
https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:106: static jlong CreateRequestAdapter(JNIEnv* jenv, On 2014/11/03 20:21:16, mmenke wrote: > These, too, always use env. Looking over existing code, I find the j prefix to > calls from Java pretty uncommon, but as long as we're consistent in cronet, I'm > fine with them. I still feel that using j prefix will potentially solve a lot of confusion down the road. I am not very clear on whether to use "env" or "jenv", but IMO we should use j prefix for all the rest.
850 comments down, 150 to go! https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:36: CronetURLRequestAdapter::~CronetURLRequestAdapter() { On 2014/11/03 17:13:16, mmenke wrote: > DCHECK(IsOnNetworkThread()); Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:40: const std::string& value) { On 2014/11/03 17:13:16, mmenke wrote: > DCHECK(!IsOnNetworkThread());? Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:81: // Receive more data. On 2014/11/03 17:13:16, mmenke wrote: > Method level comments should be in headers. Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:95: base::Unretained(this))); On 2014/11/03 17:13:16, mmenke wrote: > Get rid of DestroyOnNetworkThread and use > context_->GetNetworkTaskRunner()->DeleteSoon instead? Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:155: // Reads all available data or starts an asynchronous read. On 2014/11/03 17:13:16, mmenke wrote: > Method level comments should only go in the headers. Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:161: read_buffer_.get(), read_buffer_->size(), &bytes_read)) { On 2014/11/03 17:13:16, mmenke wrote: > Don't use the return value of URLRequest (Which has weird, undocumented > behavior), just use the value url_request_->status() in all cases. > > I suggest just duplicating the ResourceLoader's logic in > ResumeReading/StartReading and OnReadCompleted. > https://code.google.com/p/chromium/codesearch#chromium/src/content/browser/lo... Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:33: // An adapter from the JNI CronetUrlRequest object to the Chromium URLRequest. On 2014/11/03 17:13:16, mmenke wrote: > Should mention threading model. Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:36: // The delegate which is called when the request_adapter finishes. On 2014/11/03 17:13:16, mmenke wrote: > request_adapter -> CronetURLRequestAdapter or request adapter. Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:44: virtual void OnError(int net_error) = 0; On 2014/11/03 17:13:16, mmenke wrote: > Should document these - when called, where called, what the embedder should do > in response. Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:78: const GURL& url() const { return initial_url_; } On 2014/11/03 17:13:16, mmenke wrote: > Not used Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:84: unsigned char* Data() const; On 2014/11/03 17:13:16, mmenke wrote: > Not used Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:230: destroyRequestAdapter(); On 2014/11/03 17:13:16, mmenke wrote: > BUG: Calling cancel on one thread while another thread is in a call to > onDataReceived. We may delete the IOBuffer while the embedder is still reading > from it. Unfortunately, our embedders seem to want that situation to Just > Work(tm). Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:29: * @param executor Executor on which all callbacks will be called. On 2014/11/03 17:13:16, mmenke wrote: > Worth mentioning that Executor must not just run tasks on the thread its Run > method is called on? We could actually mostly support that...except for > shutdown(). Could you elaborate? What's wrong with shutdown? https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:41: * @return a human-readable name of the context. On 2014/11/03 17:13:16, mmenke wrote: > name of -> version string for Done. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:43: public abstract String getName(); On 2014/11/03 17:13:16, mmenke wrote: > I think getVersionString is much clearer. "Name" generally implies uniqueness > of some sort, but two UrlRequestContexts will share the same name. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:43: // layer. Always called on Network Thread. On 2014/11/03 20:21:16, mmenke wrote: > nit: on -> on the Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:47: JniCronetURLRequestAdapterDelegate(JNIEnv* jenv, jobject jowner) { On 2014/11/03 20:21:16, mmenke wrote: > I don't believe this should actually be j prefixed - the API doesn't actually > know if they directly come from Java. At least I believe that's the standard we > discussed. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:52: JNIEnv* jenv = base::android::AttachCurrentThread(); On 2014/11/03 20:21:16, mmenke wrote: > env is the name pretty much always used for JNIEnv, except in NCN util, which > should probably be changed to be consistent. Should search your code and fix > all instances, rather than me pointing out all occurences. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:63: http_status_code); On 2014/11/03 20:21:16, mmenke wrote: > Fix indent Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:89: protected: On 2014/11/03 20:21:16, mmenke wrote: > Since nothing subclasses this class, this method should be public or private. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:94: base::android::ScopedJavaGlobalRef<jobject> owner_; On 2014/11/03 20:21:16, mmenke wrote: > This isn't quite accurately named (And again, I think our round-robin ownership > is kinda weird here, and we get pretty much nothing from separating the Adapter > and the delegate). Should have a comment that this actually owns the adapter. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:106: static jlong CreateRequestAdapter(JNIEnv* jenv, On 2014/11/03 20:27:49, xunjieli wrote: > On 2014/11/03 20:21:16, mmenke wrote: > > These, too, always use env. Looking over existing code, I find the j prefix > to > > calls from Java pretty uncommon, but as long as we're consistent in cronet, > I'm > > fine with them. > > I still feel that using j prefix will potentially solve a lot of confusion down > the road. I am not very clear on whether to use "env" or "jenv", but IMO we > should use j prefix for all the rest. I don't have strong preference, but I guess 'coming directly from java' is a good rule for 'j' prefix. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:138: if (!jurl_request_adapter) On 2014/11/03 20:21:16, mmenke wrote: > This can't happen. Fine to DCHECK on it. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:144: DCHECK(!request_adapter->IsOnNetworkThread()); On 2014/11/03 20:21:16, mmenke wrote: > DCHECKs on input state should generally go first. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:158: return JNI_FALSE; On 2014/11/03 20:21:16, mmenke wrote: > This can't happen. Fine to DCHECK on it. This goes for all the calls in this > file, I believe - as long as we have the mutex when we call into C++, the > adapter can not be NULL. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:162: DCHECK(!request_adapter->IsOnNetworkThread()); On 2014/11/03 20:21:16, mmenke wrote: > DCHECKs should go first, when they can. Goes for rest of file, too. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:32: read_buffer_(new net::IOBufferWithSize(kReadBufferSize)) { On 2014/11/03 20:21:16, mmenke wrote: > Suggest only initializing this before the first read, to reduce memory usage a > little. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:33: On 2014/11/03 20:21:16, mmenke wrote: > Remove blank line. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:22: */ On 2014/11/03 20:21:17, mmenke wrote: > Thread safety model should be documented. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:32: private final List<String> mUrlChain = new ArrayList<String>(); On 2014/11/03 20:21:17, mmenke wrote: > Should say just what URLs this has in it (The URL currently being requested, and > all URLs previously requested. New URLs are only added after it is decided a > redirect will be followed) Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:37: private String mMethod; On 2014/11/03 20:21:16, mmenke wrote: > mInitialMethod? Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:40: private OnDataReceivedRunnable mOnDataReceivedTask; On 2014/11/03 20:21:17, mmenke wrote: > Suggest assing some whitespace here, or sorting these into groups (Those set by > the embedder together, and before those having to do with the received response, > etc). Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:54: public void run() { On 2014/11/03 20:21:17, mmenke wrote: > Blank line before function definition. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:150: } On 2014/11/03 20:21:17, mmenke wrote: > This can't happen, can it? Should we even check for it? Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:371: if (mUrlRequestAdapter == 0) { On 2014/11/03 20:21:16, mmenke wrote: > I wonder about the overhead of just calling isCancelled here instead - we do > have to grab the mutex again (Which works, in Java), but I think it's a lot > clearer than using isCanceled for the first check, and mUrlRequestAdapter == 0 > for the second. Hmm, isCanceled is not the same as mUrlRequestAdapter == 0. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:375: // thread as request is waiting to follow redirect. On 2014/11/03 20:21:17, mmenke wrote: > as request -> as the request Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:458: destroyRequestAdapter(); On 2014/11/03 20:21:17, mmenke wrote: > Worth mentioning why this has to be done first. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:20: public static final int REQUEST_PRIORITY_HIGHEST = 4; On 2014/11/03 20:21:17, mmenke wrote: > Doesn't cronet_url_request.h generate a CronetUrlRequestPriority.java file (Or > something like that) with all of these in it? I think those are internal between C++ and Java. This is interface between Cronet and embedder. https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... File net/test/url_request/url_request_mock_http_job.cc (right): https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:35: }; On 2014/11/03 20:21:17, mmenke wrote: > COMPILE_ASSERT(arraysize(kFailurePhase) == MAX_FAILURE_PHASE, > SomeRandomText_using_some_random_style);? (And add MAX_FAILURE_PHASE, and > whatever header COMPILE_ASSERT comes frome) Done. https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:228: std::string value; On 2014/11/03 20:21:17, mmenke wrote: > nit: phase_[net_]error_string, maybe? Done. https://codereview.chromium.org/586143002/diff/810001/net/test/url_request/ur... net/test/url_request/url_request_mock_http_job.cc:251: << phase_key; On 2014/11/03 20:21:17, mmenke wrote: > I don't think we need all this logging. Done.
Quick responses. https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:29: * @param executor Executor on which all callbacks will be called. On 2014/11/03 21:23:37, mef wrote: > On 2014/11/03 17:13:16, mmenke wrote: > > Worth mentioning that Executor must not just run tasks on the thread its Run > > method is called on? We could actually mostly support that...except for > > shutdown(). > > Could you elaborate? What's wrong with shutdown? It can't be called on the network thread. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:371: if (mUrlRequestAdapter == 0) { On 2014/11/03 21:23:38, mef wrote: > On 2014/11/03 20:21:16, mmenke wrote: > > I wonder about the overhead of just calling isCancelled here instead - we do > > have to grab the mutex again (Which works, in Java), but I think it's a lot > > clearer than using isCanceled for the first check, and mUrlRequestAdapter == 0 > > for the second. > Hmm, isCanceled is not the same as mUrlRequestAdapter == 0. Here, it is. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:20: public static final int REQUEST_PRIORITY_HIGHEST = 4; On 2014/11/03 21:23:38, mef wrote: > On 2014/11/03 20:21:17, mmenke wrote: > > Doesn't cronet_url_request.h generate a CronetUrlRequestPriority.java file (Or > > something like that) with all of these in it? > > I think those are internal between C++ and Java. This is interface between > Cronet and embedder. I really don't think we want or need 4 versions of this enum.
Getting there! https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/790001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:29: * @param executor Executor on which all callbacks will be called. On 2014/11/03 21:42:06, mmenke wrote: > On 2014/11/03 21:23:37, mef wrote: > > On 2014/11/03 17:13:16, mmenke wrote: > > > Worth mentioning that Executor must not just run tasks on the thread its Run > > > method is called on? We could actually mostly support that...except for > > > shutdown(). > > > > Could you elaborate? What's wrong with shutdown? > > It can't be called on the network thread. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:371: if (mUrlRequestAdapter == 0) { On 2014/11/03 21:42:06, mmenke wrote: > On 2014/11/03 21:23:38, mef wrote: > > On 2014/11/03 20:21:16, mmenke wrote: > > > I wonder about the overhead of just calling isCancelled here instead - we do > > > have to grab the mutex again (Which works, in Java), but I think it's a lot > > > clearer than using isCanceled for the first check, and mUrlRequestAdapter == > 0 > > > for the second. > > Hmm, isCanceled is not the same as mUrlRequestAdapter == 0. > > Here, it is. Done. https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (right): https://codereview.chromium.org/586143002/diff/810001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:20: public static final int REQUEST_PRIORITY_HIGHEST = 4; On 2014/11/03 21:42:06, mmenke wrote: > On 2014/11/03 21:23:38, mef wrote: > > On 2014/11/03 20:21:17, mmenke wrote: > > > Doesn't cronet_url_request.h generate a CronetUrlRequestPriority.java file > (Or > > > something like that) with all of these in it? > > > > I think those are internal between C++ and Java. This is interface between > > Cronet and embedder. > > I really don't think we want or need 4 versions of this enum. Done.
More comments. Was thinking we wouldn't make it to 1000, but now I'm thinking we will. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:21: Maybe have a file-level comment along the lines of "This file contains all the plumbing to handle the bidirectional communication between the Java CronetURLRequest and C++ CronetURLRequestAdapter." https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:26: // layer. Always called on the Network Thread. Maybe "Created on a Java thread, but always called and destroyed on the Network thread?" https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:33: // CronetURLRequestAdapter::CronetURLRequestAdapterDelegate implementation: https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:79: base::android::ScopedJavaGlobalRef<jobject> owner_; include base/android/scoped_java_ref.h https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:160: request_adapter->Start(); optional: Think it would be cleaner to post tasks here, instead of calling into the adapter? Advantages: * Adapter would live completely on the network thread after construction, with the exception of grabbing its NetworkThread field, and this file becomes solely responsible for thread safety, as opposed to splitting the responsibility for that between the two classes. * We'd get rid of all those methods that just post a task to run another method. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:215: jenv, jurl_request, jheaders_map, name.Release(), value.Release()); I think this is a leak: When we call into Java, I don't think it takes ownership of the reference we pass into it, does it? See, for example, JniCronetURLRequestAdapterDelegate::OnBytesRead above. On the other hand, when we return a value to Java in these JNI methods, it *does* take ownership. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:223: jenv, jurl_request, jheaders_map, nullptr, status_line.Release()); Again, Release() -> obj()... Actually, I think we should just remove this code. If we want to mimic HttpURLConnection, should add this to the wrapper - as-is, seems like a bit of a hack, which I don't think we want to support for the async API. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:27: * any thread it is protected by mUrlRequestAdapterLock. I think this comment can be cleaned up. I can provide suggestions when I have time, if you want. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:31: /** Native adapter object, owned by UrlRequest. */ Should this use the "/**"? I assume the others don't because Javadoc uses it. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:44: /* Suggest a blank line before each of these multi-line comments, for legibility. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:87: mInOnDataReceived = true; Should explicitly mention why this is needed. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:97: if (isCanceled()) { Can just merge these and get rid of mDestroyRequestAdapterAfterOnDataReceived: if (isCanceled()) { destroyRequestAdapter(); return; } https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:230: if (mUrlRequestAdapter != 0) { Should check mStarted instead (It prevents restarting after cancellation or completion). Or better, just call checkNotStarted(). https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:240: mUrlRequestAdapter = 0; Replace these two lines with destroyRequestAdapter()? And same below. Alternatively, could do a try/catch, and destroy in the catch clause (And re-throw the exception, though you'll need to make sure you're only catching silently an exception type that doesn't need an explicit throws declaration). https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:324: private NativeResponseInfo prepareResponseInfo(int httpStatusCode) { Should either rename network thread methods to make it clear where they're run, or comment about it. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:336: nativeGetNegotiatedProtocol(urlRequestAdapter)); Should mention why all these calls into the adapter are safe, even if mUrlRequestAdapter may have been 0ed out. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:346: } Should we check if we're cancelled, too? Seems like being cancelled before start could cause Bad Things(tm) https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:361: private void appendHeaderToMap(HeadersMap headersMap, static...Actually, I suggest just inlining this, think it's clearer that way, rather than having it a couple hundred lines away from the one method that invokes it. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:371: * and exception could be retrieved from request using getException(). There is no GetException method. We actually pass in the exception to the listener's onFailed method. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:371: * and exception could be retrieved from request using getException(). "Only called on the Executor". https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:373: private void onCalledByNativeException(Exception e) { Both the name and description aren't terribly accurate - these are exceptions thrown by the listener when called by Runnables that are posted to executors in CalledByNative methods. Maybe onListenerException? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:373: private void onCalledByNativeException(Exception e) { If the request has already been cancelled, we should probably do nothing - should consistently try not to call into mListener after cancllation, I think. Could even use a synchronized block to prevent double cancellation, though not sure if that really gets us much. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:483: private void onComplete() { onSucceeded? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:503: destroyRequestAdapter(); Hrm...Does it make sense to grab the lock, check is cancelled, and then destroy the adapter? Feels a little safer, but I'm not sure it lets us may any strong guarantees. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:556: try { Is this try block even needed? This is a weird enough way to fail that if it is needed, we should have a test for it (The call stack is C++->Java->C++->Java->throws exception, and it's easy to imagine some sort of change that ends up on giving us an extra Java call into the listener in this case). https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:111: || mResponseStep == ResponseStep.ON_REDIRECT); Are all these exceptions on another thread going to make findbugs sad?
https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:39: ConvertUTF8ToJavaString(env, new_location.spec()).Release(), Again, think this is a leak - shouldn't be releasing, since Java doesn't take ownership, but rather grabs another reference, if needed.
just some style nits :) https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:27: : context_(context), a totally optional nit. Use "context_adapter" instead of just "context". https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:104: bool GetWasCached() const; nit: I find the method name not very intuitive. How about "wasResponseCached()" to better align with the implementation in ResponseInfo? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:108: jstring fileName) { nit: fileName -> jfile_name. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java:92: long maxSize) { nit: indent. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java:128: int port, nit: indent. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:25: ResponseInfo info, nit: +8 indent. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:48: ResponseInfo info, nit: +8 indent. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:70: ResponseInfo info, nit: +8 indent. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:19: nit: extra blank line.
Thanks, quick comments. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:39: ConvertUTF8ToJavaString(env, new_location.spec()).Release(), On 2014/11/06 16:11:01, mmenke wrote: > Again, think this is a leak - shouldn't be releasing, since Java doesn't take > ownership, but rather grabs another reference, if needed. Good point, I think you are right, I'll change them. This seems to be a fairly common pattern in existing code, but that doesn't make it correct. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:160: request_adapter->Start(); On 2014/11/06 16:08:26, mmenke wrote: > optional: Think it would be cleaner to post tasks here, instead of calling into > the adapter? > > Advantages: > * Adapter would live completely on the network thread after construction, with > the exception of grabbing its NetworkThread field, and this file becomes solely > responsible for thread safety, as opposed to splitting the responsibility for > that between the two classes. > * We'd get rid of all those methods that just post a task to run another method. Sounds reasonable, I'll try that. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:27: * any thread it is protected by mUrlRequestAdapterLock. On 2014/11/06 16:08:27, mmenke wrote: > I think this comment can be cleaned up. I can provide suggestions when I have > time, if you want. I'll appreciate that. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:556: try { On 2014/11/06 16:08:27, mmenke wrote: > Is this try block even needed? This is a weird enough way to fail that if it is > needed, we should have a test for it (The call stack is > C++->Java->C++->Java->throws exception, and it's easy to imagine some sort of > change that ends up on giving us an extra Java call into the listener in this > case). Hmm, maybe not. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java:111: || mResponseStep == ResponseStep.ON_REDIRECT); On 2014/11/06 16:08:27, mmenke wrote: > Are all these exceptions on another thread going to make findbugs sad? Surprisingly not. I guess it doesn't go deep enough to figure this out.
If you respond to all outstanding comments, we'll be just shy of 1000. :) https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:233: std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol(); This is an unnecessary string copy. Can just inline it in the next line, or make it a const std::string&. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:167: // thread in case the URLRequest can provide data synchronously. I don't think this gets us anything - we always have to post a task to Java asynchronously, anyways. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:171: base::Unretained(this), This also isn't threadsafe - if we get a cancel message between posting this message and running it, we crash. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:8: #include <jni.h> Not needed - by design, this file has no dependencies on Java https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:26: class UploadDataStream; UploadDataStream is not used (Admittedly, we'll want to add it later) https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:97: // Gets all response headers, as a HttpResponseHeaders object. Worth mentioning it will return NULL if the last attempted request received no headers? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:98: net::HttpResponseHeaders* GetResponseHeaders() const; const net::HttpResponseHeaders*? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:104: bool GetWasCached() const; Suggest grouping these three getBlah functions, and mention how they work ("When called during a OnRedirect or OnResponseStarted callback, they return the corresponding information for the corresponding response.") https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:107: // proxy handling. More accurate would be "Gets the total amount of body data received from network after SSL/SPDY/QUIC decoding and proxy handling. Basically the size of the body prior to decompression." https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:110: // net::URLRequest::Delegate overrides nit: +: https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:136: scoped_ptr<net::URLRequest> url_request_; nit: Suggest dividing these into groups - line break before initial_url_, and one after initial_request_headers. Think it makes them a little easier to visually parse. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:22: namespace { nit: Suggest moving this into the cronet namespace. Admittedly, only saves one "cronet::", but if we add more stuff, will probably be more useful. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:25: const base::android::ScopedJavaGlobalRef<jobject>& jowner) { Need to include the header for ScopedJavaGlobalRef https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:35: bool CronetUrlRequestContextRegisterJni(JNIEnv* jenv) { Per comments elsewhere, this is called env pretty universally elsewhere - and is rather different from jobjects/jstrings - those are references to java variables, while this is the current thread's Java environment. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:41: jobject jcaller, optional: Should we use something more meaningful than jcaller, here and in cronet_url_request? Like jurl_[cronet_]request_context / jurl_request? A bit more wordy, but a bit clearer than "caller". Same goes for jowner as well. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:55: base::JSONValueConverter<URLRequestContextConfig> converter; Should probably include the JSONValueConverter header, though admittedly, url_request_context_config.h does as well. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:81: if (jurl_request_context_adapter == 0) DCHECK(jurl_request_context_adapter);? For thread safety reasons, we have to prevent two destroys at once Java-side, so this should never happen. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:101: return base::android::ConvertUTF8ToJavaString(jenv, json).Release(); I don't think this should be a method on the context, since it doesn't gather data just for one context - think it makes sense in its own C++/Java file, with any other global methods we want to expose. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:34: nativeSetMinLogLevel(getLoggingLevel()); Does it really make sense to call this whenever we create a context, rather than during startup or something? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:118: @CalledByNative Why isn't @SuppressWarnings("unused") needed? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:29: * Sets the HTTP method verb to use for this request. All of these should mention they may not be called if the request has been started (And maybe cancelled? The latter case may not be worth mentioning) https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:47: * Starts the request, all callbacks go to listener. May only be called once. May not be called if cancel has been called on the request. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:52: * Can be called at any time. +"If the Executor passed to UrlRequest on construction runs tasks on a single thread, and cancel is called on that thread, no listener methods will be invoked after cancel is called. Otherwise, at most one listener method may be made after cancel has completed." https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:57: * nit: Remove blank line. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:49: * throw an exception. Cannot be called on network thread. nit: Maybe "Cannot be called on network thread - the thread Cronet calls into Executor on (Which is different from the thread the Executor invokes callbacks on). May block until all the Context's resources have been cleaned up." https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestException.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestException.java:14: /** Net Error code if exception is reported by native. */ nit: Error -> error
A couple more minor comments... Done reviewing for the day. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:151: for (size_t hint = 0; hint < config->quic_hints.size(); ++hint) { nit: Should be using a iterator (const_iterator, actually) https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:159: if (quic_hint.port <= std::numeric_limits<uint16>::min() || Why is the validation code different? Just using an old version of it? https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:51: ~CronetURLRequestContextAdapter(); This should be right under the constructor (Same for its definition in the other file) https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:101: listener.setFailure(FailureType.BLOCK, ResponseStep.ON_RESPONSE_STARTED); nit: Suggest splitting this line. https://codereview.chromium.org/586143002/diff/870001/components/cronet/url_r... File components/cronet/url_request_context_config.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/url_r... components/cronet/url_request_context_config.cc:79: &URLRequestContextConfig::quic_hints); Should try to match order here and in url_request_context_config_list.h and in UrlRequestContextConfig* - makes it easier to see what's missing.
Just 8 more! https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:21: On 2014/11/06 16:08:26, mmenke wrote: > Maybe have a file-level comment along the lines of "This file contains all the > plumbing to handle the bidirectional communication between the Java > CronetURLRequest and C++ CronetURLRequestAdapter." Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:26: // layer. Always called on the Network Thread. On 2014/11/06 16:08:26, mmenke wrote: > Maybe "Created on a Java thread, but always called and destroyed on the Network > thread?" Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:33: On 2014/11/06 16:08:26, mmenke wrote: > // CronetURLRequestAdapter::CronetURLRequestAdapterDelegate implementation: Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:39: ConvertUTF8ToJavaString(env, new_location.spec()).Release(), On 2014/11/06 16:11:01, mmenke wrote: > Again, think this is a leak - shouldn't be releasing, since Java doesn't take > ownership, but rather grabs another reference, if needed. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:79: base::android::ScopedJavaGlobalRef<jobject> owner_; On 2014/11/06 16:08:26, mmenke wrote: > include base/android/scoped_java_ref.h Done, it was already there. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:160: request_adapter->Start(); On 2014/11/06 17:07:46, mef wrote: > On 2014/11/06 16:08:26, mmenke wrote: > > optional: Think it would be cleaner to post tasks here, instead of calling > into > > the adapter? > > > > Advantages: > > * Adapter would live completely on the network thread after construction, with > > the exception of grabbing its NetworkThread field, and this file becomes > solely > > responsible for thread safety, as opposed to splitting the responsibility for > > that between the two classes. > > * We'd get rid of all those methods that just post a task to run another > method. > > Sounds reasonable, I'll try that. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:215: jenv, jurl_request, jheaders_map, name.Release(), value.Release()); On 2014/11/06 16:08:26, mmenke wrote: > I think this is a leak: When we call into Java, I don't think it takes > ownership of the reference we pass into it, does it? See, for example, > JniCronetURLRequestAdapterDelegate::OnBytesRead above. > > On the other hand, when we return a value to Java in these JNI methods, it > *does* take ownership. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:223: jenv, jurl_request, jheaders_map, nullptr, status_line.Release()); On 2014/11/06 16:08:26, mmenke wrote: > Again, Release() -> obj()... Actually, I think we should just remove this code. > If we want to mimic HttpURLConnection, should add this to the wrapper - as-is, > seems like a bit of a hack, which I don't think we want to support for the async > API. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:233: std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol(); On 2014/11/06 17:31:28, mmenke wrote: > This is an unnecessary string copy. Can just inline it in the next line, or > make it a const std::string&. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:27: : context_(context), On 2014/11/06 17:02:36, xunjieli wrote: > a totally optional nit. Use "context_adapter" instead of just "context". Acknowledged. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:167: // thread in case the URLRequest can provide data synchronously. On 2014/11/06 17:31:28, mmenke wrote: > I don't think this gets us anything - we always have to post a task to Java > asynchronously, anyways. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:171: base::Unretained(this), On 2014/11/06 17:31:28, mmenke wrote: > This also isn't threadsafe - if we get a cancel message between posting this > message and running it, we crash. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:8: #include <jni.h> On 2014/11/06 17:31:28, mmenke wrote: > Not needed - by design, this file has no dependencies on Java Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:26: class UploadDataStream; On 2014/11/06 17:31:28, mmenke wrote: > UploadDataStream is not used (Admittedly, we'll want to add it later) Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:97: // Gets all response headers, as a HttpResponseHeaders object. On 2014/11/06 17:31:28, mmenke wrote: > Worth mentioning it will return NULL if the last attempted request received no > headers? Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:98: net::HttpResponseHeaders* GetResponseHeaders() const; On 2014/11/06 17:31:28, mmenke wrote: > const net::HttpResponseHeaders*? Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:104: bool GetWasCached() const; On 2014/11/06 17:02:36, xunjieli wrote: > nit: I find the method name not very intuitive. How about "wasResponseCached()" > to better align with the implementation in ResponseInfo? Done. I'll keep 'GetWasCached' name for consistency with others. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:107: // proxy handling. On 2014/11/06 17:31:28, mmenke wrote: > More accurate would be "Gets the total amount of body data received from network > after SSL/SPDY/QUIC decoding and proxy handling. Basically the size of the body > prior to decompression." Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:110: // net::URLRequest::Delegate overrides On 2014/11/06 17:31:28, mmenke wrote: > nit: +: Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:136: scoped_ptr<net::URLRequest> url_request_; On 2014/11/06 17:31:28, mmenke wrote: > nit: Suggest dividing these into groups - line break before initial_url_, and > one after initial_request_headers. Think it makes them a little easier to > visually parse. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_context.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:22: namespace { On 2014/11/06 17:31:29, mmenke wrote: > nit: Suggest moving this into the cronet namespace. Admittedly, only saves one > "cronet::", but if we add more stuff, will probably be more useful. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:25: const base::android::ScopedJavaGlobalRef<jobject>& jowner) { On 2014/11/06 17:31:28, mmenke wrote: > Need to include the header for ScopedJavaGlobalRef Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:35: bool CronetUrlRequestContextRegisterJni(JNIEnv* jenv) { On 2014/11/06 17:31:28, mmenke wrote: > Per comments elsewhere, this is called env pretty universally elsewhere - and is > rather different from jobjects/jstrings - those are references to java > variables, while this is the current thread's Java environment. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:41: jobject jcaller, On 2014/11/06 17:31:28, mmenke wrote: > optional: Should we use something more meaningful than jcaller, here and in > cronet_url_request? Like jurl_[cronet_]request_context / jurl_request? A bit > more wordy, but a bit clearer than "caller". Same goes for jowner as well. Acknowledged. I think those are sufficiently generic boilerplate not to deserve unique names. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:55: base::JSONValueConverter<URLRequestContextConfig> converter; On 2014/11/06 17:31:28, mmenke wrote: > Should probably include the JSONValueConverter header, though admittedly, > url_request_context_config.h does as well. Done. Moved conversion from JSON into URLRequestContextConfig::LoadFromJSON(). https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:81: if (jurl_request_context_adapter == 0) On 2014/11/06 17:31:28, mmenke wrote: > DCHECK(jurl_request_context_adapter);? For thread safety reasons, we have to > prevent two destroys at once Java-side, so this should never happen. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:101: return base::android::ConvertUTF8ToJavaString(jenv, json).Release(); On 2014/11/06 17:31:28, mmenke wrote: > I don't think this should be a method on the context, since it doesn't gather > data just for one context - think it makes sense in its own C++/Java file, with > any other global methods we want to expose. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context.cc:108: jstring fileName) { On 2014/11/06 17:02:36, xunjieli wrote: > nit: fileName -> jfile_name. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:151: for (size_t hint = 0; hint < config->quic_hints.size(); ++hint) { On 2014/11/06 20:50:14, mmenke wrote: > nit: Should be using a iterator (const_iterator, actually) Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:159: if (quic_hint.port <= std::numeric_limits<uint16>::min() || On 2014/11/06 20:50:15, mmenke wrote: > Why is the validation code different? Just using an old version of it? Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:51: ~CronetURLRequestContextAdapter(); On 2014/11/06 20:50:15, mmenke wrote: > This should be right under the constructor (Same for its definition in the other > file) Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:31: /** Native adapter object, owned by UrlRequest. */ On 2014/11/06 16:08:27, mmenke wrote: > Should this use the "/**"? I assume the others don't because Javadoc uses it. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:44: /* On 2014/11/06 16:08:27, mmenke wrote: > Suggest a blank line before each of these multi-line comments, for legibility. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:87: mInOnDataReceived = true; On 2014/11/06 16:08:27, mmenke wrote: > Should explicitly mention why this is needed. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:97: if (isCanceled()) { On 2014/11/06 16:08:27, mmenke wrote: > Can just merge these and get rid of mDestroyRequestAdapterAfterOnDataReceived: > > if (isCanceled()) { > destroyRequestAdapter(); > return; > } Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:230: if (mUrlRequestAdapter != 0) { On 2014/11/06 16:08:27, mmenke wrote: > Should check mStarted instead (It prevents restarting after cancellation or > completion). Or better, just call checkNotStarted(). Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:240: mUrlRequestAdapter = 0; On 2014/11/06 16:08:27, mmenke wrote: > Replace these two lines with destroyRequestAdapter()? And same below. > > Alternatively, could do a try/catch, and destroy in the catch clause (And > re-throw the exception, though you'll need to make sure you're only catching > silently an exception type that doesn't need an explicit throws declaration). Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:324: private NativeResponseInfo prepareResponseInfo(int httpStatusCode) { On 2014/11/06 16:08:27, mmenke wrote: > Should either rename network thread methods to make it clear where they're run, > or comment about it. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:336: nativeGetNegotiatedProtocol(urlRequestAdapter)); On 2014/11/06 16:08:27, mmenke wrote: > Should mention why all these calls into the adapter are safe, even if > mUrlRequestAdapter may have been 0ed out. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:346: } On 2014/11/06 16:08:26, mmenke wrote: > Should we check if we're cancelled, too? Seems like being cancelled before > start could cause Bad Things(tm) Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:361: private void appendHeaderToMap(HeadersMap headersMap, On 2014/11/06 16:08:27, mmenke wrote: > static...Actually, I suggest just inlining this, think it's clearer that way, > rather than having it a couple hundred lines away from the one method that > invokes it. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:371: * and exception could be retrieved from request using getException(). On 2014/11/06 16:08:27, mmenke wrote: > There is no GetException method. We actually pass in the exception to the > listener's onFailed method. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:373: private void onCalledByNativeException(Exception e) { On 2014/11/06 16:08:27, mmenke wrote: > Both the name and description aren't terribly accurate - these are exceptions > thrown by the listener when called by Runnables that are posted to executors in > CalledByNative methods. > > Maybe onListenerException? Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:483: private void onComplete() { On 2014/11/06 16:08:27, mmenke wrote: > onSucceeded? Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:503: destroyRequestAdapter(); On 2014/11/06 16:08:27, mmenke wrote: > Hrm...Does it make sense to grab the lock, check is cancelled, and then destroy > the adapter? Feels a little safer, but I'm not sure it lets us may any strong > guarantees. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java:556: try { On 2014/11/06 17:07:47, mef wrote: > On 2014/11/06 16:08:27, mmenke wrote: > > Is this try block even needed? This is a weird enough way to fail that if it > is > > needed, we should have a test for it (The call stack is > > C++->Java->C++->Java->throws exception, and it's easy to imagine some sort of > > change that ends up on giving us an extra Java call into the listener in this > > case). > > Hmm, maybe not. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:34: nativeSetMinLogLevel(getLoggingLevel()); On 2014/11/06 17:31:29, mmenke wrote: > Does it really make sense to call this whenever we create a context, rather than > during startup or something? Good question. Theoretically log level could change over time. :) Practically I think it is ok to do it during global initialization, along side with porting Helen's changes for proxies, NCN, etc to the new interface. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java:118: @CalledByNative On 2014/11/06 17:31:29, mmenke wrote: > Why isn't @SuppressWarnings("unused") needed? Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:29: * Sets the HTTP method verb to use for this request. On 2014/11/06 17:31:29, mmenke wrote: > All of these should mention they may not be called if the request has been > started (And maybe cancelled? The latter case may not be worth mentioning) Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:47: * Starts the request, all callbacks go to listener. On 2014/11/06 17:31:29, mmenke wrote: > May only be called once. May not be called if cancel has been called on the > request. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:52: * Can be called at any time. On 2014/11/06 17:31:29, mmenke wrote: > +"If the Executor passed to UrlRequest on construction runs tasks on a single > thread, and cancel is called on that thread, no listener methods will be invoked > after cancel is called. Otherwise, at most one listener method may be made > after cancel has completed." Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequest.java:57: * On 2014/11/06 17:31:29, mmenke wrote: > nit: Remove blank line. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java:49: * throw an exception. Cannot be called on network thread. On 2014/11/06 17:31:29, mmenke wrote: > nit: Maybe "Cannot be called on network thread - the thread Cronet calls into > Executor on (Which is different from the thread the Executor invokes callbacks > on). May block until all the Context's resources have been cleaned up." Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java:92: long maxSize) { On 2014/11/06 17:02:36, xunjieli wrote: > nit: indent. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java:128: int port, On 2014/11/06 17:02:36, xunjieli wrote: > nit: indent. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestException.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestException.java:14: /** Net Error code if exception is reported by native. */ On 2014/11/06 17:31:29, mmenke wrote: > nit: Error -> error Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:25: ResponseInfo info, On 2014/11/06 17:02:36, xunjieli wrote: > nit: +8 indent. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:48: ResponseInfo info, On 2014/11/06 17:02:36, xunjieli wrote: > nit: +8 indent. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java:70: ResponseInfo info, On 2014/11/06 17:02:36, xunjieli wrote: > nit: +8 indent. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestContextTest.java:101: listener.setFailure(FailureType.BLOCK, ResponseStep.ON_RESPONSE_STARTED); On 2014/11/06 20:50:15, mmenke wrote: > nit: Suggest splitting this line. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... File components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/andro... components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/CronetUrlRequestTest.java:19: On 2014/11/06 17:02:36, xunjieli wrote: > nit: extra blank line. Done. https://codereview.chromium.org/586143002/diff/870001/components/cronet/url_r... File components/cronet/url_request_context_config.cc (right): https://codereview.chromium.org/586143002/diff/870001/components/cronet/url_r... components/cronet/url_request_context_config.cc:79: &URLRequestContextConfig::quic_hints); On 2014/11/06 20:50:15, mmenke wrote: > Should try to match order here and in url_request_context_config_list.h and in > UrlRequestContextConfig* - makes it easier to see what's missing. Done.
Think we shouldn't change the interface in this CL, but I've been thinking about Charles' suggestion about having the embedder allocate the read buffers - this gives the embedder more control over memory allocation and read size, which could be handy. We'd probably then want to switch to a completely pull-based API, which is closer to what net/ uses internally, rather than having a pause() method. I'd been a bit concerned about error handling and memory management / cleanup, which is why I'd been thinking about a push-based API, but looking at what we have, my concerns really seem to be non-issues (Or no worse than issues we have with a pull-based API). I think switching is worth considering (Note that the change from one to the other is pretty trivial - basically instead of calling followRedirect/read internally, the embedder would call them).
I thought that as net/ uses refcounted IOBuffer that could live beyond request, it can't directly take app-supplied buffer. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:59: base::android::ScopedJavaLocalRef<jobject> java_buffer( So, it seems that theoretically |bytes_read| could wary from call to call, can't it? In this case we either need to pass it back explicitly to the listener, or to recreate java_buffer every time that it changes. WDYT?
https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:59: base::android::ScopedJavaLocalRef<jobject> java_buffer( On 2014/11/06 23:16:53, mef wrote: > So, it seems that theoretically |bytes_read| could wary from call to call, can't > it? > In this case we either need to pass it back explicitly to the listener, or to > recreate java_buffer every time that it changes. WDYT? We'd create a Java byte buffer with a capacity of the entire length of |bytes_buffer| initially. On each read, we'd then set its position to be bytes_read, rather than setting its capacity.
I think this is good enough, for the moment, though suppose I am still finding real bugs. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:56: void OnBytesRead(unsigned char* bytes_buffer, |bytes_buffer| seems too easy to confuse with the Java byte buffer class (Which, admittedly, we wrap this in immediately...But that's an implementation detail the adapter probably shouldn't care about). My suggestion is just to call it buffer, or bytes, or data, or whatever. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:59: base::android::ScopedJavaLocalRef<jobject> java_buffer( On 2014/11/06 23:35:06, mmenke wrote: > On 2014/11/06 23:16:53, mef wrote: > > So, it seems that theoretically |bytes_read| could wary from call to call, > can't > > it? > > In this case we either need to pass it back explicitly to the listener, or to > > recreate java_buffer every time that it changes. WDYT? > > We'd create a Java byte buffer with a capacity of the entire length of > |bytes_buffer| initially. On each read, we'd then set its position to be > bytes_read, rather than setting its capacity. Could put it off until a future CL - if we switch to a pull-based API, we'll need something different, anyways. That having been said, fine if you want to make the switch on this CL, but I think we should change the interface if we do. Add a SetBuffer method, which takes in the buffer and the size, and then make this just take in a bytes_read - that makes it clearer from the interface that the buffer doesn't change, and don't need to worry about whether you should handle the buffer pointer changing from one call to another in here or not. Could either pass the buffer to Java in the new function, and keep the pointer cached there, or pass it in to Java on each read. Second option may be slightly preferable, just because the Java class is quite large already, and this is a pretty small class, so it makes for more readable code...not really a big issue, either way, though. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:182: base::Unretained(request_adapter))); I guess there's no standard templated delete task, and we can't use DeleteSoon here, since we don't have access to the task runner? https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:242: env, jurl_request, jheaders_map, nullptr, status_line.obj()); You said you're removed this, but didn't. Do you disagree with me about keeping this, or did you forget to remove it? https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:253: request_adapter->GetNegotiatedProtocol()).Release(); Fix formatting. Just moving env onto the second line of the statement would be fine. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:86: const { nit: const should go on the same line as the close parenthesis. This is generally formatted as: const net::HttpResponseHeaders* CronetURLRequestAdapter::GetResponseHeaders() const { https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:153: return true; Seems more logical that MaybeReportError return true if it reports an error, rather than if it doesn't report an error. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:37: // to network thread. Last two sentences are now incorrect. Maybe "All methods except those needed to set up a request must be called exclusively on the network thread." https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:51: // either destroy the request, or call ReadData. Maybe add "The request may only be destroyed after the embedder is done with |bytes_buffer (See rename suggestion)|, as deleting the request frees the buffer." https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:58: // the request. Instead of "embedder", should we use "consumer", or use passive voice? It's not the embedder that destroys the request on finish or error, but the cronet Java code. The adapter probably shouldn't even know what an embedder is. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:124: // Returns true if currently running on network thread. nit: Maybe "currently running" -> run / called / invoked. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:125: bool IsOnNetworkThread() const; Suggest moving these two methods up above the "Methods called only on network thread." comment, as these may be called on any thread. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:203: delete network_thread_; BUG: Need to stick network_thread_ in a local, as |this| may be destroyed before we dereference network_thread_ to delete it. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:41: // Releases all resources for the request context and deletes the object. Worth mentioning it blocks until the thread is destroyed? https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:47: GetNetworkTaskRunner() const; If this doesn't fit on one line, I think generally the next line generally isn't indented at all?
Achievement unlocked: 1k comments! https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:56: void OnBytesRead(unsigned char* bytes_buffer, On 2014/11/07 15:19:08, mmenke wrote: > |bytes_buffer| seems too easy to confuse with the Java byte buffer class (Which, > admittedly, we wrap this in immediately...But that's an implementation detail > the adapter probably shouldn't care about). > > My suggestion is just to call it buffer, or bytes, or data, or whatever. Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:59: base::android::ScopedJavaLocalRef<jobject> java_buffer( On 2014/11/07 15:19:08, mmenke wrote: > On 2014/11/06 23:35:06, mmenke wrote: > > On 2014/11/06 23:16:53, mef wrote: > > > So, it seems that theoretically |bytes_read| could wary from call to call, > > can't > > > it? > > > In this case we either need to pass it back explicitly to the listener, or > to > > > recreate java_buffer every time that it changes. WDYT? > > > > We'd create a Java byte buffer with a capacity of the entire length of > > |bytes_buffer| initially. On each read, we'd then set its position to be > > bytes_read, rather than setting its capacity. > > Could put it off until a future CL - if we switch to a pull-based API, we'll > need something different, anyways. > > That having been said, fine if you want to make the switch on this CL, but I > think we should change the interface if we do. Add a SetBuffer method, which > takes in the buffer and the size, and then make this just take in a bytes_read - > that makes it clearer from the interface that the buffer doesn't change, and > don't need to worry about whether you should handle the buffer pointer changing > from one call to another in here or not. > > Could either pass the buffer to Java in the new function, and keep the pointer > cached there, or pass it in to Java on each read. Second option may be slightly > preferable, just because the Java class is quite large already, and this is a > pretty small class, so it makes for more readable code...not really a big issue, > either way, though. Acknowledged. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:182: base::Unretained(request_adapter))); On 2014/11/07 15:19:08, mmenke wrote: > I guess there's no standard templated delete task, and we can't use DeleteSoon > here, since we don't have access to the task runner? Yeah, I had a choice between custom 'Destroy' explicitly posted on network thread or custom 'DestroySoon' implicitly posting DeleteSoon from arbitrary thread. This seemed a little cleaner. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:242: env, jurl_request, jheaders_map, nullptr, status_line.obj()); On 2014/11/07 15:19:08, mmenke wrote: > You said you're removed this, but didn't. Do you disagree with me about keeping > this, or did you forget to remove it? Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:253: request_adapter->GetNegotiatedProtocol()).Release(); On 2014/11/07 15:19:08, mmenke wrote: > Fix formatting. Just moving env onto the second line of the statement would be > fine. Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:86: const { On 2014/11/07 15:19:08, mmenke wrote: > nit: const should go on the same line as the close parenthesis. This is > generally formatted as: > > const net::HttpResponseHeaders* > CronetURLRequestAdapter::GetResponseHeaders() const { Done. It didn't look right, thanks for suggestion! https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:153: return true; On 2014/11/07 15:19:08, mmenke wrote: > Seems more logical that MaybeReportError return true if it reports an error, > rather than if it doesn't report an error. Arghh, it made more sense when it was called 'CheckStatus'. :) Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:37: // to network thread. On 2014/11/07 15:19:09, mmenke wrote: > Last two sentences are now incorrect. > > Maybe "All methods except those needed to set up a request must be called > exclusively on the network thread." Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:51: // either destroy the request, or call ReadData. On 2014/11/07 15:19:08, mmenke wrote: > Maybe add "The request may only be destroyed after the embedder is done with > |bytes_buffer (See rename suggestion)|, as deleting the request frees the > buffer." Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:58: // the request. On 2014/11/07 15:19:09, mmenke wrote: > Instead of "embedder", should we use "consumer", or use passive voice? It's not > the embedder that destroys the request on finish or error, but the cronet Java > code. The adapter probably shouldn't even know what an embedder is. Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:124: // Returns true if currently running on network thread. On 2014/11/07 15:19:09, mmenke wrote: > nit: Maybe "currently running" -> run / called / invoked. Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:125: bool IsOnNetworkThread() const; On 2014/11/07 15:19:08, mmenke wrote: > Suggest moving these two methods up above the "Methods called only on network > thread." comment, as these may be called on any thread. Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.cc (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.cc:203: delete network_thread_; On 2014/11/07 15:19:09, mmenke wrote: > BUG: Need to stick network_thread_ in a local, as |this| may be destroyed > before we dereference network_thread_ to delete it. Great catch! Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... File components/cronet/android/cronet_url_request_context_adapter.h (right): https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:41: // Releases all resources for the request context and deletes the object. On 2014/11/07 15:19:09, mmenke wrote: > Worth mentioning it blocks until the thread is destroyed? Done. https://codereview.chromium.org/586143002/diff/890001/components/cronet/andro... components/cronet/android/cronet_url_request_context_adapter.h:47: GetNetworkTaskRunner() const; On 2014/11/07 15:19:09, mmenke wrote: > If this doesn't fit on one line, I think generally the next line generally isn't > indented at all? Hmm, fits now. Not sure why was like that.
Think this has gone on enough. LGTM. Can deal with other issues as they come up.
https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:145: bool CronetURLRequestAdapter::IsOnNetworkThread() const { definition order must match declaration order. https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:52: // destroyed after the embedder is done with |bytes||, as deleting the nit: Remove extra "|"
lgtm-ed before. two more nits. hope to see this landed today! https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:23: // between the Java CronetURLRequest and C++ CronetURLRequestAdapter." nit: extra quote at the end of the sentence. https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:52: // destroyed after the embedder is done with |bytes||, as deleting the nit: exra pipe?
Yay! Thanks! https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... File components/cronet/android/cronet_url_request.cc (right): https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... components/cronet/android/cronet_url_request.cc:23: // between the Java CronetURLRequest and C++ CronetURLRequestAdapter." On 2014/11/07 16:28:40, xunjieli wrote: > nit: extra quote at the end of the sentence. Done. https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.cc (right): https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.cc:145: bool CronetURLRequestAdapter::IsOnNetworkThread() const { On 2014/11/07 16:28:07, mmenke wrote: > definition order must match declaration order. Done. https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... File components/cronet/android/cronet_url_request_adapter.h (right): https://codereview.chromium.org/586143002/diff/910001/components/cronet/andro... components/cronet/android/cronet_url_request_adapter.h:52: // destroyed after the embedder is done with |bytes||, as deleting the On 2014/11/07 16:28:07, mmenke wrote: > nit: Remove extra "|" Done.
The CQ bit was checked by mef@chromium.org
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/586143002/950001
Message was sent while issue was closed.
Committed patchset #46 (id:950001)
Message was sent while issue was closed.
Patchset 46 (id:??) landed as https://crrev.com/d190710e56c9399e0bc1e9a88b26093190974c4d Cr-Commit-Position: refs/heads/master@{#303252} |