• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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.cronet_sample_apk;
6 
7 import android.app.Activity;
8 import android.content.DialogInterface;
9 import android.os.Bundle;
10 import android.util.Log;
11 import android.view.LayoutInflater;
12 import android.view.View;
13 import android.widget.EditText;
14 import android.widget.TextView;
15 
16 import androidx.appcompat.app.AlertDialog;
17 
18 import org.chromium.net.CronetEngine;
19 import org.chromium.net.CronetException;
20 import org.chromium.net.UrlRequest;
21 import org.chromium.net.UrlResponseInfo;
22 
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.nio.ByteBuffer;
26 import java.nio.channels.Channels;
27 import java.nio.channels.WritableByteChannel;
28 import java.util.concurrent.Executor;
29 import java.util.concurrent.Executors;
30 
31 /**
32  * Activity for managing the Cronet Sample.
33  */
34 public class CronetSampleActivity extends Activity {
35     private static final String TAG = CronetSampleActivity.class.getSimpleName();
36 
37     private CronetEngine mCronetEngine;
38 
39     private String mUrl;
40     private TextView mResultText;
41     private TextView mReceiveDataText;
42 
43     class SimpleUrlRequestCallback extends UrlRequest.Callback {
44         private ByteArrayOutputStream mBytesReceived = new ByteArrayOutputStream();
45         private WritableByteChannel mReceiveChannel = Channels.newChannel(mBytesReceived);
46 
47         @Override
onRedirectReceived( UrlRequest request, UrlResponseInfo info, String newLocationUrl)48         public void onRedirectReceived(
49                 UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
50             Log.i(TAG, "****** onRedirectReceived ******");
51             request.followRedirect();
52         }
53 
54         @Override
onResponseStarted(UrlRequest request, UrlResponseInfo info)55         public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
56             Log.i(TAG, "****** Response Started ******");
57             Log.i(TAG, "*** Headers Are *** " + info.getAllHeaders());
58 
59             request.read(ByteBuffer.allocateDirect(32 * 1024));
60         }
61 
62         @Override
onReadCompleted( UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer)63         public void onReadCompleted(
64                 UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
65             byteBuffer.flip();
66             Log.i(TAG, "****** onReadCompleted ******" + byteBuffer);
67 
68             try {
69                 mReceiveChannel.write(byteBuffer);
70             } catch (IOException e) {
71                 Log.i(TAG, "IOException during ByteBuffer read. Details: ", e);
72             }
73             byteBuffer.clear();
74             request.read(byteBuffer);
75         }
76 
77         @Override
onSucceeded(UrlRequest request, UrlResponseInfo info)78         public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
79             Log.i(TAG, "****** Request Completed, status code is " + info.getHttpStatusCode()
80                             + ", total received bytes is " + info.getReceivedByteCount());
81 
82             final String receivedData = mBytesReceived.toString();
83             final String url = info.getUrl();
84             final String text = "Completed " + url + " (" + info.getHttpStatusCode() + ")";
85             CronetSampleActivity.this.runOnUiThread(new Runnable() {
86                 @Override
87                 public void run() {
88                     mResultText.setText(text);
89                     mReceiveDataText.setText(receivedData);
90                     promptForURL(url);
91                 }
92             });
93         }
94 
95         @Override
onFailed(UrlRequest request, UrlResponseInfo info, CronetException error)96         public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
97             Log.i(TAG, "****** onFailed, error is: " + error.getMessage());
98 
99             final String url = mUrl;
100             final String text = "Failed " + mUrl + " (" + error.getMessage() + ")";
101             CronetSampleActivity.this.runOnUiThread(new Runnable() {
102                 @Override
103                 public void run() {
104                     mResultText.setText(text);
105                     promptForURL(url);
106                 }
107             });
108         }
109     }
110 
111     @Override
onCreate(final Bundle savedInstanceState)112     protected void onCreate(final Bundle savedInstanceState) {
113         super.onCreate(savedInstanceState);
114         setContentView(R.layout.activity_main);
115         mResultText = (TextView) findViewById(R.id.resultView);
116         mReceiveDataText = (TextView) findViewById(R.id.dataView);
117         mReceiveDataText.setOnClickListener(new View.OnClickListener() {
118             @Override
119             public void onClick(View v) {
120                 promptForURL(mUrl);
121             }
122         });
123 
124         CronetEngine.Builder myBuilder = new CronetEngine.Builder(this);
125         myBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)
126                 .enableHttp2(true)
127                 .enableQuic(true);
128 
129         mCronetEngine = myBuilder.build();
130 
131         String appUrl = (getIntent() != null ? getIntent().getDataString() : null);
132         if (appUrl == null) {
133             promptForURL("https://");
134         } else {
135             startWithURL(appUrl);
136         }
137     }
138 
promptForURL(String url)139     private void promptForURL(String url) {
140         Log.i(TAG, "No URL provided via intent, prompting user...");
141         AlertDialog.Builder alert = new AlertDialog.Builder(this);
142         alert.setTitle("Enter a URL");
143         LayoutInflater inflater = getLayoutInflater();
144         View alertView = inflater.inflate(R.layout.dialog_url, null);
145         final EditText urlInput = (EditText) alertView.findViewById(R.id.urlText);
146         urlInput.setText(url);
147         final EditText postInput = (EditText) alertView.findViewById(R.id.postText);
148         alert.setView(alertView);
149 
150         alert.setPositiveButton("Load", new DialogInterface.OnClickListener() {
151             @Override
152             public void onClick(DialogInterface dialog, int button) {
153                 String url = urlInput.getText().toString();
154                 String postData = postInput.getText().toString();
155                 startWithURL(url, postData);
156             }
157         });
158         alert.show();
159     }
160 
applyPostDataToUrlRequestBuilder( UrlRequest.Builder builder, Executor executor, String postData)161     private void applyPostDataToUrlRequestBuilder(
162             UrlRequest.Builder builder, Executor executor, String postData) {
163         if (postData != null && postData.length() > 0) {
164             builder.setHttpMethod("POST");
165             builder.addHeader("Content-Type", "application/x-www-form-urlencoded");
166             builder.setUploadDataProvider(
167                     UploadDataProviders.create(postData.getBytes()), executor);
168         }
169     }
170 
startWithURL(String url)171     private void startWithURL(String url) {
172         startWithURL(url, null);
173     }
174 
startWithURL(String url, String postData)175     private void startWithURL(String url, String postData) {
176         Log.i(TAG, "Cronet started: " + url);
177         mUrl = url;
178 
179         Executor executor = Executors.newSingleThreadExecutor();
180         UrlRequest.Callback callback = new SimpleUrlRequestCallback();
181         UrlRequest.Builder builder = mCronetEngine.newUrlRequestBuilder(url, callback, executor);
182         applyPostDataToUrlRequestBuilder(builder, executor, postData);
183         builder.build().start();
184     }
185 
186     // Starts writing NetLog to disk. startNetLog() should be called afterwards.
startNetLog()187     private void startNetLog() {
188         mCronetEngine.startNetLogToFile(getCacheDir().getPath() + "/netlog.json", false);
189     }
190 
191     // Stops writing NetLog to disk. Should be called after calling startNetLog().
192     // NetLog can be downloaded afterwards via:
193     //   adb root
194     //   adb pull /data/data/org.chromium.cronet_sample_apk/cache/netlog.json
195     // netlog.json can then be viewed in a Chrome tab navigated to chrome://net-internals/#import
stopNetLog()196     private void stopNetLog() {
197         mCronetEngine.stopNetLog();
198     }
199 }
200