Compare commits

..

13 Commits

Author SHA1 Message Date
Cameron Gutman 1ac721a35b Bump to version 5.1.2 2017-08-13 18:51:22 -07:00
Cameron Gutman e49b1c92a2 Update for AS 3.0 Beta 2 2017-08-13 18:37:31 -07:00
Cameron Gutman db4295bf83 Add adaptive icon for PC shortcut 2017-08-13 18:31:09 -07:00
Cameron Gutman 824c37f9d5 Adaptive launcher icon 2017-08-13 18:06:53 -07:00
Cameron Gutman acf4426952 Update for Gradle 4 2017-06-24 12:56:52 -07:00
Cameron Gutman e8c50342ab Version 5.1.1 2017-06-17 16:06:57 -07:00
Cameron Gutman 598995de3b Fix audio renderer using non-existant classes on Lollipop 2017-06-16 20:27:03 -07:00
Cameron Gutman 01cf0cc649 Fix Lint error 2017-06-16 20:06:45 -07:00
Cameron Gutman fa560f462f Add battery saver mode 2017-06-16 20:01:41 -07:00
Cameron Gutman f6e40118a9 Bring back the warning displayed if video decoder initialization fails 2017-06-16 19:50:50 -07:00
Cameron Gutman fe7148dbd4 Only throw decoder exceptions if we're still receiving them after 3 seconds 2017-06-16 19:39:15 -07:00
Cameron Gutman 60de065836 Cleanup video decoder teardown paths 2017-06-16 19:11:39 -07:00
Cameron Gutman 6f82f82abb Use low latency audio pathway on Lollipop and later 2017-06-16 19:08:15 -07:00
53 changed files with 240 additions and 69 deletions
+13 -8
View File
@@ -5,16 +5,18 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '26.0.0'
buildToolsVersion '26.0.1'
defaultConfig {
minSdkVersion 16
targetSdkVersion 26
versionName "5.1"
versionCode = 128
versionName "5.1.2"
versionCode = 130
}
flavorDimensions "root"
productFlavors {
root {
// Android O has native mouse capture, so don't show the rooted
@@ -25,6 +27,8 @@ android {
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64"
}
dimension "root"
}
nonRoot {
@@ -32,6 +36,8 @@ android {
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64"
}
dimension "root"
}
}
@@ -54,10 +60,9 @@ android {
}
dependencies {
compile 'org.bouncycastle:bcprov-jdk15on:1.52'
compile 'org.bouncycastle:bcpkix-jdk15on:1.52'
compile files('libs/jcodec-0.1.9-patched.jar')
implementation 'org.bouncycastle:bcprov-jdk15on:1.52'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.52'
implementation files('libs/jcodec-0.1.9-patched.jar')
debugCompile project(path:':moonlight-common', configuration:'debug')
releaseCompile project(path:':moonlight-common', configuration:'release')
implementation project(':moonlight-common')
}
+2 -1
View File
@@ -29,7 +29,8 @@
android:fullBackupContent="@xml/backup_rules"
android:isGame="true"
android:banner="@drawable/atv_banner"
android:icon="@drawable/ic_launcher"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme">
<!-- Samsung multi-window support -->
Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

+11 -1
View File
@@ -214,7 +214,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Initialize the MediaCodec helper before creating the decoder
MediaCodecHelper.initializeWithContext(this);
decoderRenderer = new MediaCodecDecoderRenderer(prefConfig.videoFormat, prefConfig.bitrate);
decoderRenderer = new MediaCodecDecoderRenderer(prefConfig.videoFormat, prefConfig.bitrate, prefConfig.batterySaver);
// Display a message to the user if H.265 was forced on but we still didn't find a decoder
if (prefConfig.videoFormat == PreferenceConfiguration.FORCE_H265_ON && !decoderRenderer.isHevcSupported()) {
@@ -944,6 +944,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
displayedFailureDialog = true;
LimeLog.severe(stage+" failed: "+errorCode);
// If video initialization failed and the surface is still valid, display extra information for the user
if (stage.contains("video") && streamView.getHolder().getSurface().isValid()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Game.this, "Video decoder failed to initialize. Your device may not support the selected resolution.", Toast.LENGTH_LONG).show();
}
});
}
Dialog.displayDialog(this, getResources().getString(R.string.conn_error_title),
getResources().getString(R.string.conn_error_msg)+" "+stage, true);
}
@@ -1,8 +1,10 @@
package com.limelight.binding.audio;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Build;
import com.limelight.LimeLog;
import com.limelight.nvstream.av.audio.AudioRenderer;
@@ -12,10 +14,58 @@ public class AndroidAudioRenderer implements AudioRenderer {
private AudioTrack track;
private AudioTrack createAudioTrack(int channelConfig, int bufferSize, boolean lowLatency) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return new AudioTrack(AudioManager.STREAM_MUSIC,
48000,
channelConfig,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);
}
else {
AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME);
AudioFormat format = new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(48000)
.setChannelMask(channelConfig)
.build();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
// Use FLAG_LOW_LATENCY on L through N
if (lowLatency) {
attributesBuilder.setFlags(AudioAttributes.FLAG_LOW_LATENCY);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AudioTrack.Builder trackBuilder = new AudioTrack.Builder()
.setAudioFormat(format)
.setAudioAttributes(attributesBuilder.build())
.setTransferMode(AudioTrack.MODE_STREAM)
.setBufferSizeInBytes(bufferSize);
// Use PERFORMANCE_MODE_LOW_LATENCY on O and later
if (lowLatency) {
trackBuilder.setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY);
}
return trackBuilder.build();
}
else {
return new AudioTrack(attributesBuilder.build(),
format,
bufferSize,
AudioTrack.MODE_STREAM,
AudioManager.AUDIO_SESSION_ID_GENERATE);
}
}
}
@Override
public int setup(int audioConfiguration) {
int channelConfig;
int bufferSize;
int bytesPerFrame;
switch (audioConfiguration)
@@ -38,44 +88,76 @@ public class AndroidAudioRenderer implements AudioRenderer {
// do this on many devices and it lowers audio latency.
// We'll try the small buffer size first and if it fails,
// use the recommended larger buffer size.
try {
// Buffer two frames of audio if possible
bufferSize = bytesPerFrame * 2;
track = new AudioTrack(AudioManager.STREAM_MUSIC,
48000,
channelConfig,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);
track.play();
} catch (Exception e) {
// Try to release the AudioTrack if we got far enough
try {
if (track != null) {
track.release();
}
} catch (Exception ignored) {}
for (int i = 0; i < 4; i++) {
boolean lowLatency;
int bufferSize;
// Now try the larger buffer size
bufferSize = Math.max(AudioTrack.getMinBufferSize(48000,
// We will try:
// 1) Small buffer, low latency mode
// 2) Large buffer, low latency mode
// 3) Small buffer, standard mode
// 4) Large buffer, standard mode
switch (i) {
case 0:
case 1:
lowLatency = true;
break;
case 2:
case 3:
lowLatency = false;
break;
default:
// Unreachable
throw new IllegalStateException();
}
switch (i) {
case 0:
case 2:
bufferSize = bytesPerFrame * 2;
break;
case 1:
case 3:
// Try the larger buffer size
bufferSize = Math.max(AudioTrack.getMinBufferSize(48000,
channelConfig,
AudioFormat.ENCODING_PCM_16BIT),
bytesPerFrame * 2);
bytesPerFrame * 2);
// Round to next frame
bufferSize = (((bufferSize + (bytesPerFrame - 1)) / bytesPerFrame) * bytesPerFrame);
// Round to next frame
bufferSize = (((bufferSize + (bytesPerFrame - 1)) / bytesPerFrame) * bytesPerFrame);
break;
default:
// Unreachable
throw new IllegalStateException();
}
track = new AudioTrack(AudioManager.STREAM_MUSIC,
48000,
channelConfig,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);
track.play();
// Skip low latency options if hardware sample rate isn't 48000Hz
if (AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC) != 48000 && lowLatency) {
continue;
}
try {
track = createAudioTrack(channelConfig, bufferSize, lowLatency);
track.play();
// Successfully created working AudioTrack. We're done here.
LimeLog.info("Audio track configuration: "+bufferSize+" "+lowLatency);
break;
} catch (Exception e) {
// Try to release the AudioTrack if we got far enough
try {
if (track != null) {
track.release();
track = null;
}
} catch (Exception ignored) {}
}
}
LimeLog.info("Audio track buffer size: "+bufferSize);
return 0;
}
@@ -51,6 +51,10 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
private boolean needsBaselineSpsHack;
private SeqParameterSet savedSps;
private RendererException initialException;
private long initialExceptionTimestamp;
private static final int EXCEPTION_REPORT_DELAY_MS = 3000;
private long lastTimestampUs;
private long decoderTimeMs;
private long totalTimeMs;
@@ -105,12 +109,18 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
this.renderTarget = renderTarget;
}
public MediaCodecDecoderRenderer(int videoFormat, int bitrate) {
public MediaCodecDecoderRenderer(int videoFormat, int bitrate, boolean batterySaver) {
//dumpDecoders();
this.bitrate = bitrate;
spinnerThreads = new Thread[Runtime.getRuntime().availableProcessors()];
// Disable spinner threads in battery saver mode
if (batterySaver) {
spinnerThreads = new Thread[0];
}
else {
spinnerThreads = new Thread[Runtime.getRuntime().availableProcessors()];
}
avcDecoder = findAvcDecoder();
if (avcDecoder != null) {
@@ -294,13 +304,31 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
}
}
// Only throw if the surface is still around and we're not stopping
if (!stopping && renderTarget.getSurface().isValid()) {
if (buf != null || codecFlags != 0) {
throw new RendererException(this, e, buf, codecFlags);
// Only throw if we're not stopping
if (!stopping) {
//
// There seems to be a race condition with decoder/surface teardown causing some
// decoders to to throw IllegalStateExceptions even before 'stopping' is set.
// To workaround this while allowing real exceptions to propagate, we will eat the
// first exception. If we are still receiving exceptions 3 seconds later, we will
// throw the original exception again.
//
if (initialException != null) {
// This isn't the first time we've had an exception processing video
if (System.currentTimeMillis() - initialExceptionTimestamp >= EXCEPTION_REPORT_DELAY_MS) {
// It's been over 3 seconds and we're still getting exceptions. Throw the original now.
throw initialException;
}
}
else {
throw new RendererException(this, e);
// This is the first exception we've hit
if (buf != null || codecFlags != 0) {
initialException = new RendererException(this, e, buf, codecFlags);
}
else {
initialException = new RendererException(this, e);
}
initialExceptionTimestamp = System.currentTimeMillis();
}
}
}
@@ -311,7 +339,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
@Override
public void run() {
BufferInfo info = new BufferInfo();
while (!isInterrupted()) {
while (!stopping) {
try {
// Try to output a frame
int outIndex = videoDecoder.dequeueOutputBuffer(info, 50000);
@@ -369,7 +397,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
public void run() {
// This thread exists to keep the CPU at a higher DVFS state on devices
// where the governor scales clock speed sporadically, causing dropped frames.
while (!isInterrupted()) {
while (!stopping) {
try {
Thread.sleep(0, 1);
} catch (InterruptedException e) {
@@ -418,17 +446,21 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
startSpinnerThreads();
}
// !!! May be called even if setup()/start() fails !!!
public void prepareForStop() {
// Let the decoding code know to ignore codec exceptions now
stopping = true;
// Halt the rendering thread
if (rendererThread != null) {
rendererThread.interrupt();
}
}
@Override
public void stop() {
stopping = true;
// Halt the rendering thread
rendererThread.interrupt();
// May be called already, but we'll call it now to be safe
prepareForStop();
try {
// Invalidate pending decode buffers
@@ -653,13 +685,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
inputBufferIndex = dequeueInputBuffer();
if (inputBufferIndex < 0) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
buf = getEmptyInputBuffer(inputBufferIndex);
if (buf == null) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
// Write the annex B header
@@ -687,13 +719,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
inputBufferIndex = dequeueInputBuffer();
if (inputBufferIndex < 0) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
buf = getEmptyInputBuffer(inputBufferIndex);
if (buf == null) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
if (needsBaselineSpsHack) {
@@ -726,13 +758,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
inputBufferIndex = dequeueInputBuffer();
if (inputBufferIndex < 0) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
buf = getEmptyInputBuffer(inputBufferIndex);
if (buf == null) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
// When we get the PPS, submit the VPS and SPS together with
@@ -751,13 +783,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
inputBufferIndex = dequeueInputBuffer();
if (inputBufferIndex < 0) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
buf = getEmptyInputBuffer(inputBufferIndex);
if (buf == null) {
// We're being torn down now
return MoonBridge.DR_OK;
return MoonBridge.DR_NEED_IDR;
}
}
@@ -900,6 +932,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
str += "Is Exynos 4: "+renderer.isExynos4+"\n";
str += "/proc/cpuinfo:\n";
try {
str += MediaCodecHelper.readCpuinfo();
} catch (Exception e) {
str += e.getMessage();
}
str += "Full decoder dump:\n";
try {
str += MediaCodecHelper.dumpDecoders();
@@ -23,6 +23,7 @@ public class PreferenceConfiguration {
private static final String USB_DRIVER_PREF_SRING = "checkbox_usb_driver";
private static final String VIDEO_FORMAT_PREF_STRING = "video_format";
private static final String ONSCREEN_CONTROLLER_PREF_STRING = "checkbox_show_onscreen_controls";
private static final String BATTERY_SAVER_PREF_STRING = "checkbox_battery_saver";
private static final int BITRATE_DEFAULT_720_30 = 5;
private static final int BITRATE_DEFAULT_720_60 = 10;
@@ -45,6 +46,7 @@ public class PreferenceConfiguration {
private static final boolean DEFAULT_USB_DRIVER = true;
private static final String DEFAULT_VIDEO_FORMAT = "auto";
private static final boolean ONSCREEN_CONTROLLER_DEFAULT = false;
private static final boolean DEFAULT_BATTERY_SAVER = false;
public static final int FORCE_H265_ON = -1;
public static final int AUTOSELECT_H265 = 0;
@@ -58,6 +60,7 @@ public class PreferenceConfiguration {
public String language;
public boolean listMode, smallIconMode, multiController, enable51Surround, usbDriver;
public boolean onscreenController;
public boolean batterySaver;
public static int getDefaultBitrate(String resFpsString) {
if (resFpsString.equals("720p30")) {
@@ -188,6 +191,7 @@ public class PreferenceConfiguration {
config.enable51Surround = prefs.getBoolean(ENABLE_51_SURROUND_PREF_STRING, DEFAULT_ENABLE_51_SURROUND);
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
config.onscreenController = prefs.getBoolean(ONSCREEN_CONTROLLER_PREF_STRING, ONSCREEN_CONTROLLER_DEFAULT);
config.batterySaver = prefs.getBoolean(BATTERY_SAVER_PREF_STRING, DEFAULT_BATTERY_SAVER);
return config;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_pc_scut_background"/>
<foreground android:drawable="@mipmap/ic_pc_scut_foreground"/>
</adaptive-icon>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_pc_scut_background"/>
<foreground android:drawable="@mipmap/ic_pc_scut_foreground"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#565C64</color>
</resources>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_pc_scut_background">#FFFFFF</color>
</resources>
+2
View File
@@ -104,6 +104,8 @@
<string name="title_checkbox_stretch_video">Stretch video to full-screen</string>
<string name="title_checkbox_disable_warnings">Disable warning messages</string>
<string name="summary_checkbox_disable_warnings">Disable on-screen connection warning messages while streaming</string>
<string name="title_checkbox_battery_saver">Battery saver</string>
<string name="summary_checkbox_battery_saver">Uses less battery, but may increase stuttering</string>
<string name="category_audio_settings">Audio Settings</string>
<string name="title_checkbox_51_surround">Enable 5.1 surround sound</string>
+3 -3
View File
@@ -21,9 +21,9 @@
android:title="@string/title_checkbox_stretch_video"
android:defaultValue="false" />
<CheckBoxPreference
android:key="checkbox_disable_warnings"
android:title="@string/title_checkbox_disable_warnings"
android:summary="@string/summary_checkbox_disable_warnings"
android:key="checkbox_battery_saver"
android:title="@string/title_checkbox_battery_saver"
android:summary="@string/summary_checkbox_battery_saver"
android:defaultValue="false" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/category_audio_settings">
+1 -1
View File
@@ -4,7 +4,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.android.tools.build:gradle:3.0.0-beta2'
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
#Thu Mar 02 18:32:01 PST 2017
#Sat Aug 12 15:52:56 PDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-rc-1-all.zip