| @@ -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) | |||
| } | |||
| //============================================================================== | |||
| bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) | |||
| struct AndroidMessageCallback : public Android::Runnable | |||
| { | |||
| message->incReferenceCount(); | |||
| android.activity.callVoidMethod (JuceAppActivity.postMessage, (jlong) (pointer_sized_uint) message); | |||
| return true; | |||
| } | |||
| AndroidMessageCallback (const MessageManager::MessageBase::Ptr& messageToDeliver) | |||
| : message (messageToDeliver) | |||
| {} | |||
| JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (JNIEnv* env, jobject, jlong value)) | |||
| { | |||
| setEnv (env); | |||
| AndroidMessageCallback (MessageManager::MessageBase::Ptr && messageToDeliver) | |||
| : message (static_cast<MessageManager::MessageBase::Ptr&&> (messageToDeliver)) | |||
| {} | |||
| JUCE_TRY | |||
| void run() override | |||
| { | |||
| MessageManager::MessageBase* const message = (MessageManager::MessageBase*) (pointer_sized_uint) value; | |||
| message->messageCallback(); | |||
| message->decReferenceCount(); | |||
| 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 | |||
| } | |||
| JUCE_CATCH_EXCEPTION | |||
| } | |||
| MessageManager::MessageBase::Ptr message; | |||
| }; | |||
| bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) | |||
| { | |||
| return Android::Handler::getInstance()->post (new AndroidMessageCallback (message)); | |||
| } | |||
| //============================================================================== | |||
| 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(); | |||