Upgrading to JUCE 7.0.8

This commit is contained in:
Jonathan Thomas
2024-12-08 11:52:40 -06:00
parent 3ef80991d2
commit 92141fd2b3
880 changed files with 84780 additions and 27787 deletions

View File

@@ -9,30 +9,31 @@ required for the Java source code you wish to compile.
2. If you are creating byte-code for new .java files, move the new files into
the native/javacore/app folder of the module, or create one if it doesn't
exist. Remember that .java files need to be in nested sub-folders which
resemble their package, i.e. a Java class com.roli.juce.HelloWorld.java
should be in the module's native/javacore/app/com/roli/juce folder.
If you wish to modify existing .java files in the JUCE modules then just rename
native/java to native/javacore.
resemble their package, i.e. a Java class com.rmsl.juce.HelloWorld.java should
be in the module's native/javacore/app/com/rmsl/juce folder. If you wish to
modify existing .java files in the JUCE modules then just rename native/java to
native/javacore.
3. Build your project with AS and run. The app will now use the source code in
the folder created in step 2 so you can debug your Java code this way.
3. Build your project with Android Studio and run. The app will now use the
source code in the folder created in step 2 so you can debug your Java code
this way.
4. Once everything is working rebuild your app in release mode.
5. Go to your app's Builds/Android folder. Inside there you will find
build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes.
build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes.
Inside of that folder, you will find all your Java byte-code compiled classes.
Remove any classes that you are not interested in (typically you'll find
Java.class, JuceApp.class and JuceSharingContentProvider.class which you will
probably want to remove).
Java.class and JuceApp.class which you will probably want to remove).
6. Inside of build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes
6. Inside of
build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes
execute the following dx command:
<path-to-your-android-sdk>/build-tools/<latest-build-tool-version>/dx --dex --verbose --min-sdk-version=<your-min-sdk-of-your-classes> --output /tmp/JavaDexByteCode.dex .
(Replace <your-min-sdk-of-your-classes> with the minimal sdk version you used in step 1.)
7. gzip the output:
gzip /tmp/JavaDexByteCode.dex

View File

@@ -1,58 +0,0 @@
package com.roli.juce;
import android.app.DialogFragment;
import android.content.Intent;
import android.os.Bundle;
public class FragmentOverlay extends DialogFragment
{
@Override
public void onCreate (Bundle state)
{
super.onCreate (state);
cppThis = getArguments ().getLong ("cppThis");
if (cppThis != 0)
onCreateNative (cppThis, state);
}
@Override
public void onStart ()
{
super.onStart ();
if (cppThis != 0)
onStartNative (cppThis);
}
public void onRequestPermissionsResult (int requestCode,
String[] permissions,
int[] grantResults)
{
if (cppThis != 0)
onRequestPermissionsResultNative (cppThis, requestCode,
permissions, grantResults);
}
@Override
public void onActivityResult (int requestCode, int resultCode, Intent data)
{
if (cppThis != 0)
onActivityResultNative (cppThis, requestCode, resultCode, data);
}
public void close ()
{
cppThis = 0;
dismiss ();
}
//==============================================================================
private long cppThis = 0;
private native void onActivityResultNative (long myself, int requestCode, int resultCode, Intent data);
private native void onCreateNative (long myself, Bundle state);
private native void onStartNative (long myself);
private native void onRequestPermissionsResultNative (long myself, int requestCode,
String[] permissions, int[] grantResults);
}

View File

@@ -1,407 +0,0 @@
package com.roli.juce;
import java.lang.Runnable;
import java.io.*;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Callable;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.*;
public class JuceHTTPStream
{
public JuceHTTPStream(String address, boolean isPostToUse, byte[] postDataToUse,
String headersToUse, int timeOutMsToUse,
int[] statusCodeToUse, StringBuffer responseHeadersToUse,
int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException
{
isPost = isPostToUse;
postData = postDataToUse;
headers = headersToUse;
timeOutMs = timeOutMsToUse;
statusCode = statusCodeToUse;
responseHeaders = responseHeadersToUse;
totalLength = -1;
numRedirectsToFollow = numRedirectsToFollowToUse;
httpRequestCmd = httpRequestCmdToUse;
connection = createConnection(address, isPost, postData, headers, timeOutMs, httpRequestCmd);
}
public static final JuceHTTPStream createHTTPStream(String address, boolean isPost, byte[] postData,
String headers, int timeOutMs, int[] statusCode,
StringBuffer responseHeaders, int numRedirectsToFollow,
String httpRequestCmd)
{
// timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL)
if (timeOutMs < 0)
timeOutMs = 0;
else if (timeOutMs == 0)
timeOutMs = 30000;
for (; ; )
{
try
{
JuceHTTPStream httpStream = new JuceHTTPStream(address, isPost, postData, headers,
timeOutMs, statusCode, responseHeaders,
numRedirectsToFollow, httpRequestCmd);
return httpStream;
} catch (Throwable e)
{
}
return null;
}
}
private final HttpURLConnection createConnection(String address, boolean isPost, byte[] postData,
String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException
{
HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection());
try
{
newConnection.setInstanceFollowRedirects(false);
newConnection.setConnectTimeout(timeOutMs);
newConnection.setReadTimeout(timeOutMs);
// headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines.
// So convert headers string to an array, with an element for each line
String headerLines[] = headers.split("\\n");
// Set request headers
for (int i = 0; i < headerLines.length; ++i)
{
int pos = headerLines[i].indexOf(":");
if (pos > 0 && pos < headerLines[i].length())
{
String field = headerLines[i].substring(0, pos);
String value = headerLines[i].substring(pos + 1);
if (value.length() > 0)
newConnection.setRequestProperty(field, value);
}
}
newConnection.setRequestMethod(httpRequestCmd);
if (isPost)
{
newConnection.setDoOutput(true);
if (postData != null)
{
OutputStream out = newConnection.getOutputStream();
out.write(postData);
out.flush();
}
}
return newConnection;
} catch (Throwable e)
{
newConnection.disconnect();
throw new IOException("Connection error");
}
}
private final InputStream getCancellableStream(final boolean isInput) throws ExecutionException
{
synchronized (createFutureLock)
{
if (hasBeenCancelled.get())
return null;
streamFuture = executor.submit(new Callable<BufferedInputStream>()
{
@Override
public BufferedInputStream call() throws IOException
{
return new BufferedInputStream(isInput ? connection.getInputStream()
: connection.getErrorStream());
}
});
}
try
{
return streamFuture.get();
} catch (InterruptedException e)
{
return null;
} catch (CancellationException e)
{
return null;
}
}
public final boolean connect()
{
boolean result = false;
int numFollowedRedirects = 0;
while (true)
{
result = doConnect();
if (!result)
return false;
if (++numFollowedRedirects > numRedirectsToFollow)
break;
int status = statusCode[0];
if (status == 301 || status == 302 || status == 303 || status == 307)
{
// Assumes only one occurrence of "Location"
int pos1 = responseHeaders.indexOf("Location:") + 10;
int pos2 = responseHeaders.indexOf("\n", pos1);
if (pos2 > pos1)
{
String currentLocation = connection.getURL().toString();
String newLocation = responseHeaders.substring(pos1, pos2);
try
{
// Handle newLocation whether it's absolute or relative
URL baseUrl = new URL(currentLocation);
URL newUrl = new URL(baseUrl, newLocation);
String transformedNewLocation = newUrl.toString();
if (transformedNewLocation != currentLocation)
{
// Clear responseHeaders before next iteration
responseHeaders.delete(0, responseHeaders.length());
synchronized (createStreamLock)
{
if (hasBeenCancelled.get())
return false;
connection.disconnect();
try
{
connection = createConnection(transformedNewLocation, isPost,
postData, headers, timeOutMs,
httpRequestCmd);
} catch (Throwable e)
{
return false;
}
}
} else
{
break;
}
} catch (Throwable e)
{
return false;
}
} else
{
break;
}
} else
{
break;
}
}
return result;
}
private final boolean doConnect()
{
synchronized (createStreamLock)
{
if (hasBeenCancelled.get())
return false;
try
{
try
{
inputStream = getCancellableStream(true);
} catch (ExecutionException e)
{
if (connection.getResponseCode() < 400)
{
statusCode[0] = connection.getResponseCode();
connection.disconnect();
return false;
}
} finally
{
statusCode[0] = connection.getResponseCode();
}
try
{
if (statusCode[0] >= 400)
inputStream = getCancellableStream(false);
else
inputStream = getCancellableStream(true);
} catch (ExecutionException e)
{
}
for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet())
{
if (entry.getKey() != null && entry.getValue() != null)
{
responseHeaders.append(entry.getKey() + ": "
+ android.text.TextUtils.join(",", entry.getValue()) + "\n");
if (entry.getKey().compareTo("Content-Length") == 0)
totalLength = Integer.decode(entry.getValue().get(0));
}
}
return true;
} catch (IOException e)
{
return false;
}
}
}
static class DisconnectionRunnable implements Runnable
{
public DisconnectionRunnable(HttpURLConnection theConnection,
InputStream theInputStream,
ReentrantLock theCreateStreamLock,
Object theCreateFutureLock,
Future<BufferedInputStream> theStreamFuture)
{
connectionToDisconnect = theConnection;
inputStream = theInputStream;
createStreamLock = theCreateStreamLock;
createFutureLock = theCreateFutureLock;
streamFuture = theStreamFuture;
}
public void run()
{
try
{
if (!createStreamLock.tryLock())
{
synchronized (createFutureLock)
{
if (streamFuture != null)
streamFuture.cancel(true);
}
createStreamLock.lock();
}
if (connectionToDisconnect != null)
connectionToDisconnect.disconnect();
if (inputStream != null)
inputStream.close();
} catch (IOException e)
{
} finally
{
createStreamLock.unlock();
}
}
private HttpURLConnection connectionToDisconnect;
private InputStream inputStream;
private ReentrantLock createStreamLock;
private Object createFutureLock;
Future<BufferedInputStream> streamFuture;
}
public final void release()
{
DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable(connection,
inputStream,
createStreamLock,
createFutureLock,
streamFuture);
synchronized (createStreamLock)
{
hasBeenCancelled.set(true);
connection = null;
}
Thread disconnectionThread = new Thread(disconnectionRunnable);
disconnectionThread.start();
}
public final int read(byte[] buffer, int numBytes)
{
int num = 0;
try
{
synchronized (createStreamLock)
{
if (inputStream != null)
num = inputStream.read(buffer, 0, numBytes);
}
} catch (IOException e)
{
}
if (num > 0)
position += num;
return num;
}
public final long getPosition()
{
return position;
}
public final long getTotalLength()
{
return totalLength;
}
public final boolean isExhausted()
{
return false;
}
public final boolean setPosition(long newPos)
{
return false;
}
private boolean isPost;
private byte[] postData;
private String headers;
private int timeOutMs;
String httpRequestCmd;
private HttpURLConnection connection;
private int[] statusCode;
private StringBuffer responseHeaders;
private int totalLength;
private int numRedirectsToFollow;
private InputStream inputStream;
private long position;
private final ReentrantLock createStreamLock = new ReentrantLock();
private final Object createFutureLock = new Object();
private AtomicBoolean hasBeenCancelled = new AtomicBoolean();
private final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory());
Future<BufferedInputStream> streamFuture;
}