Upgrade to OkHttp3

Summary:
Update to [OkHttp](https://github.com/square/okhttp) to [OkHttp3](https://publicobject.com/2015/12/12/com-squareup-okhttp3/)

We must also update:
- Fresco to 0.10.0
- okio to 1.8.0

**Motivation**
Reasons for upgrading:
* Issue #4021
* "We discovered that RN Android sometimes fails to connect to the latest stable version of NGINX when HTTP/2 is enabled. We aren't seeing errors with other HTTP clients so we think it's specific to RN and OkHttp. Square has fixed several HTTP/2 bugs over the past eight months." - ide
* OkHttp3 will be maintained & improved, but OkHttp2 will only receive [security fixes](https://publicobject.com/2016/02/11/okhttp-certificate-pinning-vulnerability/)
* Cleaner APIs - "Get and Set prefixes are avoided"
* Deprecated/Removed - HttpURLConnection & Apache HTTP
* React Native apps are currently being forced to bundle two versions of OkHttp (v2 & v3), if another library uses v3
* Improved WebSocket performance - [CHANGELOG.md](https://github.com/square/okhttp/blob/master
Closes https://github.com/facebook/react-native/pull/6113

Reviewed By: andreicoman11, lexs

Differential Revision: D3292375

Pulled By: bestander

fbshipit-source-id: 7c7043eaa2ea63f95854108b401c4066098d67f7
This commit is contained in:
Andrew Jack 2016-05-17 12:37:50 -07:00 committed by Facebook Github Bot 1
parent 5047f6f54c
commit 6bbaff2944
29 changed files with 378 additions and 273 deletions

View File

@ -259,13 +259,14 @@ dependencies {
compile fileTree(dir: 'src/main/third-party/java/infer-annotations/', include: ['*.jar']) compile fileTree(dir: 'src/main/third-party/java/infer-annotations/', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1' compile 'com.android.support:recyclerview-v7:23.0.1'
compile 'com.facebook.fresco:fresco:0.8.1' compile 'com.facebook.fresco:fresco:0.10.0'
compile 'com.facebook.fresco:imagepipeline-okhttp:0.8.1' compile 'com.facebook.fresco:imagepipeline-okhttp3:0.10.0'
compile 'com.fasterxml.jackson.core:jackson-core:2.2.3' compile 'com.fasterxml.jackson.core:jackson-core:2.2.3'
compile 'com.google.code.findbugs:jsr305:3.0.0' compile 'com.google.code.findbugs:jsr305:3.0.0'
compile 'com.squareup.okhttp:okhttp:2.5.0' compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp:okhttp-ws:2.5.0' compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
compile 'com.squareup.okio:okio:1.6.0' compile 'com.squareup.okhttp3:okhttp-ws:3.2.0'
compile 'com.squareup.okio:okio:1.8.0'
compile 'org.webkit:android-jsc:r174650' compile 'org.webkit:android-jsc:r174650'
testCompile "junit:junit:${JUNIT_VERSION}" testCompile "junit:junit:${JUNIT_VERSION}"

View File

@ -21,16 +21,16 @@ android_library(
react_native_dep('java/com/facebook/proguard/annotations:annotations'), react_native_dep('java/com/facebook/proguard/annotations:annotations'),
], ],
deps = [ deps = [
react_native_target('java/com/facebook/react/common:common'),
react_native_dep('java/com/facebook/systrace:systrace'), react_native_dep('java/com/facebook/systrace:systrace'),
react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'), react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'),
react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'), react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'),
react_native_dep('third-party/java/infer-annotations:infer-annotations'), react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jackson:core'), react_native_dep('third-party/java/jackson:core'),
react_native_dep('third-party/java/jsr-305:jsr-305'), react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okhttp:okhttp3-ws'),
react_native_dep('third-party/java/okio:okio'), react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/okhttp:okhttp'), react_native_target('java/com/facebook/react/common:common'),
react_native_dep('third-party/java/okhttp:okhttp-ws'),
], ],
visibility = [ visibility = [
'PUBLIC', 'PUBLIC',

View File

@ -25,14 +25,15 @@ import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.JsonToken;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.Response; import okhttp3.RequestBody;
import com.squareup.okhttp.ws.WebSocket; import okhttp3.Response;
import com.squareup.okhttp.ws.WebSocketCall; import okhttp3.ResponseBody;
import com.squareup.okhttp.ws.WebSocketListener; import okhttp3.ws.WebSocket;
import okhttp3.ws.WebSocketCall;
import okhttp3.ws.WebSocketListener;
import okio.Buffer; import okio.Buffer;
import okio.BufferedSource;
/** /**
* A wrapper around WebSocketClient that recognizes RN debugging message format. * A wrapper around WebSocketClient that recognizes RN debugging message format.
@ -59,11 +60,11 @@ public class JSDebuggerWebSocketClient implements WebSocketListener {
throw new IllegalStateException("JSDebuggerWebSocketClient is already initialized."); throw new IllegalStateException("JSDebuggerWebSocketClient is already initialized.");
} }
mConnectCallback = callback; mConnectCallback = callback;
mHttpClient = new OkHttpClient(); mHttpClient = new OkHttpClient.Builder()
mHttpClient.setConnectTimeout(10, TimeUnit.SECONDS); .connectTimeout(10, TimeUnit.SECONDS)
mHttpClient.setWriteTimeout(10, TimeUnit.SECONDS); .writeTimeout(10, TimeUnit.SECONDS)
// Disable timeouts for read .readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
mHttpClient.setReadTimeout(0, TimeUnit.MINUTES); .build();
Request request = new Request.Builder().url(url).build(); Request request = new Request.Builder().url(url).build();
WebSocketCall call = WebSocketCall.create(mHttpClient, request); WebSocketCall call = WebSocketCall.create(mHttpClient, request);
@ -162,10 +163,8 @@ public class JSDebuggerWebSocketClient implements WebSocketListener {
new IllegalStateException("WebSocket connection no longer valid")); new IllegalStateException("WebSocket connection no longer valid"));
return; return;
} }
Buffer messageBuffer = new Buffer();
messageBuffer.writeUtf8(message);
try { try {
mWebSocket.sendMessage(WebSocket.PayloadType.TEXT, messageBuffer); mWebSocket.sendMessage(RequestBody.create(WebSocket.TEXT, message));
} catch (IOException e) { } catch (IOException e) {
triggerRequestFailure(requestID, e); triggerRequestFailure(requestID, e);
} }
@ -188,17 +187,17 @@ public class JSDebuggerWebSocketClient implements WebSocketListener {
} }
@Override @Override
public void onMessage(BufferedSource payload, WebSocket.PayloadType type) throws IOException { public void onMessage(ResponseBody response) throws IOException {
if (type != WebSocket.PayloadType.TEXT) { if (response.contentType() != WebSocket.TEXT) {
FLog.w(TAG, "Websocket received unexpected message with payload of type " + type); FLog.w(TAG, "Websocket received unexpected message with payload of type " + response.contentType());
return; return;
} }
String message = null; String message = null;
try { try {
message = payload.readUtf8(); message = response.source().readUtf8();
} finally { } finally {
payload.close(); response.close();
} }
Integer replyID = null; Integer replyID = null;

View File

@ -18,9 +18,9 @@ import com.facebook.react.bridge.queue.MessageQueueThreadImpl;
import com.facebook.react.bridge.queue.ProxyQueueThreadExceptionHandler; import com.facebook.react.bridge.queue.ProxyQueueThreadExceptionHandler;
import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.react.common.build.ReactBuildConfig;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.Response; import okhttp3.Response;
import okio.Okio; import okio.Okio;
import okio.Sink; import okio.Sink;

View File

@ -7,6 +7,7 @@ android_library(
':build_config', ':build_config',
react_native_dep('third-party/java/infer-annotations:infer-annotations'), react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'), react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp3'),
], ],
exported_deps = [ exported_deps = [
react_native_dep('java/com/facebook/proguard/annotations:annotations'), react_native_dep('java/com/facebook/proguard/annotations:annotations'),

View File

@ -0,0 +1,35 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
* <p/>
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.common.network;
import okhttp3.Call;
import okhttp3.OkHttpClient;
/**
* Helper class that provides the necessary methods for canceling queued and running OkHttp calls
*/
public class OkHttpCallUtil {
private OkHttpCallUtil() {
}
public static void cancelTag(OkHttpClient client, Object tag) {
for (Call call : client.dispatcher().queuedCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
for (Call call : client.dispatcher().runningCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
}
}

View File

@ -5,17 +5,16 @@ android_library(
manifest = 'AndroidManifest.xml', manifest = 'AndroidManifest.xml',
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [ deps = [
react_native_target('res:devsupport'), react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'),
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okio:okio'),
react_native_target('java/com/facebook/react/bridge:bridge'), react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'), react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/modules/debug:debug'), react_native_target('java/com/facebook/react/modules/debug:debug'),
react_native_target('java/com/facebook/react/modules/systeminfo:systeminfo'), react_native_target('java/com/facebook/react/modules/systeminfo:systeminfo'),
react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'), react_native_target('res:devsupport'),
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp'),
react_native_dep('third-party/java/okio:okio'),
], ],
visibility = [ visibility = [
'PUBLIC', 'PUBLIC',

View File

@ -17,14 +17,8 @@ import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.network.OkHttpCallUtil;
import com.facebook.react.modules.systeminfo.AndroidInfoHelpers; import com.facebook.react.modules.systeminfo.AndroidInfoHelpers;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.ConnectionPool;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -33,6 +27,13 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Okio; import okio.Okio;
import okio.Sink; import okio.Sink;
@ -91,12 +92,12 @@ public class DevServerHelper {
public DevServerHelper(DevInternalSettings settings) { public DevServerHelper(DevInternalSettings settings) {
mSettings = settings; mSettings = settings;
mClient = new OkHttpClient(); mClient = new OkHttpClient.Builder()
mClient.setConnectTimeout(HTTP_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS); .connectTimeout(HTTP_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.build();
// No read or write timeouts by default
mClient.setReadTimeout(0, TimeUnit.MILLISECONDS);
mClient.setWriteTimeout(0, TimeUnit.MILLISECONDS);
mRestartOnChangePollingHandler = new Handler(); mRestartOnChangePollingHandler = new Handler();
} }
@ -176,7 +177,7 @@ public class DevServerHelper {
mDownloadBundleFromURLCall = Assertions.assertNotNull(mClient.newCall(request)); mDownloadBundleFromURLCall = Assertions.assertNotNull(mClient.newCall(request));
mDownloadBundleFromURLCall.enqueue(new Callback() { mDownloadBundleFromURLCall.enqueue(new Callback() {
@Override @Override
public void onFailure(Request request, IOException e) { public void onFailure(Call call, IOException e) {
// ignore callback if call was cancelled // ignore callback if call was cancelled
if (mDownloadBundleFromURLCall == null || mDownloadBundleFromURLCall.isCanceled()) { if (mDownloadBundleFromURLCall == null || mDownloadBundleFromURLCall.isCanceled()) {
mDownloadBundleFromURLCall = null; mDownloadBundleFromURLCall = null;
@ -191,12 +192,12 @@ public class DevServerHelper {
.append("\u2022 Ensure that your device/emulator is connected to your machine and has USB debugging enabled - run 'adb devices' to see a list of connected devices\n") .append("\u2022 Ensure that your device/emulator is connected to your machine and has USB debugging enabled - run 'adb devices' to see a list of connected devices\n")
.append("\u2022 If you're on a physical device connected to the same machine, run 'adb reverse tcp:8081 tcp:8081' to forward requests from your device\n") .append("\u2022 If you're on a physical device connected to the same machine, run 'adb reverse tcp:8081 tcp:8081' to forward requests from your device\n")
.append("\u2022 If your device is on the same Wi-Fi network, set 'Debug server host & port for device' in 'Dev settings' to your machine's IP address and the port of the local dev server - e.g. 10.0.1.1:8081\n\n") .append("\u2022 If your device is on the same Wi-Fi network, set 'Debug server host & port for device' in 'Dev settings' to your machine's IP address and the port of the local dev server - e.g. 10.0.1.1:8081\n\n")
.append("URL: ").append(request.urlString()); .append("URL: ").append(call.request().url().toString());
callback.onFailure(new DebugServerException(sb.toString())); callback.onFailure(new DebugServerException(sb.toString()));
} }
@Override @Override
public void onResponse(Response response) throws IOException { public void onResponse(Call call, Response response) throws IOException {
// ignore callback if call was cancelled // ignore callback if call was cancelled
if (mDownloadBundleFromURLCall == null || mDownloadBundleFromURLCall.isCanceled()) { if (mDownloadBundleFromURLCall == null || mDownloadBundleFromURLCall.isCanceled()) {
mDownloadBundleFromURLCall = null; mDownloadBundleFromURLCall = null;
@ -213,7 +214,7 @@ public class DevServerHelper {
} else { } else {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("The development server returned response error code: ").append(response.code()).append("\n\n") sb.append("The development server returned response error code: ").append(response.code()).append("\n\n")
.append("URL: ").append(request.urlString()).append("\n\n") .append("URL: ").append(call.request().url().toString()).append("\n\n")
.append("Body:\n") .append("Body:\n")
.append(body); .append(body);
callback.onFailure(new DebugServerException(sb.toString())); callback.onFailure(new DebugServerException(sb.toString()));
@ -251,7 +252,7 @@ public class DevServerHelper {
mClient.newCall(request).enqueue( mClient.newCall(request).enqueue(
new Callback() { new Callback() {
@Override @Override
public void onFailure(Request request, IOException e) { public void onFailure(Call call, IOException e) {
FLog.w( FLog.w(
ReactConstants.TAG, ReactConstants.TAG,
"The packager does not seem to be running as we got an IOException requesting " + "The packager does not seem to be running as we got an IOException requesting " +
@ -260,7 +261,7 @@ public class DevServerHelper {
} }
@Override @Override
public void onResponse(Response response) throws IOException { public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) { if (!response.isSuccessful()) {
FLog.e( FLog.e(
ReactConstants.TAG, ReactConstants.TAG,
@ -297,7 +298,7 @@ public class DevServerHelper {
mOnChangePollingEnabled = false; mOnChangePollingEnabled = false;
mRestartOnChangePollingHandler.removeCallbacksAndMessages(null); mRestartOnChangePollingHandler.removeCallbacksAndMessages(null);
if (mOnChangePollingClient != null) { if (mOnChangePollingClient != null) {
mOnChangePollingClient.cancel(this); OkHttpCallUtil.cancelTag(mOnChangePollingClient, this);
mOnChangePollingClient = null; mOnChangePollingClient = null;
} }
mOnServerContentChangeListener = null; mOnServerContentChangeListener = null;
@ -311,10 +312,10 @@ public class DevServerHelper {
} }
mOnChangePollingEnabled = true; mOnChangePollingEnabled = true;
mOnServerContentChangeListener = onServerContentChangeListener; mOnServerContentChangeListener = onServerContentChangeListener;
mOnChangePollingClient = new OkHttpClient(); mOnChangePollingClient = new OkHttpClient.Builder()
mOnChangePollingClient .connectionPool(new ConnectionPool(1, LONG_POLL_KEEP_ALIVE_DURATION_MS, TimeUnit.MINUTES))
.setConnectionPool(new ConnectionPool(1, LONG_POLL_KEEP_ALIVE_DURATION_MS)) .connectTimeout(HTTP_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.setConnectTimeout(HTTP_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS); .build();
enqueueOnChangeEndpointLongPolling(); enqueueOnChangeEndpointLongPolling();
} }
@ -338,7 +339,7 @@ public class DevServerHelper {
Request request = new Request.Builder().url(createOnChangeEndpointUrl()).tag(this).build(); Request request = new Request.Builder().url(createOnChangeEndpointUrl()).tag(this).build();
Assertions.assertNotNull(mOnChangePollingClient).newCall(request).enqueue(new Callback() { Assertions.assertNotNull(mOnChangePollingClient).newCall(request).enqueue(new Callback() {
@Override @Override
public void onFailure(Request request, IOException e) { public void onFailure(Call call, IOException e) {
if (mOnChangePollingEnabled) { if (mOnChangePollingEnabled) {
// this runnable is used by onchange endpoint poller to delay subsequent requests in case // this runnable is used by onchange endpoint poller to delay subsequent requests in case
// of a failure, so that we don't flood network queue with frequent requests in case when // of a failure, so that we don't flood network queue with frequent requests in case when
@ -356,7 +357,7 @@ public class DevServerHelper {
} }
@Override @Override
public void onResponse(Response response) throws IOException { public void onResponse(Call call, Response response) throws IOException {
handleOnChangePollingResponse(response.code() == 205); handleOnChangePollingResponse(response.code() == 205);
} }
}); });
@ -376,13 +377,13 @@ public class DevServerHelper {
.build(); .build();
mClient.newCall(request).enqueue(new Callback() { mClient.newCall(request).enqueue(new Callback() {
@Override @Override
public void onFailure(Request request, IOException e) { public void onFailure(Call call, IOException e) {
// ignore HTTP call response, this is just to open a debugger page and there is no reason // ignore HTTP call response, this is just to open a debugger page and there is no reason
// to report failures from here // to report failures from here
} }
@Override @Override
public void onResponse(Response response) throws IOException { public void onResponse(Call call, Response response) throws IOException {
// ignore HTTP call response - see above // ignore HTTP call response - see above
} }
}); });

View File

@ -30,10 +30,10 @@ import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
import com.facebook.react.devsupport.StackTraceHelper.StackFrame; import com.facebook.react.devsupport.StackTraceHelper.StackFrame;
import com.squareup.okhttp.MediaType; import okhttp3.MediaType;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.RequestBody; import okhttp3.RequestBody;
import org.json.JSONObject; import org.json.JSONObject;
/** /**

View File

@ -4,21 +4,21 @@ android_library(
name = 'fresco', name = 'fresco',
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [ deps = [
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/modules/common:common'),
react_native_target('java/com/facebook/react/modules/network:network'),
react_native_dep('java/com/facebook/systrace:systrace'), react_native_dep('java/com/facebook/systrace:systrace'),
react_native_dep('libraries/fresco/fresco-react-native:fbcore'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-drawee'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-react-native'), react_native_dep('libraries/fresco/fresco-react-native:fresco-react-native'),
react_native_dep('libraries/fresco/fresco-react-native:imagepipeline'), react_native_dep('libraries/fresco/fresco-react-native:imagepipeline'),
react_native_dep('libraries/fresco/fresco-react-native:imagepipeline-okhttp'), react_native_dep('libraries/fresco/fresco-react-native:imagepipeline-okhttp3'),
react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'), react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'),
react_native_dep('third-party/android/support-annotations:android-support-annotations'), react_native_dep('third-party/android/support-annotations:android-support-annotations'),
react_native_dep('third-party/android/support/v4:lib-support-v4'), react_native_dep('third-party/android/support/v4:lib-support-v4'),
react_native_dep('third-party/java/jsr-305:jsr-305'), react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp'), react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('libraries/fresco/fresco-react-native:fbcore'), react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-drawee'), react_native_target('java/com/facebook/react/modules/common:common'),
], react_native_target('java/com/facebook/react/modules/network:network'),
],
visibility = [ visibility = [
'PUBLIC', 'PUBLIC',
], ],

View File

@ -19,7 +19,7 @@ import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.internal.AndroidPredicates; import com.facebook.common.internal.AndroidPredicates;
import com.facebook.common.soloader.SoLoaderShim; import com.facebook.common.soloader.SoLoaderShim;
import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.backends.okhttp.OkHttpImagePipelineConfigFactory; import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory;
import com.facebook.imagepipeline.core.ImagePipelineConfig; import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.core.ImagePipelineFactory; import com.facebook.imagepipeline.core.ImagePipelineFactory;
import com.facebook.imagepipeline.listener.RequestListener; import com.facebook.imagepipeline.listener.RequestListener;
@ -29,7 +29,7 @@ import com.facebook.react.modules.common.ModuleDataCleaner;
import com.facebook.react.modules.network.OkHttpClientProvider; import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.soloader.SoLoader; import com.facebook.soloader.SoLoader;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
/** /**
* Module to initialize the Fresco library. * Module to initialize the Fresco library.
@ -84,8 +84,8 @@ public class FrescoModule extends ReactContextBaseJavaModule implements
ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory(); ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory();
imagePipelineFactory.getBitmapMemoryCache().removeAll(AndroidPredicates.<CacheKey>True()); imagePipelineFactory.getBitmapMemoryCache().removeAll(AndroidPredicates.<CacheKey>True());
imagePipelineFactory.getEncodedMemoryCache().removeAll(AndroidPredicates.<CacheKey>True()); imagePipelineFactory.getEncodedMemoryCache().removeAll(AndroidPredicates.<CacheKey>True());
imagePipelineFactory.getMainDiskStorageCache().clearAll(); imagePipelineFactory.getMainFileCache().clearAll();
imagePipelineFactory.getSmallImageDiskStorageCache().clearAll(); imagePipelineFactory.getSmallImageFileCache().clearAll();
} }
private static ImagePipelineConfig getDefaultConfig( private static ImagePipelineConfig getDefaultConfig(

View File

@ -4,15 +4,16 @@ android_library(
name = 'network', name = 'network',
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [ deps = [
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/modules/core:core'),
react_native_target('java/com/facebook/react/common:common'),
react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'), react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'),
react_native_dep('third-party/android/support/v4:lib-support-v4'), react_native_dep('third-party/android/support/v4:lib-support-v4'),
react_native_dep('third-party/java/infer-annotations:infer-annotations'), react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'), react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp'), react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okhttp:okhttp3-urlconnection'),
react_native_dep('third-party/java/okio:okio'), react_native_dep('third-party/java/okio:okio'),
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/modules/core:core'),
], ],
visibility = [ visibility = [
'PUBLIC', 'PUBLIC',

View File

@ -0,0 +1,11 @@
package com.facebook.react.modules.network;
import okhttp3.CookieJar;
public interface CookieJarContainer extends CookieJar {
void setCookieJar(CookieJar cookieJar);
void removeCookieJar();
}

View File

@ -9,7 +9,7 @@
package com.facebook.react.modules.network; package com.facebook.react.modules.network;
import com.squareup.okhttp.Interceptor; import okhttp3.Interceptor;
/** /**
* Classes implementing this interface return a new {@link Interceptor} when the {@link #create} * Classes implementing this interface return a new {@link Interceptor} when the {@link #create}

View File

@ -9,17 +9,6 @@
package com.facebook.react.modules.network; package com.facebook.react.modules.network;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.SocketTimeoutException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ExecutorToken; import com.facebook.react.bridge.ExecutorToken;
import com.facebook.react.bridge.GuardedAsyncTask; import com.facebook.react.bridge.GuardedAsyncTask;
@ -30,19 +19,29 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.network.OkHttpCallUtil;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.squareup.okhttp.Callback; import java.io.IOException;
import com.squareup.okhttp.Headers; import java.io.InputStream;
import com.squareup.okhttp.MediaType; import java.io.Reader;
import com.squareup.okhttp.MultipartBuilder; import java.net.SocketTimeoutException;
import com.squareup.okhttp.OkHttpClient; import java.util.List;
import com.squareup.okhttp.Request; import java.util.concurrent.TimeUnit;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import static java.lang.Math.min; import javax.annotation.Nullable;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.JavaNetCookieJar;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
/** /**
* Implements the XMLHttpRequest JavaScript interface. * Implements the XMLHttpRequest JavaScript interface.
@ -61,6 +60,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
private final OkHttpClient mClient; private final OkHttpClient mClient;
private final ForwardingCookieHandler mCookieHandler; private final ForwardingCookieHandler mCookieHandler;
private final @Nullable String mDefaultUserAgent; private final @Nullable String mDefaultUserAgent;
private final CookieJarContainer mCookieJarContainer;
private boolean mShuttingDown; private boolean mShuttingDown;
/* package */ NetworkingModule( /* package */ NetworkingModule(
@ -76,6 +76,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
} }
} }
mCookieHandler = new ForwardingCookieHandler(reactContext); mCookieHandler = new ForwardingCookieHandler(reactContext);
mCookieJarContainer = (CookieJarContainer) mClient.cookieJar();
mShuttingDown = false; mShuttingDown = false;
mDefaultUserAgent = defaultUserAgent; mDefaultUserAgent = defaultUserAgent;
} }
@ -126,7 +127,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
@Override @Override
public void initialize() { public void initialize() {
mClient.setCookieHandler(mCookieHandler); mCookieJarContainer.setCookieJar(new JavaNetCookieJar(mCookieHandler));
} }
@Override @Override
@ -137,10 +138,10 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
@Override @Override
public void onCatalystInstanceDestroy() { public void onCatalystInstanceDestroy() {
mShuttingDown = true; mShuttingDown = true;
mClient.cancel(null); OkHttpCallUtil.cancelTag(mClient, null);
mCookieHandler.destroy(); mCookieHandler.destroy();
mClient.setCookieHandler(null); mCookieJarContainer.removeCookieJar();
} }
@ReactMethod @ReactMethod
@ -167,9 +168,10 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
// client and set the timeout explicitly on the clone. This is cheap as everything else is // client and set the timeout explicitly on the clone. This is cheap as everything else is
// shared under the hood. // shared under the hood.
// See https://github.com/square/okhttp/wiki/Recipes#per-call-configuration for more information // See https://github.com/square/okhttp/wiki/Recipes#per-call-configuration for more information
if (timeout != mClient.getConnectTimeout()) { if (timeout != mClient.connectTimeoutMillis()) {
client = mClient.clone(); client = mClient.newBuilder()
client.setReadTimeout(timeout, TimeUnit.MILLISECONDS); .readTimeout(timeout, TimeUnit.MILLISECONDS)
.build();
} }
Headers requestHeaders = extractHeaders(headers, data); Headers requestHeaders = extractHeaders(headers, data);
@ -228,7 +230,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
contentType = "multipart/form-data"; contentType = "multipart/form-data";
} }
ReadableArray parts = data.getArray(REQUEST_BODY_KEY_FORMDATA); ReadableArray parts = data.getArray(REQUEST_BODY_KEY_FORMDATA);
MultipartBuilder multipartBuilder = MultipartBody.Builder multipartBuilder =
constructMultipartBody(executorToken, parts, contentType, requestId); constructMultipartBody(executorToken, parts, contentType, requestId);
if (multipartBuilder == null) { if (multipartBuilder == null) {
return; return;
@ -242,7 +244,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
client.newCall(requestBuilder.build()).enqueue( client.newCall(requestBuilder.build()).enqueue(
new Callback() { new Callback() {
@Override @Override
public void onFailure(Request request, IOException e) { public void onFailure(Call call, IOException e) {
if (mShuttingDown) { if (mShuttingDown) {
return; return;
} }
@ -250,7 +252,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
} }
@Override @Override
public void onResponse(Response response) throws IOException { public void onResponse(Call call, Response response) throws IOException {
if (mShuttingDown) { if (mShuttingDown) {
return; return;
} }
@ -328,7 +330,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
args.pushInt(requestId); args.pushInt(requestId);
args.pushInt(response.code()); args.pushInt(response.code());
args.pushMap(headers); args.pushMap(headers);
args.pushString(response.request().urlString()); args.pushString(response.request().url().toString());
getEventEmitter(ExecutorToken).emit("didReceiveNetworkResponse", args); getEventEmitter(ExecutorToken).emit("didReceiveNetworkResponse", args);
} }
@ -356,7 +358,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override @Override
protected void doInBackgroundGuarded(Void... params) { protected void doInBackgroundGuarded(Void... params) {
mClient.cancel(requestId); OkHttpCallUtil.cancelTag(mClient, requestId);
} }
}.execute(); }.execute();
} }
@ -373,15 +375,13 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
return true; return true;
} }
private private @Nullable MultipartBody.Builder constructMultipartBody(
@Nullable
MultipartBuilder constructMultipartBody(
ExecutorToken ExecutorToken, ExecutorToken ExecutorToken,
ReadableArray body, ReadableArray body,
String contentType, String contentType,
int requestId) { int requestId) {
MultipartBuilder multipartBuilder = new MultipartBuilder(); MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
multipartBuilder.type(MediaType.parse(contentType)); multipartBuilder.setType(MediaType.parse(contentType));
for (int i = 0, size = body.size(); i < size; i++) { for (int i = 0, size = body.size(); i < size; i++) {
ReadableMap bodyPart = body.getMap(i); ReadableMap bodyPart = body.getMap(i);
@ -440,9 +440,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
/** /**
* Extracts the headers from the Array. If the format is invalid, this method will return null. * Extracts the headers from the Array. If the format is invalid, this method will return null.
*/ */
private private @Nullable Headers extractHeaders(
@Nullable
Headers extractHeaders(
@Nullable ReadableArray headersArray, @Nullable ReadableArray headersArray,
@Nullable ReadableMap requestData) { @Nullable ReadableMap requestData) {
if (headersArray == null) { if (headersArray == null) {
@ -475,4 +473,4 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
return getReactApplicationContext() return getReactApplicationContext()
.getJSModule(ExecutorToken, DeviceEventManagerModule.RCTDeviceEventEmitter.class); .getJSModule(ExecutorToken, DeviceEventManagerModule.RCTDeviceEventEmitter.class);
} }
} }

View File

@ -9,11 +9,11 @@
package com.facebook.react.modules.network; package com.facebook.react.modules.network;
import javax.annotation.Nullable;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.squareup.okhttp.OkHttpClient; import javax.annotation.Nullable;
import okhttp3.OkHttpClient;
/** /**
* Helper class that provides the same OkHttpClient instance that will be used for all networking * Helper class that provides the same OkHttpClient instance that will be used for all networking
@ -30,15 +30,20 @@ public class OkHttpClientProvider {
} }
return sClient; return sClient;
} }
// okhttp3 OkHttpClient is immutable
// This allows app to init an OkHttpClient with custom settings.
public static void replaceOkHttpClient(OkHttpClient client) {
sClient = client;
}
private static OkHttpClient createClient() { private static OkHttpClient createClient() {
OkHttpClient client = new OkHttpClient();
// No timeouts by default // No timeouts by default
client.setConnectTimeout(0, TimeUnit.MILLISECONDS); return new OkHttpClient.Builder()
client.setReadTimeout(0, TimeUnit.MILLISECONDS); .connectTimeout(0, TimeUnit.MILLISECONDS)
client.setWriteTimeout(0, TimeUnit.MILLISECONDS); .readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
return client; .cookieJar(new ReactCookieJarContainer())
.build();
} }
} }

View File

@ -0,0 +1,44 @@
package com.facebook.react.modules.network;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
/**
* Basic okhttp3 CookieJar container
*/
public class ReactCookieJarContainer implements CookieJarContainer {
@Nullable
private CookieJar cookieJar = null;
@Override
public void setCookieJar(CookieJar cookieJar) {
this.cookieJar = cookieJar;
}
@Override
public void removeCookieJar() {
this.cookieJar = null;
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
if (cookieJar != null) {
cookieJar.saveFromResponse(url, cookies);
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
if (cookieJar != null) {
return cookieJar.loadForRequest(url);
}
return Collections.emptyList();
}
}

View File

@ -23,9 +23,9 @@ import android.net.Uri;
import com.facebook.common.logging.FLog; import com.facebook.common.logging.FLog;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
import com.squareup.okhttp.MediaType; import okhttp3.MediaType;
import com.squareup.okhttp.RequestBody; import okhttp3.RequestBody;
import com.squareup.okhttp.internal.Util; import okhttp3.internal.Util;
import okio.BufferedSink; import okio.BufferedSink;
import okio.ByteString; import okio.ByteString;
import okio.Okio; import okio.Okio;

View File

@ -4,16 +4,16 @@ android_library(
name = 'websocket', name = 'websocket',
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [ deps = [
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/modules/core:core'),
react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'), react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'),
react_native_dep('third-party/java/infer-annotations:infer-annotations'), react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'), react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp-ws'), react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okhttp:okhttp'), react_native_dep('third-party/java/okhttp:okhttp3-ws'),
react_native_dep('third-party/java/okio:okio'), react_native_dep('third-party/java/okio:okio'),
], react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/modules/core:core'),
],
visibility = [ visibility = [
'PUBLIC', 'PUBLIC',
], ],

View File

@ -29,12 +29,14 @@ import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.Response; import okhttp3.RequestBody;
import com.squareup.okhttp.ws.WebSocket; import okhttp3.Response;
import com.squareup.okhttp.ws.WebSocketCall; import okhttp3.ResponseBody;
import com.squareup.okhttp.ws.WebSocketListener; import okhttp3.ws.WebSocket;
import okhttp3.ws.WebSocketCall;
import okhttp3.ws.WebSocketListener;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URI; import java.net.URI;
@ -43,7 +45,6 @@ import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import okio.Buffer; import okio.Buffer;
import okio.BufferedSource;
import okio.ByteString; import okio.ByteString;
public class WebSocketModule extends ReactContextBaseJavaModule { public class WebSocketModule extends ReactContextBaseJavaModule {
@ -69,12 +70,11 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
@ReactMethod @ReactMethod
public void connect(final String url, @Nullable final ReadableArray protocols, @Nullable final ReadableMap headers, final int id) { public void connect(final String url, @Nullable final ReadableArray protocols, @Nullable final ReadableMap headers, final int id) {
OkHttpClient client = new OkHttpClient(); OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
client.setConnectTimeout(10, TimeUnit.SECONDS); .writeTimeout(10, TimeUnit.SECONDS)
client.setWriteTimeout(10, TimeUnit.SECONDS); .readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
// Disable timeouts for read .build();
client.setReadTimeout(0, TimeUnit.MINUTES);
Request.Builder builder = new Request.Builder() Request.Builder builder = new Request.Builder()
.tag(id) .tag(id)
@ -145,20 +145,20 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
} }
@Override @Override
public void onMessage(BufferedSource bufferedSource, WebSocket.PayloadType payloadType) { public void onMessage(ResponseBody response) throws IOException {
String message; String message;
try { try {
if (payloadType == WebSocket.PayloadType.BINARY) { if (response.contentType() == WebSocket.BINARY) {
message = Base64.encodeToString(bufferedSource.readByteArray(), Base64.NO_WRAP); message = Base64.encodeToString(response.source().readByteArray(), Base64.NO_WRAP);
} else { } else {
message = bufferedSource.readUtf8(); message = response.source().readUtf8();
} }
} catch (IOException e) { } catch (IOException e) {
notifyWebSocketFailed(id, e.getMessage()); notifyWebSocketFailed(id, e.getMessage());
return; return;
} }
try { try {
bufferedSource.close(); response.source().close();
} catch (IOException e) { } catch (IOException e) {
FLog.e( FLog.e(
ReactConstants.TAG, ReactConstants.TAG,
@ -169,13 +169,13 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
WritableMap params = Arguments.createMap(); WritableMap params = Arguments.createMap();
params.putInt("id", id); params.putInt("id", id);
params.putString("data", message); params.putString("data", message);
params.putString("type", payloadType == WebSocket.PayloadType.BINARY ? "binary" : "text"); params.putString("type", response.contentType() == WebSocket.BINARY ? "binary" : "text");
sendEvent("websocketMessage", params); sendEvent("websocketMessage", params);
} }
}); });
// Trigger shutdown of the dispatcher's executor so this process can exit cleanly // Trigger shutdown of the dispatcher's executor so this process can exit cleanly
client.getDispatcher().getExecutorService().shutdown(); client.dispatcher().executorService().shutdown();
} }
@ReactMethod @ReactMethod
@ -209,9 +209,7 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id); throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
} }
try { try {
client.sendMessage( client.sendMessage(RequestBody.create(WebSocket.TEXT, message));
WebSocket.PayloadType.TEXT,
new Buffer().writeUtf8(message));
} catch (IOException | IllegalStateException e) { } catch (IOException | IllegalStateException e) {
notifyWebSocketFailed(id, e.getMessage()); notifyWebSocketFailed(id, e.getMessage());
} }
@ -225,9 +223,7 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id); throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
} }
try { try {
client.sendMessage( client.sendMessage(RequestBody.create(WebSocket.TEXT, ByteString.decodeBase64(base64String)));
WebSocket.PayloadType.BINARY,
new Buffer().write(ByteString.decodeBase64(base64String)));
} catch (IOException | IllegalStateException e) { } catch (IOException | IllegalStateException e) {
notifyWebSocketFailed(id, e.getMessage()); notifyWebSocketFailed(id, e.getMessage());
} }

View File

@ -6,8 +6,8 @@ android_prebuilt_aar(
remote_file( remote_file(
name = 'fresco-binary-aar', name = 'fresco-binary-aar',
url = 'mvn:com.facebook.fresco:fresco:aar:0.8.1', url = 'mvn:com.facebook.fresco:fresco:aar:0.10.0',
sha1 = 'f0a4f04318123e1597514b2abf56b7e66581f3f8', sha1 = '8576630feea3d08eb681dec389a472623179f84d',
) )
android_prebuilt_aar( android_prebuilt_aar(
@ -18,19 +18,31 @@ android_prebuilt_aar(
remote_file( remote_file(
name = 'drawee-binary-aar', name = 'drawee-binary-aar',
url = 'mvn:com.facebook.fresco:drawee:aar:0.8.1', url = 'mvn:com.facebook.fresco:drawee:aar:0.10.0',
sha1 = 'a944015ddf50fdad79302e42a85a351633c24472', sha1 = 'c594f9c23f844d08ecd4c0e42df40d80767d4b18',
) )
android_library( android_library(
name = 'imagepipeline', name = 'imagepipeline',
exported_deps = [ exported_deps = [
':imagepipeline-base',
':imagepipeline-core', ':imagepipeline-core',
':bolts', ':bolts',
], ],
visibility = ['//ReactAndroid/...',], visibility = ['//ReactAndroid/...',],
) )
android_prebuilt_aar(
name = 'imagepipeline-base',
aar = ':imagepipeline-base-aar',
visibility = ['//ReactAndroid/...',],
)
remote_file(
name = 'imagepipeline-base-aar',
url = 'mvn:com.facebook.fresco:imagepipeline-base:aar:0.10.0',
sha1 = '1390f28d0e4f16b0008fed481eb1b107d93f35b8',
)
android_prebuilt_aar( android_prebuilt_aar(
name = 'imagepipeline-core', name = 'imagepipeline-core',
@ -40,8 +52,8 @@ android_prebuilt_aar(
remote_file( remote_file(
name = 'imagepipeline-aar', name = 'imagepipeline-aar',
url = 'mvn:com.facebook.fresco:imagepipeline:aar:0.8.1', url = 'mvn:com.facebook.fresco:imagepipeline:aar:0.10.0',
sha1 = '93fe3e629c03aea8f63dabd80a0e616b0caef65b', sha1 = 'ecec308b714039dd9e0cf4b7595a427765f43a01',
) )
prebuilt_jar( prebuilt_jar(
@ -64,18 +76,18 @@ android_prebuilt_aar(
remote_file( remote_file(
name = 'fbcore-aar', name = 'fbcore-aar',
url = 'mvn:com.facebook.fresco:fbcore:aar:0.8.1', url = 'mvn:com.facebook.fresco:fbcore:aar:0.10.0',
sha1 = 'cc46b3d564139bf63bb41534c7a723ee8119ae5f', sha1 = '4650dd9a46064c254e0468bba23804e8f32e6144',
) )
android_prebuilt_aar( android_prebuilt_aar(
name = 'imagepipeline-okhttp', name = 'imagepipeline-okhttp3',
aar = ':imagepipeline-okhttp-binary-aar', aar = ':imagepipeline-okhttp3-binary-aar',
visibility = ['//ReactAndroid/...',], visibility = ['//ReactAndroid/...',],
) )
remote_file( remote_file(
name = 'imagepipeline-okhttp-binary-aar', name = 'imagepipeline-okhttp3-binary-aar',
url = 'mvn:com.facebook.fresco:imagepipeline-okhttp:aar:0.8.1', url = 'mvn:com.facebook.fresco:imagepipeline-okhttp3:aar:0.10.0',
sha1 = 'd6b16dbaab8b810620347355a425fb2982e33ef8', sha1 = 'a3e95483f116b528bdf2d06f7ff2212cb9b372e2',
) )

View File

@ -1,23 +1,35 @@
prebuilt_jar( prebuilt_jar(
name = 'okhttp', name = 'okhttp3',
binary_jar = ':okhttp-binary-jar', binary_jar = ':okhttp3-binary-jar',
visibility = ['//ReactAndroid/...',], visibility = ['//ReactAndroid/...',],
) )
remote_file( remote_file(
name = 'okhttp-binary-jar', name = 'okhttp3-binary-jar',
url = 'mvn:com.squareup.okhttp:okhttp:jar:2.5.0', url = 'mvn:com.squareup.okhttp3:okhttp:jar:3.2.0',
sha1 = '4de2b4ed3445c37ec1720a7d214712e845a24636' sha1 = 'f7873a2ebde246a45c2a8d6f3247108b4c88a879'
) )
prebuilt_jar( prebuilt_jar(
name = 'okhttp-ws', name = 'okhttp3-urlconnection',
binary_jar = ':okhttp-ws-binary-jar', binary_jar = ':okhttp3-urlconnection-binary-jar',
visibility = ['//ReactAndroid/...',],
)
remote_file(
name = 'okhttp3-urlconnection-binary-jar',
url = 'mvn:com.squareup.okhttp3:okhttp-urlconnection:jar:3.2.0',
sha1 = '6f8a4b1435c9e0a6f9c5fe4a1be46627b848fd0c'
)
prebuilt_jar(
name = 'okhttp3-ws',
binary_jar = ':okhttp3-ws-binary-jar',
visibility = ['//ReactAndroid/...',], visibility = ['//ReactAndroid/...',],
) )
remote_file( remote_file(
name = 'okhttp-ws-binary-jar', name = 'okhttp3-ws-binary-jar',
url = 'mvn:com.squareup.okhttp:okhttp-ws:jar:2.5.0', url = 'mvn:com.squareup.okhttp3:okhttp-ws:jar:3.2.0',
sha1 = '0e9753b7dcae5deca92e871c5c759067070b07bc', sha1 = '1ea229d6984444c8c58b8e97ba4c8429d9d135b3',
) )

View File

@ -6,6 +6,6 @@ prebuilt_jar(
remote_file( remote_file(
name = 'okio-binary-jar', name = 'okio-binary-jar',
url = 'mvn:com.squareup.okio:okio:jar:1.6.0', url = 'mvn:com.squareup.okio:okio:jar:1.8.0',
sha1 = '98476622f10715998eacf9240d6b479f12c66143', sha1 = '05ea7af56cc7c567ed9856d99efb30740e9b17ff',
) )

View File

@ -6,8 +6,15 @@ robolectric3_test(
contacts = ['oncall+fbandroid_sheriff@xmail.facebook.com'], contacts = ['oncall+fbandroid_sheriff@xmail.facebook.com'],
srcs = glob(['*.java']), srcs = glob(['*.java']),
deps = [ deps = [
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_target('java/com/facebook/csslayout:csslayout'), react_native_target('java/com/facebook/csslayout:csslayout'),
react_native_target('java/com/facebook/react:react'),
react_native_target('java/com/facebook/react/animation:animation'), react_native_target('java/com/facebook/react/animation:animation'),
react_native_target('java/com/facebook/react/bridge:bridge'), react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'), react_native_target('java/com/facebook/react/common:common'),
@ -15,20 +22,11 @@ robolectric3_test(
react_native_target('java/com/facebook/react/uimanager:uimanager'), react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/views/text:text'), react_native_target('java/com/facebook/react/views/text:text'),
react_native_target('java/com/facebook/react/views/view:view'), react_native_target('java/com/facebook/react/views/view:view'),
react_native_target('java/com/facebook/react:react'),
react_native_tests_target('java/com/facebook/react/bridge:testhelpers'), react_native_tests_target('java/com/facebook/react/bridge:testhelpers'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
], ],
) )
project_config( project_config(
test_target = ':react', test_target = ':react',
) )

View File

@ -6,8 +6,14 @@ robolectric3_test(
name = 'modules', name = 'modules',
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [ deps = [
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_target('java/com/facebook/csslayout:csslayout'), react_native_target('java/com/facebook/csslayout:csslayout'),
react_native_target('java/com/facebook/react:react'),
react_native_target('java/com/facebook/react/animation:animation'), react_native_target('java/com/facebook/react/animation:animation'),
react_native_target('java/com/facebook/react/bridge:bridge'), react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'), react_native_target('java/com/facebook/react/common:common'),
@ -19,17 +25,10 @@ robolectric3_test(
react_native_target('java/com/facebook/react/modules/network:network'), react_native_target('java/com/facebook/react/modules/network:network'),
react_native_target('java/com/facebook/react/modules/storage:storage'), react_native_target('java/com/facebook/react/modules/storage:storage'),
react_native_target('java/com/facebook/react/modules/systeminfo:systeminfo'), react_native_target('java/com/facebook/react/modules/systeminfo:systeminfo'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/touch:touch'), react_native_target('java/com/facebook/react/touch:touch'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react:react'),
react_native_tests_target('java/com/facebook/react/bridge:testhelpers'), react_native_tests_target('java/com/facebook/react/bridge:testhelpers'),
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp'),
], ],
visibility = [ visibility = [
'PUBLIC' 'PUBLIC'

View File

@ -23,22 +23,19 @@ import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter; import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
import com.squareup.okhttp.Call; import okhttp3.Call;
import com.squareup.okhttp.Headers; import okhttp3.Headers;
import com.squareup.okhttp.MediaType; import okhttp3.MediaType;
import com.squareup.okhttp.MultipartBuilder; import okhttp3.MultipartBody;
import com.squareup.okhttp.OkHttpClient; import okhttp3.OkHttpClient;
import com.squareup.okhttp.Request; import okhttp3.Request;
import com.squareup.okhttp.RequestBody; import okhttp3.RequestBody;
import okio.Buffer; import okio.Buffer;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
@ -46,9 +43,7 @@ import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.rule.PowerMockRule; import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static org.fest.assertions.api.Assertions.assertThat; import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
@ -65,7 +60,8 @@ import static org.mockito.Mockito.when;
Arguments.class, Arguments.class,
Call.class, Call.class,
RequestBodyUtil.class, RequestBodyUtil.class,
MultipartBuilder.class, MultipartBody.class,
MultipartBody.Builder.class,
NetworkingModule.class, NetworkingModule.class,
OkHttpClient.class}) OkHttpClient.class})
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@ -100,7 +96,7 @@ public class NetworkingModuleTest {
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class); ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
verify(httpClient).newCall(argumentCaptor.capture()); verify(httpClient).newCall(argumentCaptor.capture());
assertThat(argumentCaptor.getValue().urlString()).isEqualTo("http://somedomain/foo"); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://somedomain/foo");
// We set the User-Agent header by default // We set the User-Agent header by default
assertThat(argumentCaptor.getValue().headers().size()).isEqualTo(1); assertThat(argumentCaptor.getValue().headers().size()).isEqualTo(1);
assertThat(argumentCaptor.getValue().method()).isEqualTo("GET"); assertThat(argumentCaptor.getValue().method()).isEqualTo("GET");
@ -215,7 +211,7 @@ public class NetworkingModuleTest {
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class); ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
verify(httpClient).newCall(argumentCaptor.capture()); verify(httpClient).newCall(argumentCaptor.capture());
assertThat(argumentCaptor.getValue().urlString()).isEqualTo("http://somedomain/bar"); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://somedomain/bar");
assertThat(argumentCaptor.getValue().headers().size()).isEqualTo(2); assertThat(argumentCaptor.getValue().headers().size()).isEqualTo(2);
assertThat(argumentCaptor.getValue().method()).isEqualTo("POST"); assertThat(argumentCaptor.getValue().method()).isEqualTo("POST");
assertThat(argumentCaptor.getValue().body().contentType().type()).isEqualTo("text"); assertThat(argumentCaptor.getValue().body().contentType().type()).isEqualTo("text");
@ -302,12 +298,12 @@ public class NetworkingModuleTest {
// verify url, method, headers // verify url, method, headers
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class); ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
verify(httpClient).newCall(argumentCaptor.capture()); verify(httpClient).newCall(argumentCaptor.capture());
assertThat(argumentCaptor.getValue().urlString()).isEqualTo("http://someurl/uploadFoo"); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://someurl/uploadFoo");
assertThat(argumentCaptor.getValue().method()).isEqualTo("POST"); assertThat(argumentCaptor.getValue().method()).isEqualTo("POST");
assertThat(argumentCaptor.getValue().body().contentType().type()). assertThat(argumentCaptor.getValue().body().contentType().type()).
isEqualTo(MultipartBuilder.FORM.type()); isEqualTo(MultipartBody.FORM.type());
assertThat(argumentCaptor.getValue().body().contentType().subtype()). assertThat(argumentCaptor.getValue().body().contentType().subtype()).
isEqualTo(MultipartBuilder.FORM.subtype()); isEqualTo(MultipartBody.FORM.subtype());
Headers requestHeaders = argumentCaptor.getValue().headers(); Headers requestHeaders = argumentCaptor.getValue().headers();
assertThat(requestHeaders.size()).isEqualTo(1); assertThat(requestHeaders.size()).isEqualTo(1);
} }
@ -361,12 +357,12 @@ public class NetworkingModuleTest {
// verify url, method, headers // verify url, method, headers
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class); ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
verify(httpClient).newCall(argumentCaptor.capture()); verify(httpClient).newCall(argumentCaptor.capture());
assertThat(argumentCaptor.getValue().urlString()).isEqualTo("http://someurl/uploadFoo"); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://someurl/uploadFoo");
assertThat(argumentCaptor.getValue().method()).isEqualTo("POST"); assertThat(argumentCaptor.getValue().method()).isEqualTo("POST");
assertThat(argumentCaptor.getValue().body().contentType().type()). assertThat(argumentCaptor.getValue().body().contentType().type()).
isEqualTo(MultipartBuilder.FORM.type()); isEqualTo(MultipartBody.FORM.type());
assertThat(argumentCaptor.getValue().body().contentType().subtype()). assertThat(argumentCaptor.getValue().body().contentType().subtype()).
isEqualTo(MultipartBuilder.FORM.subtype()); isEqualTo(MultipartBody.FORM.subtype());
Headers requestHeaders = argumentCaptor.getValue().headers(); Headers requestHeaders = argumentCaptor.getValue().headers();
assertThat(requestHeaders.size()).isEqualTo(3); assertThat(requestHeaders.size()).isEqualTo(3);
assertThat(requestHeaders.get("Accept")).isEqualTo("text/plain"); assertThat(requestHeaders.get("Accept")).isEqualTo("text/plain");
@ -383,9 +379,9 @@ public class NetworkingModuleTest {
when(RequestBodyUtil.create(any(MediaType.class), any(InputStream.class))).thenCallRealMethod(); when(RequestBodyUtil.create(any(MediaType.class), any(InputStream.class))).thenCallRealMethod();
when(inputStream.available()).thenReturn("imageUri".length()); when(inputStream.available()).thenReturn("imageUri".length());
final MultipartBuilder multipartBuilder = mock(MultipartBuilder.class); final MultipartBody.Builder multipartBuilder = mock(MultipartBody.Builder.class);
PowerMockito.whenNew(MultipartBuilder.class).withNoArguments().thenReturn(multipartBuilder); PowerMockito.whenNew(MultipartBody.Builder.class).withNoArguments().thenReturn(multipartBuilder);
when(multipartBuilder.type(any(MediaType.class))).thenAnswer( when(multipartBuilder.setType(any(MediaType.class))).thenAnswer(
new Answer<Object>() { new Answer<Object>() {
@Override @Override
public Object answer(InvocationOnMock invocation) throws Throwable { public Object answer(InvocationOnMock invocation) throws Throwable {
@ -403,7 +399,7 @@ public class NetworkingModuleTest {
new Answer<Object>() { new Answer<Object>() {
@Override @Override
public Object answer(InvocationOnMock invocation) throws Throwable { public Object answer(InvocationOnMock invocation) throws Throwable {
return mock(RequestBody.class); return mock(MultipartBody.class);
} }
}); });
@ -462,7 +458,7 @@ public class NetworkingModuleTest {
// verify body // verify body
verify(multipartBuilder).build(); verify(multipartBuilder).build();
verify(multipartBuilder).type(MultipartBuilder.FORM); verify(multipartBuilder).setType(MultipartBody.FORM);
ArgumentCaptor<Headers> headersArgumentCaptor = ArgumentCaptor.forClass(Headers.class); ArgumentCaptor<Headers> headersArgumentCaptor = ArgumentCaptor.forClass(Headers.class);
ArgumentCaptor<RequestBody> bodyArgumentCaptor = ArgumentCaptor.forClass(RequestBody.class); ArgumentCaptor<RequestBody> bodyArgumentCaptor = ArgumentCaptor.forClass(RequestBody.class);
verify(multipartBuilder, times(2)). verify(multipartBuilder, times(2)).

View File

@ -6,26 +6,25 @@ robolectric3_test(
contacts = ['oncall+fbandroid_sheriff@xmail.facebook.com'], contacts = ['oncall+fbandroid_sheriff@xmail.facebook.com'],
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [ deps = [
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_target('java/com/facebook/csslayout:csslayout'), react_native_target('java/com/facebook/csslayout:csslayout'),
react_native_target('java/com/facebook/react:react'),
react_native_target('java/com/facebook/react/animation:animation'), react_native_target('java/com/facebook/react/animation:animation'),
react_native_target('java/com/facebook/react/bridge:bridge'), react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'), react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/touch:touch'), react_native_target('java/com/facebook/react/touch:touch'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/uimanager/annotations:annotations'), react_native_target('java/com/facebook/react/uimanager/annotations:annotations'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/views/text:text'), react_native_target('java/com/facebook/react/views/text:text'),
react_native_target('java/com/facebook/react/views/view:view'), react_native_target('java/com/facebook/react/views/view:view'),
react_native_target('java/com/facebook/react:react'),
react_native_tests_target('java/com/facebook/react/bridge:testhelpers'), react_native_tests_target('java/com/facebook/react/bridge:testhelpers'),
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
], ],
visibility = [ visibility = [
'PUBLIC' 'PUBLIC'

View File

@ -6,31 +6,29 @@ robolectric3_test(
contacts = ['oncall+fbandroid_sheriff@xmail.facebook.com'], contacts = ['oncall+fbandroid_sheriff@xmail.facebook.com'],
srcs = glob(['**/*.java']), srcs = glob(['**/*.java']),
deps = [ deps = [
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-drawee'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-react-native'),
react_native_dep('libraries/fresco/fresco-react-native:imagepipeline'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_target('java/com/facebook/csslayout:csslayout'), react_native_target('java/com/facebook/csslayout:csslayout'),
react_native_target('java/com/facebook/react:react'),
react_native_target('java/com/facebook/react/bridge:bridge'), react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'), react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/touch:touch'), react_native_target('java/com/facebook/react/touch:touch'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/uimanager/annotations:annotations'), react_native_target('java/com/facebook/react/uimanager/annotations:annotations'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/views/image:image'), react_native_target('java/com/facebook/react/views/image:image'),
react_native_target('java/com/facebook/react/views/text:text'), react_native_target('java/com/facebook/react/views/text:text'),
react_native_target('java/com/facebook/react/views/textinput:textinput'), react_native_target('java/com/facebook/react/views/textinput:textinput'),
react_native_target('java/com/facebook/react/views/view:view'), react_native_target('java/com/facebook/react/views/view:view'),
react_native_target('java/com/facebook/react:react'),
react_native_tests_target('java/com/facebook/react/bridge:testhelpers'), react_native_tests_target('java/com/facebook/react/bridge:testhelpers'),
react_native_dep('third-party/java/robolectric3/robolectric:robolectric'),
react_native_dep('third-party/java/fest:fest'),
react_native_dep('third-party/java/junit:junit'),
react_native_dep('third-party/java/okio:okio'),
react_native_dep('third-party/java/mockito:mockito'),
react_native_dep('third-party/java/okhttp:okhttp'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-react-native'),
react_native_dep('libraries/fresco/fresco-react-native:imagepipeline'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-drawee'),
], ],
) )

View File

@ -51,9 +51,9 @@
-keepattributes Signature -keepattributes Signature
-keepattributes *Annotation* -keepattributes *Annotation*
-keep class com.squareup.okhttp.** { *; } -keep class okhttp3.** { *; }
-keep interface com.squareup.okhttp.** { *; } -keep interface okhttp3.** { *; }
-dontwarn com.squareup.okhttp.** -dontwarn okhttp3.**
# okio # okio