Use inlined version of Base64 encoder
This commit is contained in:
parent
4f65e057eb
commit
3fca86f86f
|
@ -13,7 +13,8 @@ X.Y.Z Release notes
|
||||||
* None.
|
* None.
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
* None.
|
|
||||||
|
* Building React Native Android projects using Java version 9 used deprecated API's (#1779).
|
||||||
|
|
||||||
### Internal
|
### Internal
|
||||||
* Updated to Relm Sync 3.3.0.
|
* Updated to Relm Sync 3.3.0.
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:1.3.1'
|
classpath 'com.android.tools.build:gradle:3.1.2'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
@ -14,8 +15,9 @@ buildscript {
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
mavenLocal()
|
||||||
maven {
|
maven {
|
||||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||||
url "$rootDir/../node_modules/react-native/android"
|
url "$rootDir/../node_modules/react-native/android"
|
||||||
|
|
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.net.SocketException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -211,7 +210,7 @@ class Utils {
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
*/
|
*/
|
||||||
public static String base64Encode(String data) throws UnsupportedEncodingException {
|
public static String base64Encode(String data) throws UnsupportedEncodingException {
|
||||||
return DatatypeConverter.printBase64Binary(data.getBytes("UTF-8"));
|
return Base64.encodeToString(data.getBytes("UTF-8"), Base64.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,5 +239,397 @@ class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Note: This version has been stripped down so it only supports encoding.
|
||||||
|
*/
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for encoding and decoding the Base64 representation of
|
||||||
|
* binary data. See RFCs <a
|
||||||
|
* href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and <a
|
||||||
|
* href="http://www.ietf.org/rfc/rfc3548.txt">3548</a>.
|
||||||
|
*/
|
||||||
|
class Base64 {
|
||||||
|
/**
|
||||||
|
* Default values for encoder/decoder flags.
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoder flag bit to omit the padding '=' characters at the end
|
||||||
|
* of the output (if any).
|
||||||
|
*/
|
||||||
|
public static final int NO_PADDING = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoder flag bit to omit all line terminators (i.e., the output
|
||||||
|
* will be on one long line).
|
||||||
|
*/
|
||||||
|
public static final int NO_WRAP = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoder flag bit to indicate lines should be terminated with a
|
||||||
|
* CRLF pair instead of just an LF. Has no effect if {@code
|
||||||
|
* NO_WRAP} is specified as well.
|
||||||
|
*/
|
||||||
|
public static final int CRLF = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoder/decoder flag bit to indicate using the "URL and
|
||||||
|
* filename safe" variant of Base64 (see RFC 3548 section 4) where
|
||||||
|
* {@code -} and {@code _} are used in place of {@code +} and
|
||||||
|
* {@code /}.
|
||||||
|
*/
|
||||||
|
public static final int URL_SAFE = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to pass to {@link Base64OutputStream} to indicate that it
|
||||||
|
* should not close the output stream it is wrapping when it
|
||||||
|
* itself is closed.
|
||||||
|
*/
|
||||||
|
public static final int NO_CLOSE = 16;
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// shared code
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
/* package */ static abstract class Coder {
|
||||||
|
public byte[] output;
|
||||||
|
public int op;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode/decode another block of input data. this.output is
|
||||||
|
* provided by the caller, and must be big enough to hold all
|
||||||
|
* the coded data. On exit, this.opwill be set to the length
|
||||||
|
* of the coded data.
|
||||||
|
*
|
||||||
|
* @param finish true if this is the final call to process for
|
||||||
|
* this object. Will finalize the coder state and
|
||||||
|
* include any final bytes in the output.
|
||||||
|
*
|
||||||
|
* @return true if the input so far is good; false if some
|
||||||
|
* error has been detected in the input stream..
|
||||||
|
*/
|
||||||
|
public abstract boolean process(byte[] input, int offset, int len, boolean finish);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maximum number of bytes a call to process()
|
||||||
|
* could produce for the given number of input bytes. This may
|
||||||
|
* be an overestimate.
|
||||||
|
*/
|
||||||
|
public abstract int maxOutputSize(int len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// encoding
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64-encode the given data and return a newly allocated
|
||||||
|
* String with the result.
|
||||||
|
*
|
||||||
|
* @param input the data to encode
|
||||||
|
* @param flags controls certain features of the encoded output.
|
||||||
|
* Passing {@code DEFAULT} results in output that
|
||||||
|
* adheres to RFC 2045.
|
||||||
|
*/
|
||||||
|
public static String encodeToString(byte[] input, int flags) {
|
||||||
|
try {
|
||||||
|
return new String(encode(input, flags), "US-ASCII");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
// US-ASCII is guaranteed to be available.
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64-encode the given data and return a newly allocated
|
||||||
|
* String with the result.
|
||||||
|
*
|
||||||
|
* @param input the data to encode
|
||||||
|
* @param offset the position within the input array at which to
|
||||||
|
* start
|
||||||
|
* @param len the number of bytes of input to encode
|
||||||
|
* @param flags controls certain features of the encoded output.
|
||||||
|
* Passing {@code DEFAULT} results in output that
|
||||||
|
* adheres to RFC 2045.
|
||||||
|
*/
|
||||||
|
public static String encodeToString(byte[] input, int offset, int len, int flags) {
|
||||||
|
try {
|
||||||
|
return new String(encode(input, offset, len, flags), "US-ASCII");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
// US-ASCII is guaranteed to be available.
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64-encode the given data and return a newly allocated
|
||||||
|
* byte[] with the result.
|
||||||
|
*
|
||||||
|
* @param input the data to encode
|
||||||
|
* @param flags controls certain features of the encoded output.
|
||||||
|
* Passing {@code DEFAULT} results in output that
|
||||||
|
* adheres to RFC 2045.
|
||||||
|
*/
|
||||||
|
public static byte[] encode(byte[] input, int flags) {
|
||||||
|
return encode(input, 0, input.length, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64-encode the given data and return a newly allocated
|
||||||
|
* byte[] with the result.
|
||||||
|
*
|
||||||
|
* @param input the data to encode
|
||||||
|
* @param offset the position within the input array at which to
|
||||||
|
* start
|
||||||
|
* @param len the number of bytes of input to encode
|
||||||
|
* @param flags controls certain features of the encoded output.
|
||||||
|
* Passing {@code DEFAULT} results in output that
|
||||||
|
* adheres to RFC 2045.
|
||||||
|
*/
|
||||||
|
public static byte[] encode(byte[] input, int offset, int len, int flags) {
|
||||||
|
Encoder encoder = new Encoder(flags, null);
|
||||||
|
|
||||||
|
// Compute the exact length of the array we will produce.
|
||||||
|
int output_len = len / 3 * 4;
|
||||||
|
|
||||||
|
// Account for the tail of the data and the padding bytes, if any.
|
||||||
|
if (encoder.do_padding) {
|
||||||
|
if (len % 3 > 0) {
|
||||||
|
output_len += 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (len % 3) {
|
||||||
|
case 0: break;
|
||||||
|
case 1: output_len += 2; break;
|
||||||
|
case 2: output_len += 3; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account for the newlines, if any.
|
||||||
|
if (encoder.do_newline && len > 0) {
|
||||||
|
output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *
|
||||||
|
(encoder.do_cr ? 2 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder.output = new byte[output_len];
|
||||||
|
encoder.process(input, offset, len, true);
|
||||||
|
|
||||||
|
assert encoder.op == output_len;
|
||||||
|
|
||||||
|
return encoder.output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Encoder extends Coder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup table for turning Base64 alphabet positions (6 bits)
|
||||||
|
* into output bytes.
|
||||||
|
*/
|
||||||
|
private static final byte[] ENCODE = [
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup table for turning Base64 alphabet positions (6 bits)
|
||||||
|
* into output bytes.
|
||||||
|
*/
|
||||||
|
private static final byte[] ENCODE_WEBSAFE = [
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
|
||||||
|
];
|
||||||
|
|
||||||
|
final private byte[] tail;
|
||||||
|
/* package */ int tailLen;
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
final public boolean do_padding;
|
||||||
|
final public boolean do_newline;
|
||||||
|
final public boolean do_cr;
|
||||||
|
final private byte[] alphabet;
|
||||||
|
|
||||||
|
public Encoder(int flags, byte[] output) {
|
||||||
|
this.output = output;
|
||||||
|
|
||||||
|
do_padding = (flags & NO_PADDING) == 0;
|
||||||
|
do_newline = (flags & NO_WRAP) == 0;
|
||||||
|
do_cr = (flags & CRLF) != 0;
|
||||||
|
alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
|
||||||
|
|
||||||
|
tail = new byte[2];
|
||||||
|
tailLen = 0;
|
||||||
|
|
||||||
|
count = do_newline ? LINE_GROUPS : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an overestimate for the number of bytes {@code
|
||||||
|
* len} bytes could encode to.
|
||||||
|
*/
|
||||||
|
public int maxOutputSize(int len) {
|
||||||
|
return len * 8/5 + 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean process(byte[] input, int offset, int len, boolean finish) {
|
||||||
|
// Using local variables makes the encoder about 9% faster.
|
||||||
|
final byte[] alphabet = this.alphabet;
|
||||||
|
final byte[] output = this.output;
|
||||||
|
int op = 0;
|
||||||
|
int count = this.count;
|
||||||
|
|
||||||
|
int p = offset;
|
||||||
|
len += offset;
|
||||||
|
int v = -1;
|
||||||
|
|
||||||
|
// First we need to concatenate the tail of the previous call
|
||||||
|
// with any input bytes available now and see if we can empty
|
||||||
|
// the tail.
|
||||||
|
|
||||||
|
switch (tailLen) {
|
||||||
|
case 0:
|
||||||
|
// There was no tail.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (p+2 <= len) {
|
||||||
|
// A 1-byte tail with at least 2 bytes of
|
||||||
|
// input available now.
|
||||||
|
v = ((tail[0] & 0xff) << 16) |
|
||||||
|
((input[p++] & 0xff) << 8) |
|
||||||
|
(input[p++] & 0xff);
|
||||||
|
tailLen = 0;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (p+1 <= len) {
|
||||||
|
// A 2-byte tail with at least 1 byte of input.
|
||||||
|
v = ((tail[0] & 0xff) << 16) |
|
||||||
|
((tail[1] & 0xff) << 8) |
|
||||||
|
(input[p++] & 0xff);
|
||||||
|
tailLen = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v != -1) {
|
||||||
|
output[op++] = alphabet[(v >> 18) & 0x3f];
|
||||||
|
output[op++] = alphabet[(v >> 12) & 0x3f];
|
||||||
|
output[op++] = alphabet[(v >> 6) & 0x3f];
|
||||||
|
output[op++] = alphabet[v & 0x3f];
|
||||||
|
if (--count == 0) {
|
||||||
|
if (do_cr) output[op++] = '\r';
|
||||||
|
output[op++] = '\n';
|
||||||
|
count = LINE_GROUPS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point either there is no tail, or there are fewer
|
||||||
|
// than 3 bytes of input available.
|
||||||
|
|
||||||
|
// The main loop, turning 3 input bytes into 4 output bytes on
|
||||||
|
// each iteration.
|
||||||
|
while (p+3 <= len) {
|
||||||
|
v = ((input[p] & 0xff) << 16) |
|
||||||
|
((input[p+1] & 0xff) << 8) |
|
||||||
|
(input[p+2] & 0xff);
|
||||||
|
output[op] = alphabet[(v >> 18) & 0x3f];
|
||||||
|
output[op+1] = alphabet[(v >> 12) & 0x3f];
|
||||||
|
output[op+2] = alphabet[(v >> 6) & 0x3f];
|
||||||
|
output[op+3] = alphabet[v & 0x3f];
|
||||||
|
p += 3;
|
||||||
|
op += 4;
|
||||||
|
if (--count == 0) {
|
||||||
|
if (do_cr) output[op++] = '\r';
|
||||||
|
output[op++] = '\n';
|
||||||
|
count = LINE_GROUPS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (finish) {
|
||||||
|
// Finish up the tail of the input. Note that we need to
|
||||||
|
// consume any bytes in tail before any bytes
|
||||||
|
// remaining in input; there should be at most two bytes
|
||||||
|
// total.
|
||||||
|
|
||||||
|
if (p-tailLen == len-1) {
|
||||||
|
int t = 0;
|
||||||
|
v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
|
||||||
|
tailLen -= t;
|
||||||
|
output[op++] = alphabet[(v >> 6) & 0x3f];
|
||||||
|
output[op++] = alphabet[v & 0x3f];
|
||||||
|
if (do_padding) {
|
||||||
|
output[op++] = '=';
|
||||||
|
output[op++] = '=';
|
||||||
|
}
|
||||||
|
if (do_newline) {
|
||||||
|
if (do_cr) output[op++] = '\r';
|
||||||
|
output[op++] = '\n';
|
||||||
|
}
|
||||||
|
} else if (p-tailLen == len-2) {
|
||||||
|
int t = 0;
|
||||||
|
v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
|
||||||
|
(((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
|
||||||
|
tailLen -= t;
|
||||||
|
output[op++] = alphabet[(v >> 12) & 0x3f];
|
||||||
|
output[op++] = alphabet[(v >> 6) & 0x3f];
|
||||||
|
output[op++] = alphabet[v & 0x3f];
|
||||||
|
if (do_padding) {
|
||||||
|
output[op++] = '=';
|
||||||
|
}
|
||||||
|
if (do_newline) {
|
||||||
|
if (do_cr) output[op++] = '\r';
|
||||||
|
output[op++] = '\n';
|
||||||
|
}
|
||||||
|
} else if (do_newline && op > 0 && count != LINE_GROUPS) {
|
||||||
|
if (do_cr) output[op++] = '\r';
|
||||||
|
output[op++] = '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
assert tailLen == 0;
|
||||||
|
assert p == len;
|
||||||
|
} else {
|
||||||
|
// Save the leftovers in tail to be consumed on the next
|
||||||
|
// call to encodeInternal.
|
||||||
|
|
||||||
|
if (p == len-1) {
|
||||||
|
tail[tailLen++] = input[p];
|
||||||
|
} else if (p == len-2) {
|
||||||
|
tail[tailLen++] = input[p];
|
||||||
|
tail[tailLen++] = input[p+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.op = op;
|
||||||
|
this.count = count;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Base64() { } // don't instantiate
|
||||||
|
}
|
||||||
|
|
||||||
// see https://discuss.gradle.org/t/build-gradle-cant-find-task-class-defined-in-an-apply-from-external-script/5836/2
|
// see https://discuss.gradle.org/t/build-gradle-cant-find-task-class-defined-in-an-apply-from-external-script/5836/2
|
||||||
ext.SendAnalyticsTask = SendAnalyticsTask
|
ext.SendAnalyticsTask = SendAnalyticsTask
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:1.3.1'
|
classpath 'com.android.tools.build:gradle:3.1.2'
|
||||||
classpath 'de.undercouch:gradle-download-task:1.2'
|
classpath 'de.undercouch:gradle-download-task:1.2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
mavenLocal()
|
||||||
maven {
|
maven {
|
||||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||||
url "$projectDir/../../tests/react-test-app/node_modules/react-native/android"
|
url "$projectDir/../../tests/react-test-app/node_modules/react-native/android"
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip
|
||||||
|
|
Loading…
Reference in New Issue