mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-16 00:34:19 +00:00
Android: Moved more Java code into C++
This commit is contained in:
parent
b2db1f48c1
commit
1b7d30f0f4
14 changed files with 623 additions and 433 deletions
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -385,23 +383,6 @@ public class JuceDemo extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -965,6 +946,38 @@ public class JuceDemo extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -1268,36 +1281,6 @@ public class JuceDemo extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -1314,23 +1312,6 @@ public class MidiTest extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -1894,6 +1875,38 @@ public class MidiTest extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -2197,36 +2210,6 @@ public class MidiTest extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -385,23 +383,6 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -965,6 +946,38 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -1268,36 +1281,6 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -385,23 +383,6 @@ public class OSCReceiver extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -965,6 +946,38 @@ public class OSCReceiver extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -1268,36 +1281,6 @@ public class OSCReceiver extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -385,23 +383,6 @@ public class OSCSender extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -965,6 +946,38 @@ public class OSCSender extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -1268,36 +1281,6 @@ public class OSCSender extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -1314,23 +1312,6 @@ public class JuceDemoPlugin extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -1894,6 +1875,38 @@ public class JuceDemoPlugin extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -2197,36 +2210,6 @@ public class JuceDemoPlugin extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -1314,23 +1312,6 @@ public class AudioPerformanceTest extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -1894,6 +1875,38 @@ public class AudioPerformanceTest extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -2197,36 +2210,6 @@ public class AudioPerformanceTest extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.Manifest;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
|
@ -302,23 +300,6 @@ public class JuceAppActivity extends Activity
|
|||
private native void resumeApp();
|
||||
private native void setScreenSize (int screenWidth, int screenHeight, int dpi);
|
||||
|
||||
//==============================================================================
|
||||
public native void deliverMessage (long value);
|
||||
private android.os.Handler messageHandler = new android.os.Handler();
|
||||
|
||||
public final void postMessage (long value)
|
||||
{
|
||||
messageHandler.post (new MessageCallback (value));
|
||||
}
|
||||
|
||||
private final class MessageCallback implements Runnable
|
||||
{
|
||||
public MessageCallback (long value_) { value = value_; }
|
||||
public final void run() { deliverMessage (value); }
|
||||
|
||||
private long value;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private ViewHolder viewHolder;
|
||||
private MidiDeviceManager midiDeviceManager = null;
|
||||
|
|
@ -882,6 +863,38 @@ public class JuceAppActivity extends Activity
|
|||
|
||||
private int[] cachedRenderArray = new int [256];
|
||||
|
||||
//==============================================================================
|
||||
public static class NativeInvocationHandler implements InvocationHandler
|
||||
{
|
||||
public NativeInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
nativeContext = nativeContextRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize()
|
||||
{
|
||||
dispatchFinalize (nativeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
return dispatchInvoke (nativeContext, proxy, method, args);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
private long nativeContext = 0;
|
||||
|
||||
private native void dispatchFinalize (long nativeContextRef);
|
||||
private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);
|
||||
}
|
||||
|
||||
public static InvocationHandler createInvocationHandler (long nativeContextRef)
|
||||
{
|
||||
return new NativeInvocationHandler (nativeContextRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public static class HTTPStream
|
||||
{
|
||||
|
|
@ -1185,36 +1198,6 @@ public class JuceAppActivity extends Activity
|
|||
public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }
|
||||
|
||||
//==============================================================================
|
||||
private final class SingleMediaScanner implements MediaScannerConnectionClient
|
||||
{
|
||||
public SingleMediaScanner (Context context, String filename)
|
||||
{
|
||||
file = filename;
|
||||
msc = new MediaScannerConnection (context, this);
|
||||
msc.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaScannerConnected()
|
||||
{
|
||||
msc.scanFile (file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted (String path, Uri uri)
|
||||
{
|
||||
msc.disconnect();
|
||||
}
|
||||
|
||||
private MediaScannerConnection msc;
|
||||
private String file;
|
||||
}
|
||||
|
||||
public final void scanFile (String filename)
|
||||
{
|
||||
new SingleMediaScanner (this, filename);
|
||||
}
|
||||
|
||||
public final Typeface getTypeFaceFromAsset (String assetName)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -20,6 +20,46 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "(Landroid/content/Context;Landroid/media/MediaScannerConnection$MediaScannerConnectionClient;)V") \
|
||||
METHOD (connect, "connect", "()V") \
|
||||
METHOD (disconnect, "disconnect", "()V") \
|
||||
METHOD (scanFile, "scanFile", "(Ljava/lang/String;Ljava/lang/String;)V") \
|
||||
|
||||
DECLARE_JNI_CLASS (MediaScannerConnection, "android/media/MediaScannerConnection");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
//==============================================================================
|
||||
class MediaScannerConnectionClient : public AndroidInterfaceImplementer
|
||||
{
|
||||
public:
|
||||
virtual void onMediaScannerConnected() = 0;
|
||||
virtual void onScanCompleted() = 0;
|
||||
|
||||
private:
|
||||
jobject invoke (jobject proxy, jobject method, jobjectArray args) override
|
||||
{
|
||||
auto* env = getEnv();
|
||||
|
||||
auto methodName = juceString ((jstring) env->CallObjectMethod (method, Method.getName));
|
||||
|
||||
if (methodName == "onMediaScannerConnected")
|
||||
{
|
||||
onMediaScannerConnected();
|
||||
return nullptr;
|
||||
}
|
||||
else if (methodName == "onScanCompleted")
|
||||
{
|
||||
onScanCompleted();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return AndroidInterfaceImplementer::invoke (proxy, method, args);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
bool File::isOnCDRomDrive() const
|
||||
{
|
||||
return false;
|
||||
|
|
@ -100,3 +140,49 @@ JUCE_API bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const
|
|||
void File::revealToUser() const
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class SingleMediaScanner : public MediaScannerConnectionClient
|
||||
{
|
||||
public:
|
||||
SingleMediaScanner (const String& filename)
|
||||
: msc (getEnv()->NewObject (MediaScannerConnection,
|
||||
MediaScannerConnection.constructor,
|
||||
android.activity.get(),
|
||||
CreateJavaInterface (this, "android/media/MediaScannerConnection$MediaScannerConnectionClient").get())),
|
||||
file (filename)
|
||||
{
|
||||
getEnv()->CallVoidMethod (msc.get(), MediaScannerConnection.connect);
|
||||
}
|
||||
|
||||
void onMediaScannerConnected() override
|
||||
{
|
||||
auto* env = getEnv();
|
||||
|
||||
env->CallVoidMethod (msc.get(), MediaScannerConnection.scanFile, javaString (file).get(), 0);
|
||||
}
|
||||
|
||||
void onScanCompleted() override
|
||||
{
|
||||
getEnv()->CallVoidMethod (msc.get(), MediaScannerConnection.disconnect);
|
||||
}
|
||||
|
||||
private:
|
||||
GlobalRef msc;
|
||||
String file;
|
||||
};
|
||||
|
||||
void FileOutputStream::flushInternal()
|
||||
{
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
if (fsync (getFD (fileHandle)) == -1)
|
||||
status = getResultForErrno();
|
||||
|
||||
// This stuff tells the OS to asynchronously update the metadata
|
||||
// that the OS has cached aboud the file - this metadata is used
|
||||
// when the device is acting as a USB drive, and unless it's explicitly
|
||||
// refreshed, it'll get out of step with the real file.
|
||||
new SingleMediaScanner (file.getFullPathName());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,10 +40,11 @@ extern JNIEnv* attachAndroidJNI() noexcept;
|
|||
class GlobalRef
|
||||
{
|
||||
public:
|
||||
inline GlobalRef() noexcept : obj (0) {}
|
||||
inline explicit GlobalRef (jobject o) : obj (retain (o)) {}
|
||||
inline GlobalRef (const GlobalRef& other) : obj (retain (other.obj)) {}
|
||||
~GlobalRef() { clear(); }
|
||||
inline GlobalRef() noexcept : obj (0) {}
|
||||
inline explicit GlobalRef (jobject o) : obj (retain (o)) {}
|
||||
inline GlobalRef (const GlobalRef& other) : obj (retain (other.obj)) {}
|
||||
inline GlobalRef (GlobalRef && other) noexcept : obj (0) { std::swap (other.obj, obj); }
|
||||
~GlobalRef() { clear(); }
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
|
|
@ -62,6 +63,14 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline GlobalRef& operator= (GlobalRef&& other)
|
||||
{
|
||||
clear();
|
||||
std::swap (obj, other.obj);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
inline operator jobject() const noexcept { return obj; }
|
||||
inline jobject get() const noexcept { return obj; }
|
||||
|
|
@ -98,7 +107,7 @@ public:
|
|||
|
||||
private:
|
||||
//==============================================================================
|
||||
jobject obj;
|
||||
jobject obj = 0;
|
||||
|
||||
static inline jobject retain (jobject obj)
|
||||
{
|
||||
|
|
@ -111,14 +120,19 @@ template <typename JavaType>
|
|||
class LocalRef
|
||||
{
|
||||
public:
|
||||
explicit inline LocalRef () noexcept : obj (0) {}
|
||||
explicit inline LocalRef (JavaType o) noexcept : obj (o) {}
|
||||
inline LocalRef (const LocalRef& other) noexcept : obj (retain (other.obj)) {}
|
||||
inline LocalRef (LocalRef&& other) noexcept : obj (0) { std::swap (obj, other.obj); }
|
||||
~LocalRef() { clear(); }
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (obj != 0)
|
||||
{
|
||||
getEnv()->DeleteLocalRef (obj);
|
||||
obj = 0;
|
||||
}
|
||||
}
|
||||
|
||||
LocalRef& operator= (const LocalRef& other)
|
||||
|
|
@ -129,6 +143,13 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
LocalRef& operator= (LocalRef&& other)
|
||||
{
|
||||
clear();
|
||||
std::swap (other.obj, obj);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator JavaType() const noexcept { return obj; }
|
||||
inline JavaType get() const noexcept { return obj; }
|
||||
|
||||
|
|
@ -261,7 +282,6 @@ extern AndroidSystem android;
|
|||
METHOD (createNewView, "createNewView", "(ZJ)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;") \
|
||||
METHOD (deleteView, "deleteView", "(L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;)V") \
|
||||
METHOD (createNativeSurfaceView, "createNativeSurfaceView", "(J)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$NativeSurfaceView;") \
|
||||
METHOD (postMessage, "postMessage", "(J)V") \
|
||||
METHOD (finish, "finish", "()V") \
|
||||
METHOD (setRequestedOrientation,"setRequestedOrientation", "(I)V") \
|
||||
METHOD (getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \
|
||||
|
|
@ -279,7 +299,6 @@ extern AndroidSystem android;
|
|||
STATICMETHOD (getMusicFolder, "getMusicFolder", "()Ljava/lang/String;") \
|
||||
STATICMETHOD (getDownloadsFolder, "getDownloadsFolder", "()Ljava/lang/String;") \
|
||||
STATICMETHOD (getMoviesFolder, "getMoviesFolder", "()Ljava/lang/String;") \
|
||||
METHOD (scanFile, "scanFile", "(Ljava/lang/String;)V") \
|
||||
METHOD (getTypeFaceFromAsset, "getTypeFaceFromAsset", "(Ljava/lang/String;)Landroid/graphics/Typeface;") \
|
||||
METHOD (getTypeFaceFromByteArray,"getTypeFaceFromByteArray","([B)Landroid/graphics/Typeface;") \
|
||||
METHOD (setScreenSaver, "setScreenSaver", "(Z)V") \
|
||||
|
|
@ -293,6 +312,7 @@ extern AndroidSystem android;
|
|||
METHOD (isPermissionGranted, "isPermissionGranted", "(I)Z" ) \
|
||||
METHOD (isPermissionDeclaredInManifest, "isPermissionDeclaredInManifest", "(I)Z" ) \
|
||||
METHOD (getSystemService, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;") \
|
||||
STATICMETHOD (createInvocationHandler, "createInvocationHandler", "(J)Ljava/lang/reflect/InvocationHandler;") \
|
||||
|
||||
DECLARE_JNI_CLASS (JuceAppActivity, JUCE_ANDROID_ACTIVITY_CLASSPATH);
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
|
@ -332,3 +352,76 @@ DECLARE_JNI_CLASS (Matrix, "android/graphics/Matrix");
|
|||
|
||||
DECLARE_JNI_CLASS (RectClass, "android/graphics/Rect");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (getName, "getName", "()Ljava/lang/String;") \
|
||||
METHOD (getModifiers, "getModifiers", "()I") \
|
||||
METHOD (getParameterTypes, "getParameterTypes", "()[Ljava/lang/Class;") \
|
||||
METHOD (getReturnType, "getReturnType", "()Ljava/lang/Class;") \
|
||||
METHOD (invoke, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;") \
|
||||
METHOD (hashCode, "hashCode", "()I") \
|
||||
METHOD (equals, "equals", "(Ljava/lang/Object;)Z") \
|
||||
|
||||
DECLARE_JNI_CLASS (Method, "java/lang/reflect/Method");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (getName, "getName", "()Ljava/lang/String;") \
|
||||
METHOD (getModifiers, "getModifiers", "()I") \
|
||||
METHOD (isAnnotation, "isAnnotation", "()Z") \
|
||||
METHOD (isAnonymousClass, "isAnonymousClass", "()Z") \
|
||||
METHOD (isArray, "isArray", "()Z") \
|
||||
METHOD (isEnum, "isEnum", "()Z") \
|
||||
METHOD (isInterface, "isInterface", "()Z") \
|
||||
METHOD (isLocalClass, "isLocalClass", "()Z") \
|
||||
METHOD (isMemberClass, "isMemberClass", "()Z") \
|
||||
METHOD (isPrimitive, "isPrimitive", "()Z") \
|
||||
METHOD (isSynthetic, "isSynthetic", "()Z") \
|
||||
METHOD (getComponentType, "getComponentType", "()Ljava/lang/Class;") \
|
||||
METHOD (getSuperclass, "getSuperclass", "()Ljava/lang/Class;") \
|
||||
METHOD (getClassLoader, "getClassLoader", "()Ljava/lang/ClassLoader;") \
|
||||
|
||||
DECLARE_JNI_CLASS (JavaClass, "java/lang/Class");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "()V") \
|
||||
|
||||
DECLARE_JNI_CLASS (JavaObject, "java/lang/Object");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class AndroidInterfaceImplementer;
|
||||
|
||||
// This function takes ownership of the implementer. When the returned GlobalRef
|
||||
// goes out of scope (and no other Java routine has a reference on the return-value)
|
||||
// then the implementer will be deleted as well.
|
||||
LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
|
||||
const StringArray& interfaceNames,
|
||||
LocalRef<jobject> subclass);
|
||||
|
||||
//==============================================================================
|
||||
jobject juce_invokeImplementer (JNIEnv*, jlong, jobject, jobject, jobjectArray);
|
||||
void juce_dispatchDelete (JNIEnv*, jlong);
|
||||
|
||||
//==============================================================================
|
||||
class AndroidInterfaceImplementer
|
||||
{
|
||||
protected:
|
||||
virtual ~AndroidInterfaceImplementer() {}
|
||||
virtual jobject invoke (jobject proxy, jobject method, jobjectArray args);
|
||||
|
||||
//==============================================================================
|
||||
friend LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer*, const StringArray&, LocalRef<jobject>);
|
||||
friend jobject juce_invokeImplementer (JNIEnv*, jlong, jobject, jobject, jobjectArray);
|
||||
friend void juce_dispatchDelete (JNIEnv*, jlong);
|
||||
private:
|
||||
GlobalRef javaSubClass;
|
||||
};
|
||||
|
||||
LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
|
||||
const StringArray& interfaceNames);
|
||||
LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
|
||||
const String& interfaceName);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (newProxyInstance, "newProxyInstance", "(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;") \
|
||||
|
||||
DECLARE_JNI_CLASS (JavaProxy, "java/lang/reflect/Proxy");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
JNIClassBase::JNIClassBase (const char* cp) : classPath (cp), classRef (0)
|
||||
{
|
||||
getClasses().add (this);
|
||||
|
|
@ -91,6 +98,92 @@ jfieldID JNIClassBase::resolveStaticField (JNIEnv* env, const char* fieldName, c
|
|||
return f;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
|
||||
const StringArray& interfaceNames,
|
||||
LocalRef<jobject> subclass)
|
||||
{
|
||||
auto* env = getEnv();
|
||||
|
||||
implementer->javaSubClass = GlobalRef (subclass);
|
||||
|
||||
// you need to override at least one interface
|
||||
jassert (interfaceNames.size() > 0);
|
||||
|
||||
auto classArray = LocalRef<jobject> (env->NewObjectArray (interfaceNames.size(), JavaClass, nullptr));
|
||||
LocalRef<jobject> classLoader;
|
||||
|
||||
for (auto i = 0; i < interfaceNames.size(); ++i)
|
||||
{
|
||||
auto aClass = LocalRef<jobject> (env->FindClass (interfaceNames[i].toRawUTF8()));
|
||||
|
||||
if (aClass != nullptr)
|
||||
{
|
||||
if (i == 0)
|
||||
classLoader = LocalRef<jobject> (env->CallObjectMethod (aClass, JavaClass.getClassLoader));
|
||||
|
||||
env->SetObjectArrayElement ((jobjectArray) classArray.get(), i, aClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// interface class not found
|
||||
jassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
auto invocationHandler = LocalRef<jobject> (env->CallStaticObjectMethod (JuceAppActivity,
|
||||
JuceAppActivity.createInvocationHandler,
|
||||
reinterpret_cast<jlong> (implementer)));
|
||||
|
||||
return LocalRef<jobject> (env->CallStaticObjectMethod (JavaProxy, JavaProxy.newProxyInstance,
|
||||
classLoader.get(), classArray.get(),
|
||||
invocationHandler.get()));
|
||||
}
|
||||
|
||||
LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
|
||||
const StringArray& interfaceNames)
|
||||
{
|
||||
return CreateJavaInterface (implementer, interfaceNames,
|
||||
LocalRef<jobject> (getEnv()->NewObject (JavaObject,
|
||||
JavaObject.constructor)));
|
||||
}
|
||||
|
||||
LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
|
||||
const String& interfaceName)
|
||||
{
|
||||
return CreateJavaInterface (implementer, StringArray (interfaceName));
|
||||
}
|
||||
|
||||
jobject AndroidInterfaceImplementer::invoke (jobject /*proxy*/, jobject method, jobjectArray args)
|
||||
{
|
||||
auto* env = getEnv();
|
||||
return env->CallObjectMethod (method, Method.invoke, javaSubClass.get(), args);
|
||||
}
|
||||
|
||||
jobject juce_invokeImplementer (JNIEnv* env, jlong thisPtr, jobject proxy, jobject method, jobjectArray args)
|
||||
{
|
||||
setEnv (env);
|
||||
return reinterpret_cast<AndroidInterfaceImplementer*> (thisPtr)->invoke (proxy, method, args);
|
||||
}
|
||||
|
||||
void juce_dispatchDelete (JNIEnv* env, jlong thisPtr)
|
||||
{
|
||||
setEnv (env);
|
||||
delete reinterpret_cast<AndroidInterfaceImplementer*> (thisPtr);
|
||||
}
|
||||
|
||||
JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024NativeInvocationHandler), dispatchInvoke,
|
||||
jobject, (JNIEnv* env, jobject /*object*/, jlong thisPtr, jobject proxy, jobject method, jobjectArray args))
|
||||
{
|
||||
return juce_invokeImplementer (env, thisPtr, proxy, method, args);
|
||||
}
|
||||
|
||||
JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024NativeInvocationHandler), dispatchFinalize,
|
||||
void, (JNIEnv* env, jobject /*object*/, jlong thisPtr))
|
||||
{
|
||||
juce_dispatchDelete (env, thisPtr);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
JavaVM* androidJNIJavaVM = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -554,23 +554,13 @@ ssize_t FileOutputStream::writeInternal (const void* const data, const size_t nu
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifndef JUCE_ANDROID
|
||||
void FileOutputStream::flushInternal()
|
||||
{
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
if (fsync (getFD (fileHandle)) == -1)
|
||||
status = getResultForErrno();
|
||||
|
||||
#if JUCE_ANDROID
|
||||
// This stuff tells the OS to asynchronously update the metadata
|
||||
// that the OS has cached aboud the file - this metadata is used
|
||||
// when the device is acting as a USB drive, and unless it's explicitly
|
||||
// refreshed, it'll get out of step with the real file.
|
||||
const LocalRef<jstring> t (javaString (file.getFullPathName()));
|
||||
android.activity.callVoidMethod (JuceAppActivity.scanFile, t.get());
|
||||
#endif
|
||||
}
|
||||
if (fileHandle != 0 && fsync (getFD (fileHandle)) == -1)
|
||||
status = getResultForErrno();
|
||||
}
|
||||
#endif
|
||||
|
||||
Result FileOutputStream::truncate()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,8 +20,61 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
void MessageManager::doPlatformSpecificInitialisation() {}
|
||||
void MessageManager::doPlatformSpecificShutdown() {}
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "()V") \
|
||||
METHOD (post, "post", "(Ljava/lang/Runnable;)Z") \
|
||||
|
||||
DECLARE_JNI_CLASS (JNIHandler, "android/os/Handler");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
|
||||
//==============================================================================
|
||||
namespace Android
|
||||
{
|
||||
class Runnable : public juce::AndroidInterfaceImplementer
|
||||
{
|
||||
public:
|
||||
virtual void run() = 0;
|
||||
|
||||
private:
|
||||
jobject invoke (jobject proxy, jobject method, jobjectArray args) override
|
||||
{
|
||||
auto* env = getEnv();
|
||||
auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, Method.getName));
|
||||
|
||||
if (methodName == "run")
|
||||
{
|
||||
run();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// invoke base class
|
||||
return AndroidInterfaceImplementer::invoke (proxy, method, args);
|
||||
}
|
||||
};
|
||||
|
||||
struct Handler
|
||||
{
|
||||
juce_DeclareSingleton (Handler, false)
|
||||
|
||||
Handler() : nativeHandler (getEnv()->NewObject (JNIHandler, JNIHandler.constructor)) {}
|
||||
|
||||
bool post (Runnable* runnable)
|
||||
{
|
||||
return (getEnv()->CallBooleanMethod (nativeHandler.get(), JNIHandler.post,
|
||||
CreateJavaInterface (runnable, "java/lang/Runnable").get()) != 0);
|
||||
}
|
||||
|
||||
GlobalRef nativeHandler;
|
||||
};
|
||||
|
||||
juce_ImplementSingleton (Handler);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::doPlatformSpecificInitialisation() { Android::Handler::getInstance(); }
|
||||
void MessageManager::doPlatformSpecificShutdown() {}
|
||||
|
||||
//==============================================================================
|
||||
bool MessageManager::dispatchNextMessageOnSystemQueue (const bool)
|
||||
|
|
@ -33,26 +86,37 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
struct AndroidMessageCallback : public Android::Runnable
|
||||
{
|
||||
AndroidMessageCallback (const MessageManager::MessageBase::Ptr& messageToDeliver)
|
||||
: message (messageToDeliver)
|
||||
{}
|
||||
|
||||
AndroidMessageCallback (MessageManager::MessageBase::Ptr && messageToDeliver)
|
||||
: message (static_cast<MessageManager::MessageBase::Ptr&&> (messageToDeliver))
|
||||
{}
|
||||
|
||||
void run() override
|
||||
{
|
||||
JUCE_TRY
|
||||
{
|
||||
message->messageCallback();
|
||||
|
||||
// delete the message already here as Java will only run the
|
||||
// destructor of this runnable the next time the garbage
|
||||
// collector kicks in.
|
||||
message = nullptr;
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
}
|
||||
|
||||
MessageManager::MessageBase::Ptr message;
|
||||
};
|
||||
|
||||
bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
|
||||
{
|
||||
message->incReferenceCount();
|
||||
android.activity.callVoidMethod (JuceAppActivity.postMessage, (jlong) (pointer_sized_uint) message);
|
||||
return true;
|
||||
return Android::Handler::getInstance()->post (new AndroidMessageCallback (message));
|
||||
}
|
||||
|
||||
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (JNIEnv* env, jobject, jlong value))
|
||||
{
|
||||
setEnv (env);
|
||||
|
||||
JUCE_TRY
|
||||
{
|
||||
MessageManager::MessageBase* const message = (MessageManager::MessageBase*) (pointer_sized_uint) value;
|
||||
message->messageCallback();
|
||||
message->decReferenceCount();
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::broadcastMessage (const String&)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ char OnlineUnlockStatus::MachineIDUtilities::getPlatformPrefix()
|
|||
|
||||
String OnlineUnlockStatus::MachineIDUtilities::getEncodedIDString (const String& input)
|
||||
{
|
||||
const String platform (String::charToString (getPlatformPrefix()));
|
||||
const String platform (String::charToString (static_cast<juce_wchar> (getPlatformPrefix())));
|
||||
|
||||
return platform + MD5 ((input + "salt_1" + platform).toUTF8())
|
||||
.toHexString().substring (0, 9).toUpperCase();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue