1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.net.smoke;
6 
7 import static com.google.common.truth.Truth.assertThat;
8 
9 import android.os.ConditionVariable;
10 
11 import org.chromium.net.CronetException;
12 import org.chromium.net.UrlRequest;
13 import org.chromium.net.UrlResponseInfo;
14 
15 import java.nio.ByteBuffer;
16 import java.util.concurrent.Executor;
17 import java.util.concurrent.ExecutorService;
18 import java.util.concurrent.Executors;
19 
20 /** A simple boilerplate implementation of {@link UrlRequest.Callback} that is used by smoke tests. */
21 class SmokeTestRequestCallback extends UrlRequest.Callback {
22     private static final int READ_BUFFER_SIZE = 10000;
23 
24     // An executor that is used to execute {@link UrlRequest.Callback UrlRequest callbacks}.
25     private ExecutorService mExecutor = Executors.newSingleThreadExecutor();
26 
27     // Signals when the request is done either successfully or not.
28     private final ConditionVariable mDone = new ConditionVariable();
29 
30     // The state of the request.
31     public enum State {
32         NotSet,
33         Succeeded,
34         Failed,
35         Canceled
36     }
37 
38     // The current state of the request.
39     private State mState = State.NotSet;
40 
41     // Response info of the finished request.
42     private UrlResponseInfo mResponseInfo;
43 
44     // Holds an error if the request failed.
45     private CronetException mError;
46 
47     @Override
onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl)48     public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl)
49             throws Exception {
50         request.followRedirect();
51     }
52 
53     @Override
onResponseStarted(UrlRequest request, UrlResponseInfo info)54     public void onResponseStarted(UrlRequest request, UrlResponseInfo info) throws Exception {
55         request.read(ByteBuffer.allocateDirect(READ_BUFFER_SIZE));
56     }
57 
58     @Override
onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer)59     public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer)
60             throws Exception {
61         request.read(ByteBuffer.allocateDirect(READ_BUFFER_SIZE));
62     }
63 
64     @Override
onSucceeded(UrlRequest request, UrlResponseInfo info)65     public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
66         done(State.Succeeded, info);
67     }
68 
69     @Override
onFailed(UrlRequest request, UrlResponseInfo info, CronetException error)70     public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
71         mError = error;
72         done(State.Failed, info);
73     }
74 
75     @Override
onCanceled(UrlRequest request, UrlResponseInfo info)76     public void onCanceled(UrlRequest request, UrlResponseInfo info) {
77         done(State.Canceled, info);
78     }
79 
80     /**
81      * Returns the request executor.
82      *
83      * @return the executor.
84      */
getExecutor()85     public Executor getExecutor() {
86         return mExecutor;
87     }
88 
89     /** Blocks until the request is either succeeded, failed or canceled. */
blockForDone()90     public void blockForDone() {
91         mDone.block();
92     }
93 
94     /**
95      * Returns the final state of the request.
96      *
97      * @return the state.
98      */
getFinalState()99     public State getFinalState() {
100         return mState;
101     }
102 
103     /**
104      * Returns an error that was passed to {@link #onFailed}  when the request failed.
105      *
106      * @return the error if the request failed; {@code null} otherwise.
107      */
getFailureError()108     public CronetException getFailureError() {
109         return mError;
110     }
111 
112     /**
113      * Returns {@link UrlResponseInfo} of the finished response.
114      *
115      * @return the response info. {@code null} if the request hasn't completed yet.
116      */
getResponseInfo()117     public UrlResponseInfo getResponseInfo() {
118         return mResponseInfo;
119     }
120 
done(State finalState, UrlResponseInfo responseInfo)121     private void done(State finalState, UrlResponseInfo responseInfo) {
122         assertThat(mState).isEqualTo(State.NotSet);
123         mResponseInfo = responseInfo;
124         mState = finalState;
125         mDone.open();
126     }
127 }
128