| @@ -1,58 +1,58 @@ | |||
| package com.roli.juce; | |||
| import android.app.DialogFragment; | |||
| import android.content.Intent; | |||
| import android.os.Bundle; | |||
| public class FragmentOverlay extends DialogFragment | |||
| { | |||
| @Override | |||
| public void onCreate (Bundle state) | |||
| { | |||
| super.onCreate (state); | |||
| cppThis = getArguments ().getLong ("cppThis"); | |||
| if (cppThis != 0) | |||
| onCreateNative (cppThis, state); | |||
| } | |||
| @Override | |||
| public void onStart () | |||
| { | |||
| super.onStart (); | |||
| if (cppThis != 0) | |||
| onStartNative (cppThis); | |||
| } | |||
| public void onRequestPermissionsResult (int requestCode, | |||
| String[] permissions, | |||
| int[] grantResults) | |||
| { | |||
| if (cppThis != 0) | |||
| onRequestPermissionsResultNative (cppThis, requestCode, | |||
| permissions, grantResults); | |||
| } | |||
| @Override | |||
| public void onActivityResult (int requestCode, int resultCode, Intent data) | |||
| { | |||
| if (cppThis != 0) | |||
| onActivityResultNative (cppThis, requestCode, resultCode, data); | |||
| } | |||
| public void close () | |||
| { | |||
| cppThis = 0; | |||
| dismiss (); | |||
| } | |||
| //============================================================================== | |||
| private long cppThis = 0; | |||
| private native void onActivityResultNative (long myself, int requestCode, int resultCode, Intent data); | |||
| private native void onCreateNative (long myself, Bundle state); | |||
| private native void onStartNative (long myself); | |||
| private native void onRequestPermissionsResultNative (long myself, int requestCode, | |||
| String[] permissions, int[] grantResults); | |||
| } | |||
| package com.roli.juce; | |||
| import android.app.DialogFragment; | |||
| import android.content.Intent; | |||
| import android.os.Bundle; | |||
| public class FragmentOverlay extends DialogFragment | |||
| { | |||
| @Override | |||
| public void onCreate (Bundle state) | |||
| { | |||
| super.onCreate (state); | |||
| cppThis = getArguments ().getLong ("cppThis"); | |||
| if (cppThis != 0) | |||
| onCreateNative (cppThis, state); | |||
| } | |||
| @Override | |||
| public void onStart () | |||
| { | |||
| super.onStart (); | |||
| if (cppThis != 0) | |||
| onStartNative (cppThis); | |||
| } | |||
| public void onRequestPermissionsResult (int requestCode, | |||
| String[] permissions, | |||
| int[] grantResults) | |||
| { | |||
| if (cppThis != 0) | |||
| onRequestPermissionsResultNative (cppThis, requestCode, | |||
| permissions, grantResults); | |||
| } | |||
| @Override | |||
| public void onActivityResult (int requestCode, int resultCode, Intent data) | |||
| { | |||
| if (cppThis != 0) | |||
| onActivityResultNative (cppThis, requestCode, resultCode, data); | |||
| } | |||
| public void close () | |||
| { | |||
| cppThis = 0; | |||
| dismiss (); | |||
| } | |||
| //============================================================================== | |||
| private long cppThis = 0; | |||
| private native void onActivityResultNative (long myself, int requestCode, int resultCode, Intent data); | |||
| private native void onCreateNative (long myself, Bundle state); | |||
| private native void onStartNative (long myself); | |||
| private native void onRequestPermissionsResultNative (long myself, int requestCode, | |||
| String[] permissions, int[] grantResults); | |||
| } | |||
| @@ -1,407 +1,407 @@ | |||
| package com.roli.juce; | |||
| import java.lang.Runnable; | |||
| import java.io.*; | |||
| import java.net.URL; | |||
| import java.net.HttpURLConnection; | |||
| import java.util.concurrent.CancellationException; | |||
| import java.util.concurrent.Future; | |||
| import java.util.concurrent.Executors; | |||
| import java.util.concurrent.ExecutorService; | |||
| import java.util.concurrent.ExecutionException; | |||
| import java.util.concurrent.Callable; | |||
| import java.util.concurrent.locks.ReentrantLock; | |||
| import java.util.concurrent.atomic.*; | |||
| public class JuceHTTPStream | |||
| { | |||
| public JuceHTTPStream(String address, boolean isPostToUse, byte[] postDataToUse, | |||
| String headersToUse, int timeOutMsToUse, | |||
| int[] statusCodeToUse, StringBuffer responseHeadersToUse, | |||
| int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException | |||
| { | |||
| isPost = isPostToUse; | |||
| postData = postDataToUse; | |||
| headers = headersToUse; | |||
| timeOutMs = timeOutMsToUse; | |||
| statusCode = statusCodeToUse; | |||
| responseHeaders = responseHeadersToUse; | |||
| totalLength = -1; | |||
| numRedirectsToFollow = numRedirectsToFollowToUse; | |||
| httpRequestCmd = httpRequestCmdToUse; | |||
| connection = createConnection(address, isPost, postData, headers, timeOutMs, httpRequestCmd); | |||
| } | |||
| public static final JuceHTTPStream createHTTPStream(String address, boolean isPost, byte[] postData, | |||
| String headers, int timeOutMs, int[] statusCode, | |||
| StringBuffer responseHeaders, int numRedirectsToFollow, | |||
| String httpRequestCmd) | |||
| { | |||
| // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL) | |||
| if (timeOutMs < 0) | |||
| timeOutMs = 0; | |||
| else if (timeOutMs == 0) | |||
| timeOutMs = 30000; | |||
| for (; ; ) | |||
| { | |||
| try | |||
| { | |||
| JuceHTTPStream httpStream = new JuceHTTPStream(address, isPost, postData, headers, | |||
| timeOutMs, statusCode, responseHeaders, | |||
| numRedirectsToFollow, httpRequestCmd); | |||
| return httpStream; | |||
| } catch (Throwable e) | |||
| { | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| private final HttpURLConnection createConnection(String address, boolean isPost, byte[] postData, | |||
| String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException | |||
| { | |||
| HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection()); | |||
| try | |||
| { | |||
| newConnection.setInstanceFollowRedirects(false); | |||
| newConnection.setConnectTimeout(timeOutMs); | |||
| newConnection.setReadTimeout(timeOutMs); | |||
| // headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines. | |||
| // So convert headers string to an array, with an element for each line | |||
| String headerLines[] = headers.split("\\n"); | |||
| // Set request headers | |||
| for (int i = 0; i < headerLines.length; ++i) | |||
| { | |||
| int pos = headerLines[i].indexOf(":"); | |||
| if (pos > 0 && pos < headerLines[i].length()) | |||
| { | |||
| String field = headerLines[i].substring(0, pos); | |||
| String value = headerLines[i].substring(pos + 1); | |||
| if (value.length() > 0) | |||
| newConnection.setRequestProperty(field, value); | |||
| } | |||
| } | |||
| newConnection.setRequestMethod(httpRequestCmd); | |||
| if (isPost) | |||
| { | |||
| newConnection.setDoOutput(true); | |||
| if (postData != null) | |||
| { | |||
| OutputStream out = newConnection.getOutputStream(); | |||
| out.write(postData); | |||
| out.flush(); | |||
| } | |||
| } | |||
| return newConnection; | |||
| } catch (Throwable e) | |||
| { | |||
| newConnection.disconnect(); | |||
| throw new IOException("Connection error"); | |||
| } | |||
| } | |||
| private final InputStream getCancellableStream(final boolean isInput) throws ExecutionException | |||
| { | |||
| synchronized (createFutureLock) | |||
| { | |||
| if (hasBeenCancelled.get()) | |||
| return null; | |||
| streamFuture = executor.submit(new Callable<BufferedInputStream>() | |||
| { | |||
| @Override | |||
| public BufferedInputStream call() throws IOException | |||
| { | |||
| return new BufferedInputStream(isInput ? connection.getInputStream() | |||
| : connection.getErrorStream()); | |||
| } | |||
| }); | |||
| } | |||
| try | |||
| { | |||
| return streamFuture.get(); | |||
| } catch (InterruptedException e) | |||
| { | |||
| return null; | |||
| } catch (CancellationException e) | |||
| { | |||
| return null; | |||
| } | |||
| } | |||
| public final boolean connect() | |||
| { | |||
| boolean result = false; | |||
| int numFollowedRedirects = 0; | |||
| while (true) | |||
| { | |||
| result = doConnect(); | |||
| if (!result) | |||
| return false; | |||
| if (++numFollowedRedirects > numRedirectsToFollow) | |||
| break; | |||
| int status = statusCode[0]; | |||
| if (status == 301 || status == 302 || status == 303 || status == 307) | |||
| { | |||
| // Assumes only one occurrence of "Location" | |||
| int pos1 = responseHeaders.indexOf("Location:") + 10; | |||
| int pos2 = responseHeaders.indexOf("\n", pos1); | |||
| if (pos2 > pos1) | |||
| { | |||
| String currentLocation = connection.getURL().toString(); | |||
| String newLocation = responseHeaders.substring(pos1, pos2); | |||
| try | |||
| { | |||
| // Handle newLocation whether it's absolute or relative | |||
| URL baseUrl = new URL(currentLocation); | |||
| URL newUrl = new URL(baseUrl, newLocation); | |||
| String transformedNewLocation = newUrl.toString(); | |||
| if (transformedNewLocation != currentLocation) | |||
| { | |||
| // Clear responseHeaders before next iteration | |||
| responseHeaders.delete(0, responseHeaders.length()); | |||
| synchronized (createStreamLock) | |||
| { | |||
| if (hasBeenCancelled.get()) | |||
| return false; | |||
| connection.disconnect(); | |||
| try | |||
| { | |||
| connection = createConnection(transformedNewLocation, isPost, | |||
| postData, headers, timeOutMs, | |||
| httpRequestCmd); | |||
| } catch (Throwable e) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| } else | |||
| { | |||
| break; | |||
| } | |||
| } catch (Throwable e) | |||
| { | |||
| return false; | |||
| } | |||
| } else | |||
| { | |||
| break; | |||
| } | |||
| } else | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| private final boolean doConnect() | |||
| { | |||
| synchronized (createStreamLock) | |||
| { | |||
| if (hasBeenCancelled.get()) | |||
| return false; | |||
| try | |||
| { | |||
| try | |||
| { | |||
| inputStream = getCancellableStream(true); | |||
| } catch (ExecutionException e) | |||
| { | |||
| if (connection.getResponseCode() < 400) | |||
| { | |||
| statusCode[0] = connection.getResponseCode(); | |||
| connection.disconnect(); | |||
| return false; | |||
| } | |||
| } finally | |||
| { | |||
| statusCode[0] = connection.getResponseCode(); | |||
| } | |||
| try | |||
| { | |||
| if (statusCode[0] >= 400) | |||
| inputStream = getCancellableStream(false); | |||
| else | |||
| inputStream = getCancellableStream(true); | |||
| } catch (ExecutionException e) | |||
| { | |||
| } | |||
| for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet()) | |||
| { | |||
| if (entry.getKey() != null && entry.getValue() != null) | |||
| { | |||
| responseHeaders.append(entry.getKey() + ": " | |||
| + android.text.TextUtils.join(",", entry.getValue()) + "\n"); | |||
| if (entry.getKey().compareTo("Content-Length") == 0) | |||
| totalLength = Integer.decode(entry.getValue().get(0)); | |||
| } | |||
| } | |||
| return true; | |||
| } catch (IOException e) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| } | |||
| static class DisconnectionRunnable implements Runnable | |||
| { | |||
| public DisconnectionRunnable(HttpURLConnection theConnection, | |||
| InputStream theInputStream, | |||
| ReentrantLock theCreateStreamLock, | |||
| Object theCreateFutureLock, | |||
| Future<BufferedInputStream> theStreamFuture) | |||
| { | |||
| connectionToDisconnect = theConnection; | |||
| inputStream = theInputStream; | |||
| createStreamLock = theCreateStreamLock; | |||
| createFutureLock = theCreateFutureLock; | |||
| streamFuture = theStreamFuture; | |||
| } | |||
| public void run() | |||
| { | |||
| try | |||
| { | |||
| if (!createStreamLock.tryLock()) | |||
| { | |||
| synchronized (createFutureLock) | |||
| { | |||
| if (streamFuture != null) | |||
| streamFuture.cancel(true); | |||
| } | |||
| createStreamLock.lock(); | |||
| } | |||
| if (connectionToDisconnect != null) | |||
| connectionToDisconnect.disconnect(); | |||
| if (inputStream != null) | |||
| inputStream.close(); | |||
| } catch (IOException e) | |||
| { | |||
| } finally | |||
| { | |||
| createStreamLock.unlock(); | |||
| } | |||
| } | |||
| private HttpURLConnection connectionToDisconnect; | |||
| private InputStream inputStream; | |||
| private ReentrantLock createStreamLock; | |||
| private Object createFutureLock; | |||
| Future<BufferedInputStream> streamFuture; | |||
| } | |||
| public final void release() | |||
| { | |||
| DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable(connection, | |||
| inputStream, | |||
| createStreamLock, | |||
| createFutureLock, | |||
| streamFuture); | |||
| synchronized (createStreamLock) | |||
| { | |||
| hasBeenCancelled.set(true); | |||
| connection = null; | |||
| } | |||
| Thread disconnectionThread = new Thread(disconnectionRunnable); | |||
| disconnectionThread.start(); | |||
| } | |||
| public final int read(byte[] buffer, int numBytes) | |||
| { | |||
| int num = 0; | |||
| try | |||
| { | |||
| synchronized (createStreamLock) | |||
| { | |||
| if (inputStream != null) | |||
| num = inputStream.read(buffer, 0, numBytes); | |||
| } | |||
| } catch (IOException e) | |||
| { | |||
| } | |||
| if (num > 0) | |||
| position += num; | |||
| return num; | |||
| } | |||
| public final long getPosition() | |||
| { | |||
| return position; | |||
| } | |||
| public final long getTotalLength() | |||
| { | |||
| return totalLength; | |||
| } | |||
| public final boolean isExhausted() | |||
| { | |||
| return false; | |||
| } | |||
| public final boolean setPosition(long newPos) | |||
| { | |||
| return false; | |||
| } | |||
| private boolean isPost; | |||
| private byte[] postData; | |||
| private String headers; | |||
| private int timeOutMs; | |||
| String httpRequestCmd; | |||
| private HttpURLConnection connection; | |||
| private int[] statusCode; | |||
| private StringBuffer responseHeaders; | |||
| private int totalLength; | |||
| private int numRedirectsToFollow; | |||
| private InputStream inputStream; | |||
| private long position; | |||
| private final ReentrantLock createStreamLock = new ReentrantLock(); | |||
| private final Object createFutureLock = new Object(); | |||
| private AtomicBoolean hasBeenCancelled = new AtomicBoolean(); | |||
| private final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory()); | |||
| Future<BufferedInputStream> streamFuture; | |||
| } | |||
| package com.roli.juce; | |||
| import java.lang.Runnable; | |||
| import java.io.*; | |||
| import java.net.URL; | |||
| import java.net.HttpURLConnection; | |||
| import java.util.concurrent.CancellationException; | |||
| import java.util.concurrent.Future; | |||
| import java.util.concurrent.Executors; | |||
| import java.util.concurrent.ExecutorService; | |||
| import java.util.concurrent.ExecutionException; | |||
| import java.util.concurrent.Callable; | |||
| import java.util.concurrent.locks.ReentrantLock; | |||
| import java.util.concurrent.atomic.*; | |||
| public class JuceHTTPStream | |||
| { | |||
| public JuceHTTPStream(String address, boolean isPostToUse, byte[] postDataToUse, | |||
| String headersToUse, int timeOutMsToUse, | |||
| int[] statusCodeToUse, StringBuffer responseHeadersToUse, | |||
| int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException | |||
| { | |||
| isPost = isPostToUse; | |||
| postData = postDataToUse; | |||
| headers = headersToUse; | |||
| timeOutMs = timeOutMsToUse; | |||
| statusCode = statusCodeToUse; | |||
| responseHeaders = responseHeadersToUse; | |||
| totalLength = -1; | |||
| numRedirectsToFollow = numRedirectsToFollowToUse; | |||
| httpRequestCmd = httpRequestCmdToUse; | |||
| connection = createConnection(address, isPost, postData, headers, timeOutMs, httpRequestCmd); | |||
| } | |||
| public static final JuceHTTPStream createHTTPStream(String address, boolean isPost, byte[] postData, | |||
| String headers, int timeOutMs, int[] statusCode, | |||
| StringBuffer responseHeaders, int numRedirectsToFollow, | |||
| String httpRequestCmd) | |||
| { | |||
| // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL) | |||
| if (timeOutMs < 0) | |||
| timeOutMs = 0; | |||
| else if (timeOutMs == 0) | |||
| timeOutMs = 30000; | |||
| for (; ; ) | |||
| { | |||
| try | |||
| { | |||
| JuceHTTPStream httpStream = new JuceHTTPStream(address, isPost, postData, headers, | |||
| timeOutMs, statusCode, responseHeaders, | |||
| numRedirectsToFollow, httpRequestCmd); | |||
| return httpStream; | |||
| } catch (Throwable e) | |||
| { | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| private final HttpURLConnection createConnection(String address, boolean isPost, byte[] postData, | |||
| String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException | |||
| { | |||
| HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection()); | |||
| try | |||
| { | |||
| newConnection.setInstanceFollowRedirects(false); | |||
| newConnection.setConnectTimeout(timeOutMs); | |||
| newConnection.setReadTimeout(timeOutMs); | |||
| // headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines. | |||
| // So convert headers string to an array, with an element for each line | |||
| String headerLines[] = headers.split("\\n"); | |||
| // Set request headers | |||
| for (int i = 0; i < headerLines.length; ++i) | |||
| { | |||
| int pos = headerLines[i].indexOf(":"); | |||
| if (pos > 0 && pos < headerLines[i].length()) | |||
| { | |||
| String field = headerLines[i].substring(0, pos); | |||
| String value = headerLines[i].substring(pos + 1); | |||
| if (value.length() > 0) | |||
| newConnection.setRequestProperty(field, value); | |||
| } | |||
| } | |||
| newConnection.setRequestMethod(httpRequestCmd); | |||
| if (isPost) | |||
| { | |||
| newConnection.setDoOutput(true); | |||
| if (postData != null) | |||
| { | |||
| OutputStream out = newConnection.getOutputStream(); | |||
| out.write(postData); | |||
| out.flush(); | |||
| } | |||
| } | |||
| return newConnection; | |||
| } catch (Throwable e) | |||
| { | |||
| newConnection.disconnect(); | |||
| throw new IOException("Connection error"); | |||
| } | |||
| } | |||
| private final InputStream getCancellableStream(final boolean isInput) throws ExecutionException | |||
| { | |||
| synchronized (createFutureLock) | |||
| { | |||
| if (hasBeenCancelled.get()) | |||
| return null; | |||
| streamFuture = executor.submit(new Callable<BufferedInputStream>() | |||
| { | |||
| @Override | |||
| public BufferedInputStream call() throws IOException | |||
| { | |||
| return new BufferedInputStream(isInput ? connection.getInputStream() | |||
| : connection.getErrorStream()); | |||
| } | |||
| }); | |||
| } | |||
| try | |||
| { | |||
| return streamFuture.get(); | |||
| } catch (InterruptedException e) | |||
| { | |||
| return null; | |||
| } catch (CancellationException e) | |||
| { | |||
| return null; | |||
| } | |||
| } | |||
| public final boolean connect() | |||
| { | |||
| boolean result = false; | |||
| int numFollowedRedirects = 0; | |||
| while (true) | |||
| { | |||
| result = doConnect(); | |||
| if (!result) | |||
| return false; | |||
| if (++numFollowedRedirects > numRedirectsToFollow) | |||
| break; | |||
| int status = statusCode[0]; | |||
| if (status == 301 || status == 302 || status == 303 || status == 307) | |||
| { | |||
| // Assumes only one occurrence of "Location" | |||
| int pos1 = responseHeaders.indexOf("Location:") + 10; | |||
| int pos2 = responseHeaders.indexOf("\n", pos1); | |||
| if (pos2 > pos1) | |||
| { | |||
| String currentLocation = connection.getURL().toString(); | |||
| String newLocation = responseHeaders.substring(pos1, pos2); | |||
| try | |||
| { | |||
| // Handle newLocation whether it's absolute or relative | |||
| URL baseUrl = new URL(currentLocation); | |||
| URL newUrl = new URL(baseUrl, newLocation); | |||
| String transformedNewLocation = newUrl.toString(); | |||
| if (transformedNewLocation != currentLocation) | |||
| { | |||
| // Clear responseHeaders before next iteration | |||
| responseHeaders.delete(0, responseHeaders.length()); | |||
| synchronized (createStreamLock) | |||
| { | |||
| if (hasBeenCancelled.get()) | |||
| return false; | |||
| connection.disconnect(); | |||
| try | |||
| { | |||
| connection = createConnection(transformedNewLocation, isPost, | |||
| postData, headers, timeOutMs, | |||
| httpRequestCmd); | |||
| } catch (Throwable e) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| } else | |||
| { | |||
| break; | |||
| } | |||
| } catch (Throwable e) | |||
| { | |||
| return false; | |||
| } | |||
| } else | |||
| { | |||
| break; | |||
| } | |||
| } else | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| private final boolean doConnect() | |||
| { | |||
| synchronized (createStreamLock) | |||
| { | |||
| if (hasBeenCancelled.get()) | |||
| return false; | |||
| try | |||
| { | |||
| try | |||
| { | |||
| inputStream = getCancellableStream(true); | |||
| } catch (ExecutionException e) | |||
| { | |||
| if (connection.getResponseCode() < 400) | |||
| { | |||
| statusCode[0] = connection.getResponseCode(); | |||
| connection.disconnect(); | |||
| return false; | |||
| } | |||
| } finally | |||
| { | |||
| statusCode[0] = connection.getResponseCode(); | |||
| } | |||
| try | |||
| { | |||
| if (statusCode[0] >= 400) | |||
| inputStream = getCancellableStream(false); | |||
| else | |||
| inputStream = getCancellableStream(true); | |||
| } catch (ExecutionException e) | |||
| { | |||
| } | |||
| for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet()) | |||
| { | |||
| if (entry.getKey() != null && entry.getValue() != null) | |||
| { | |||
| responseHeaders.append(entry.getKey() + ": " | |||
| + android.text.TextUtils.join(",", entry.getValue()) + "\n"); | |||
| if (entry.getKey().compareTo("Content-Length") == 0) | |||
| totalLength = Integer.decode(entry.getValue().get(0)); | |||
| } | |||
| } | |||
| return true; | |||
| } catch (IOException e) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| } | |||
| static class DisconnectionRunnable implements Runnable | |||
| { | |||
| public DisconnectionRunnable(HttpURLConnection theConnection, | |||
| InputStream theInputStream, | |||
| ReentrantLock theCreateStreamLock, | |||
| Object theCreateFutureLock, | |||
| Future<BufferedInputStream> theStreamFuture) | |||
| { | |||
| connectionToDisconnect = theConnection; | |||
| inputStream = theInputStream; | |||
| createStreamLock = theCreateStreamLock; | |||
| createFutureLock = theCreateFutureLock; | |||
| streamFuture = theStreamFuture; | |||
| } | |||
| public void run() | |||
| { | |||
| try | |||
| { | |||
| if (!createStreamLock.tryLock()) | |||
| { | |||
| synchronized (createFutureLock) | |||
| { | |||
| if (streamFuture != null) | |||
| streamFuture.cancel(true); | |||
| } | |||
| createStreamLock.lock(); | |||
| } | |||
| if (connectionToDisconnect != null) | |||
| connectionToDisconnect.disconnect(); | |||
| if (inputStream != null) | |||
| inputStream.close(); | |||
| } catch (IOException e) | |||
| { | |||
| } finally | |||
| { | |||
| createStreamLock.unlock(); | |||
| } | |||
| } | |||
| private HttpURLConnection connectionToDisconnect; | |||
| private InputStream inputStream; | |||
| private ReentrantLock createStreamLock; | |||
| private Object createFutureLock; | |||
| Future<BufferedInputStream> streamFuture; | |||
| } | |||
| public final void release() | |||
| { | |||
| DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable(connection, | |||
| inputStream, | |||
| createStreamLock, | |||
| createFutureLock, | |||
| streamFuture); | |||
| synchronized (createStreamLock) | |||
| { | |||
| hasBeenCancelled.set(true); | |||
| connection = null; | |||
| } | |||
| Thread disconnectionThread = new Thread(disconnectionRunnable); | |||
| disconnectionThread.start(); | |||
| } | |||
| public final int read(byte[] buffer, int numBytes) | |||
| { | |||
| int num = 0; | |||
| try | |||
| { | |||
| synchronized (createStreamLock) | |||
| { | |||
| if (inputStream != null) | |||
| num = inputStream.read(buffer, 0, numBytes); | |||
| } | |||
| } catch (IOException e) | |||
| { | |||
| } | |||
| if (num > 0) | |||
| position += num; | |||
| return num; | |||
| } | |||
| public final long getPosition() | |||
| { | |||
| return position; | |||
| } | |||
| public final long getTotalLength() | |||
| { | |||
| return totalLength; | |||
| } | |||
| public final boolean isExhausted() | |||
| { | |||
| return false; | |||
| } | |||
| public final boolean setPosition(long newPos) | |||
| { | |||
| return false; | |||
| } | |||
| private boolean isPost; | |||
| private byte[] postData; | |||
| private String headers; | |||
| private int timeOutMs; | |||
| String httpRequestCmd; | |||
| private HttpURLConnection connection; | |||
| private int[] statusCode; | |||
| private StringBuffer responseHeaders; | |||
| private int totalLength; | |||
| private int numRedirectsToFollow; | |||
| private InputStream inputStream; | |||
| private long position; | |||
| private final ReentrantLock createStreamLock = new ReentrantLock(); | |||
| private final Object createFutureLock = new Object(); | |||
| private AtomicBoolean hasBeenCancelled = new AtomicBoolean(); | |||
| private final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory()); | |||
| Future<BufferedInputStream> streamFuture; | |||
| } | |||
| @@ -1,493 +1,493 @@ | |||
| package com.roli.juce; | |||
| import android.app.Activity; | |||
| import android.app.Application; | |||
| import android.content.Context; | |||
| import android.graphics.Canvas; | |||
| import android.graphics.ColorMatrix; | |||
| import android.graphics.ColorMatrixColorFilter; | |||
| import android.graphics.Paint; | |||
| import android.graphics.Rect; | |||
| import android.os.Bundle; | |||
| import android.text.InputType; | |||
| import android.view.KeyEvent; | |||
| import android.view.MotionEvent; | |||
| import android.view.View; | |||
| import android.view.ViewGroup; | |||
| import android.view.ViewTreeObserver; | |||
| import android.view.inputmethod.BaseInputConnection; | |||
| import android.view.inputmethod.EditorInfo; | |||
| import android.view.inputmethod.InputConnection; | |||
| import android.view.inputmethod.InputMethodManager; | |||
| import java.lang.reflect.Method; | |||
| public final class ComponentPeerView extends ViewGroup | |||
| implements View.OnFocusChangeListener, Application.ActivityLifecycleCallbacks | |||
| { | |||
| public ComponentPeerView (Context context, boolean opaque_, long host) | |||
| { | |||
| super (context); | |||
| if (Application.class.isInstance (context)) | |||
| { | |||
| ((Application) context).registerActivityLifecycleCallbacks (this); | |||
| } else | |||
| { | |||
| ((Application) context.getApplicationContext ()).registerActivityLifecycleCallbacks (this); | |||
| } | |||
| this.host = host; | |||
| setWillNotDraw (false); | |||
| opaque = opaque_; | |||
| setFocusable (true); | |||
| setFocusableInTouchMode (true); | |||
| setOnFocusChangeListener (this); | |||
| // swap red and blue colours to match internal opengl texture format | |||
| ColorMatrix colorMatrix = new ColorMatrix (); | |||
| float[] colorTransform = {0, 0, 1.0f, 0, 0, | |||
| 0, 1.0f, 0, 0, 0, | |||
| 1.0f, 0, 0, 0, 0, | |||
| 0, 0, 0, 1.0f, 0}; | |||
| colorMatrix.set (colorTransform); | |||
| paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix)); | |||
| java.lang.reflect.Method method = null; | |||
| try | |||
| { | |||
| method = getClass ().getMethod ("setLayerType", int.class, Paint.class); | |||
| } catch (SecurityException e) | |||
| { | |||
| } catch (NoSuchMethodException e) | |||
| { | |||
| } | |||
| if (method != null) | |||
| { | |||
| try | |||
| { | |||
| int layerTypeNone = 0; | |||
| method.invoke (this, layerTypeNone, null); | |||
| } catch (java.lang.IllegalArgumentException e) | |||
| { | |||
| } catch (java.lang.IllegalAccessException e) | |||
| { | |||
| } catch (java.lang.reflect.InvocationTargetException e) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| public void clear () | |||
| { | |||
| host = 0; | |||
| } | |||
| //============================================================================== | |||
| private native void handlePaint (long host, Canvas canvas, Paint paint); | |||
| @Override | |||
| public void onDraw (Canvas canvas) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| handlePaint (host, canvas, paint); | |||
| } | |||
| @Override | |||
| public boolean isOpaque () | |||
| { | |||
| return opaque; | |||
| } | |||
| private boolean opaque; | |||
| private long host; | |||
| private Paint paint = new Paint (); | |||
| //============================================================================== | |||
| private native void handleMouseDown (long host, int index, float x, float y, long time); | |||
| private native void handleMouseDrag (long host, int index, float x, float y, long time); | |||
| private native void handleMouseUp (long host, int index, float x, float y, long time); | |||
| @Override | |||
| public boolean onTouchEvent (MotionEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| int action = event.getAction (); | |||
| long time = event.getEventTime (); | |||
| switch (action & MotionEvent.ACTION_MASK) | |||
| { | |||
| case MotionEvent.ACTION_DOWN: | |||
| handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| return true; | |||
| case MotionEvent.ACTION_CANCEL: | |||
| case MotionEvent.ACTION_UP: | |||
| handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| return true; | |||
| case MotionEvent.ACTION_MOVE: | |||
| { | |||
| handleMouseDrag (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| int n = event.getPointerCount (); | |||
| if (n > 1) | |||
| { | |||
| int point[] = new int[2]; | |||
| getLocationOnScreen (point); | |||
| for (int i = 1; i < n; ++i) | |||
| handleMouseDrag (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); | |||
| } | |||
| return true; | |||
| } | |||
| case MotionEvent.ACTION_POINTER_UP: | |||
| { | |||
| int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; | |||
| if (i == 0) | |||
| { | |||
| handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| } else | |||
| { | |||
| int point[] = new int[2]; | |||
| getLocationOnScreen (point); | |||
| handleMouseUp (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); | |||
| } | |||
| return true; | |||
| } | |||
| case MotionEvent.ACTION_POINTER_DOWN: | |||
| { | |||
| int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; | |||
| if (i == 0) | |||
| { | |||
| handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| } else | |||
| { | |||
| int point[] = new int[2]; | |||
| getLocationOnScreen (point); | |||
| handleMouseDown (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); | |||
| } | |||
| return true; | |||
| } | |||
| default: | |||
| break; | |||
| } | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| private native void handleKeyDown (long host, int keycode, int textchar); | |||
| private native void handleKeyUp (long host, int keycode, int textchar); | |||
| private native void handleBackButton (long host); | |||
| private native void handleKeyboardHidden (long host); | |||
| public void showKeyboard (String type) | |||
| { | |||
| InputMethodManager imm = (InputMethodManager) getContext ().getSystemService (Context.INPUT_METHOD_SERVICE); | |||
| if (imm != null) | |||
| { | |||
| if (type.length () > 0) | |||
| { | |||
| imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); | |||
| imm.setInputMethod (getWindowToken (), type); | |||
| keyboardDismissListener.startListening (); | |||
| } else | |||
| { | |||
| imm.hideSoftInputFromWindow (getWindowToken (), 0); | |||
| keyboardDismissListener.stopListening (); | |||
| } | |||
| } | |||
| } | |||
| public void backButtonPressed () | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| handleBackButton (host); | |||
| } | |||
| @Override | |||
| public boolean onKeyDown (int keyCode, KeyEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| switch (keyCode) | |||
| { | |||
| case KeyEvent.KEYCODE_VOLUME_UP: | |||
| case KeyEvent.KEYCODE_VOLUME_DOWN: | |||
| return super.onKeyDown (keyCode, event); | |||
| case KeyEvent.KEYCODE_BACK: | |||
| { | |||
| ((Activity) getContext ()).onBackPressed (); | |||
| return true; | |||
| } | |||
| default: | |||
| break; | |||
| } | |||
| handleKeyDown (host, keyCode, event.getUnicodeChar ()); | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean onKeyUp (int keyCode, KeyEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| handleKeyUp (host, keyCode, event.getUnicodeChar ()); | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction () != KeyEvent.ACTION_MULTIPLE) | |||
| return super.onKeyMultiple (keyCode, count, event); | |||
| if (event.getCharacters () != null) | |||
| { | |||
| int utf8Char = event.getCharacters ().codePointAt (0); | |||
| handleKeyDown (host, utf8Char, utf8Char); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| private final class KeyboardDismissListener | |||
| { | |||
| public KeyboardDismissListener (ComponentPeerView viewToUse) | |||
| { | |||
| view = viewToUse; | |||
| } | |||
| private void startListening () | |||
| { | |||
| view.getViewTreeObserver ().addOnGlobalLayoutListener (viewTreeObserver); | |||
| } | |||
| private void stopListening () | |||
| { | |||
| view.getViewTreeObserver ().removeGlobalOnLayoutListener (viewTreeObserver); | |||
| } | |||
| private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener | |||
| { | |||
| TreeObserver () | |||
| { | |||
| keyboardShown = false; | |||
| } | |||
| @Override | |||
| public void onGlobalLayout () | |||
| { | |||
| Rect r = new Rect (); | |||
| View parentView = getRootView (); | |||
| int diff = 0; | |||
| if (parentView == null) | |||
| { | |||
| getWindowVisibleDisplayFrame (r); | |||
| diff = getHeight () - (r.bottom - r.top); | |||
| } else | |||
| { | |||
| parentView.getWindowVisibleDisplayFrame (r); | |||
| diff = parentView.getHeight () - (r.bottom - r.top); | |||
| } | |||
| // Arbitrary threshold, surely keyboard would take more than 20 pix. | |||
| if (diff < 20 && keyboardShown) | |||
| { | |||
| keyboardShown = false; | |||
| handleKeyboardHidden (view.host); | |||
| } | |||
| if (!keyboardShown && diff > 20) | |||
| keyboardShown = true; | |||
| } | |||
| ; | |||
| private boolean keyboardShown; | |||
| } | |||
| ; | |||
| private ComponentPeerView view; | |||
| private TreeObserver viewTreeObserver = new TreeObserver (); | |||
| } | |||
| private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener (this); | |||
| // this is here to make keyboard entry work on a Galaxy Tab2 10.1 | |||
| @Override | |||
| public InputConnection onCreateInputConnection (EditorInfo outAttrs) | |||
| { | |||
| outAttrs.actionLabel = ""; | |||
| outAttrs.hintText = ""; | |||
| outAttrs.initialCapsMode = 0; | |||
| outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; | |||
| outAttrs.label = ""; | |||
| outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI; | |||
| outAttrs.inputType = InputType.TYPE_NULL; | |||
| return new BaseInputConnection (this, false); | |||
| } | |||
| //============================================================================== | |||
| @Override | |||
| protected void onSizeChanged (int w, int h, int oldw, int oldh) | |||
| { | |||
| super.onSizeChanged (w, h, oldw, oldh); | |||
| if (host != 0) | |||
| viewSizeChanged (host); | |||
| } | |||
| @Override | |||
| protected void onLayout (boolean changed, int left, int top, int right, int bottom) | |||
| { | |||
| } | |||
| private native void viewSizeChanged (long host); | |||
| @Override | |||
| public void onFocusChange (View v, boolean hasFocus) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| if (v == this) | |||
| focusChanged (host, hasFocus); | |||
| } | |||
| private native void focusChanged (long host, boolean hasFocus); | |||
| public void setViewName (String newName) | |||
| { | |||
| } | |||
| public void setSystemUiVisibilityCompat (int visibility) | |||
| { | |||
| Method systemUIVisibilityMethod = null; | |||
| try | |||
| { | |||
| systemUIVisibilityMethod = this.getClass ().getMethod ("setSystemUiVisibility", int.class); | |||
| } catch (SecurityException e) | |||
| { | |||
| return; | |||
| } catch (NoSuchMethodException e) | |||
| { | |||
| return; | |||
| } | |||
| if (systemUIVisibilityMethod == null) return; | |||
| try | |||
| { | |||
| systemUIVisibilityMethod.invoke (this, visibility); | |||
| } catch (java.lang.IllegalArgumentException e) | |||
| { | |||
| } catch (java.lang.IllegalAccessException e) | |||
| { | |||
| } catch (java.lang.reflect.InvocationTargetException e) | |||
| { | |||
| } | |||
| } | |||
| public boolean isVisible () | |||
| { | |||
| return getVisibility () == VISIBLE; | |||
| } | |||
| public void setVisible (boolean b) | |||
| { | |||
| setVisibility (b ? VISIBLE : INVISIBLE); | |||
| } | |||
| public boolean containsPoint (int x, int y) | |||
| { | |||
| return true; //xxx needs to check overlapping views | |||
| } | |||
| //============================================================================== | |||
| private native void handleAppPaused (long host); | |||
| private native void handleAppResumed (long host); | |||
| @Override | |||
| public void onActivityPaused (Activity activity) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| handleAppPaused (host); | |||
| } | |||
| @Override | |||
| public void onActivityStopped (Activity activity) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivitySaveInstanceState (Activity activity, Bundle bundle) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityDestroyed (Activity activity) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityCreated (Activity activity, Bundle bundle) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityStarted (Activity activity) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityResumed (Activity activity) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| // Ensure that navigation/status bar visibility is correctly restored. | |||
| handleAppResumed (host); | |||
| } | |||
| } | |||
| package com.roli.juce; | |||
| import android.app.Activity; | |||
| import android.app.Application; | |||
| import android.content.Context; | |||
| import android.graphics.Canvas; | |||
| import android.graphics.ColorMatrix; | |||
| import android.graphics.ColorMatrixColorFilter; | |||
| import android.graphics.Paint; | |||
| import android.graphics.Rect; | |||
| import android.os.Bundle; | |||
| import android.text.InputType; | |||
| import android.view.KeyEvent; | |||
| import android.view.MotionEvent; | |||
| import android.view.View; | |||
| import android.view.ViewGroup; | |||
| import android.view.ViewTreeObserver; | |||
| import android.view.inputmethod.BaseInputConnection; | |||
| import android.view.inputmethod.EditorInfo; | |||
| import android.view.inputmethod.InputConnection; | |||
| import android.view.inputmethod.InputMethodManager; | |||
| import java.lang.reflect.Method; | |||
| public final class ComponentPeerView extends ViewGroup | |||
| implements View.OnFocusChangeListener, Application.ActivityLifecycleCallbacks | |||
| { | |||
| public ComponentPeerView (Context context, boolean opaque_, long host) | |||
| { | |||
| super (context); | |||
| if (Application.class.isInstance (context)) | |||
| { | |||
| ((Application) context).registerActivityLifecycleCallbacks (this); | |||
| } else | |||
| { | |||
| ((Application) context.getApplicationContext ()).registerActivityLifecycleCallbacks (this); | |||
| } | |||
| this.host = host; | |||
| setWillNotDraw (false); | |||
| opaque = opaque_; | |||
| setFocusable (true); | |||
| setFocusableInTouchMode (true); | |||
| setOnFocusChangeListener (this); | |||
| // swap red and blue colours to match internal opengl texture format | |||
| ColorMatrix colorMatrix = new ColorMatrix (); | |||
| float[] colorTransform = {0, 0, 1.0f, 0, 0, | |||
| 0, 1.0f, 0, 0, 0, | |||
| 1.0f, 0, 0, 0, 0, | |||
| 0, 0, 0, 1.0f, 0}; | |||
| colorMatrix.set (colorTransform); | |||
| paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix)); | |||
| java.lang.reflect.Method method = null; | |||
| try | |||
| { | |||
| method = getClass ().getMethod ("setLayerType", int.class, Paint.class); | |||
| } catch (SecurityException e) | |||
| { | |||
| } catch (NoSuchMethodException e) | |||
| { | |||
| } | |||
| if (method != null) | |||
| { | |||
| try | |||
| { | |||
| int layerTypeNone = 0; | |||
| method.invoke (this, layerTypeNone, null); | |||
| } catch (java.lang.IllegalArgumentException e) | |||
| { | |||
| } catch (java.lang.IllegalAccessException e) | |||
| { | |||
| } catch (java.lang.reflect.InvocationTargetException e) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| public void clear () | |||
| { | |||
| host = 0; | |||
| } | |||
| //============================================================================== | |||
| private native void handlePaint (long host, Canvas canvas, Paint paint); | |||
| @Override | |||
| public void onDraw (Canvas canvas) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| handlePaint (host, canvas, paint); | |||
| } | |||
| @Override | |||
| public boolean isOpaque () | |||
| { | |||
| return opaque; | |||
| } | |||
| private boolean opaque; | |||
| private long host; | |||
| private Paint paint = new Paint (); | |||
| //============================================================================== | |||
| private native void handleMouseDown (long host, int index, float x, float y, long time); | |||
| private native void handleMouseDrag (long host, int index, float x, float y, long time); | |||
| private native void handleMouseUp (long host, int index, float x, float y, long time); | |||
| @Override | |||
| public boolean onTouchEvent (MotionEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| int action = event.getAction (); | |||
| long time = event.getEventTime (); | |||
| switch (action & MotionEvent.ACTION_MASK) | |||
| { | |||
| case MotionEvent.ACTION_DOWN: | |||
| handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| return true; | |||
| case MotionEvent.ACTION_CANCEL: | |||
| case MotionEvent.ACTION_UP: | |||
| handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| return true; | |||
| case MotionEvent.ACTION_MOVE: | |||
| { | |||
| handleMouseDrag (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| int n = event.getPointerCount (); | |||
| if (n > 1) | |||
| { | |||
| int point[] = new int[2]; | |||
| getLocationOnScreen (point); | |||
| for (int i = 1; i < n; ++i) | |||
| handleMouseDrag (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); | |||
| } | |||
| return true; | |||
| } | |||
| case MotionEvent.ACTION_POINTER_UP: | |||
| { | |||
| int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; | |||
| if (i == 0) | |||
| { | |||
| handleMouseUp (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| } else | |||
| { | |||
| int point[] = new int[2]; | |||
| getLocationOnScreen (point); | |||
| handleMouseUp (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); | |||
| } | |||
| return true; | |||
| } | |||
| case MotionEvent.ACTION_POINTER_DOWN: | |||
| { | |||
| int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; | |||
| if (i == 0) | |||
| { | |||
| handleMouseDown (host, event.getPointerId (0), event.getRawX (), event.getRawY (), time); | |||
| } else | |||
| { | |||
| int point[] = new int[2]; | |||
| getLocationOnScreen (point); | |||
| handleMouseDown (host, event.getPointerId (i), event.getX (i) + point[0], event.getY (i) + point[1], time); | |||
| } | |||
| return true; | |||
| } | |||
| default: | |||
| break; | |||
| } | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| private native void handleKeyDown (long host, int keycode, int textchar); | |||
| private native void handleKeyUp (long host, int keycode, int textchar); | |||
| private native void handleBackButton (long host); | |||
| private native void handleKeyboardHidden (long host); | |||
| public void showKeyboard (String type) | |||
| { | |||
| InputMethodManager imm = (InputMethodManager) getContext ().getSystemService (Context.INPUT_METHOD_SERVICE); | |||
| if (imm != null) | |||
| { | |||
| if (type.length () > 0) | |||
| { | |||
| imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); | |||
| imm.setInputMethod (getWindowToken (), type); | |||
| keyboardDismissListener.startListening (); | |||
| } else | |||
| { | |||
| imm.hideSoftInputFromWindow (getWindowToken (), 0); | |||
| keyboardDismissListener.stopListening (); | |||
| } | |||
| } | |||
| } | |||
| public void backButtonPressed () | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| handleBackButton (host); | |||
| } | |||
| @Override | |||
| public boolean onKeyDown (int keyCode, KeyEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| switch (keyCode) | |||
| { | |||
| case KeyEvent.KEYCODE_VOLUME_UP: | |||
| case KeyEvent.KEYCODE_VOLUME_DOWN: | |||
| return super.onKeyDown (keyCode, event); | |||
| case KeyEvent.KEYCODE_BACK: | |||
| { | |||
| ((Activity) getContext ()).onBackPressed (); | |||
| return true; | |||
| } | |||
| default: | |||
| break; | |||
| } | |||
| handleKeyDown (host, keyCode, event.getUnicodeChar ()); | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean onKeyUp (int keyCode, KeyEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| handleKeyUp (host, keyCode, event.getUnicodeChar ()); | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) | |||
| { | |||
| if (host == 0) | |||
| return false; | |||
| if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction () != KeyEvent.ACTION_MULTIPLE) | |||
| return super.onKeyMultiple (keyCode, count, event); | |||
| if (event.getCharacters () != null) | |||
| { | |||
| int utf8Char = event.getCharacters ().codePointAt (0); | |||
| handleKeyDown (host, utf8Char, utf8Char); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| private final class KeyboardDismissListener | |||
| { | |||
| public KeyboardDismissListener (ComponentPeerView viewToUse) | |||
| { | |||
| view = viewToUse; | |||
| } | |||
| private void startListening () | |||
| { | |||
| view.getViewTreeObserver ().addOnGlobalLayoutListener (viewTreeObserver); | |||
| } | |||
| private void stopListening () | |||
| { | |||
| view.getViewTreeObserver ().removeGlobalOnLayoutListener (viewTreeObserver); | |||
| } | |||
| private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener | |||
| { | |||
| TreeObserver () | |||
| { | |||
| keyboardShown = false; | |||
| } | |||
| @Override | |||
| public void onGlobalLayout () | |||
| { | |||
| Rect r = new Rect (); | |||
| View parentView = getRootView (); | |||
| int diff = 0; | |||
| if (parentView == null) | |||
| { | |||
| getWindowVisibleDisplayFrame (r); | |||
| diff = getHeight () - (r.bottom - r.top); | |||
| } else | |||
| { | |||
| parentView.getWindowVisibleDisplayFrame (r); | |||
| diff = parentView.getHeight () - (r.bottom - r.top); | |||
| } | |||
| // Arbitrary threshold, surely keyboard would take more than 20 pix. | |||
| if (diff < 20 && keyboardShown) | |||
| { | |||
| keyboardShown = false; | |||
| handleKeyboardHidden (view.host); | |||
| } | |||
| if (!keyboardShown && diff > 20) | |||
| keyboardShown = true; | |||
| } | |||
| ; | |||
| private boolean keyboardShown; | |||
| } | |||
| ; | |||
| private ComponentPeerView view; | |||
| private TreeObserver viewTreeObserver = new TreeObserver (); | |||
| } | |||
| private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener (this); | |||
| // this is here to make keyboard entry work on a Galaxy Tab2 10.1 | |||
| @Override | |||
| public InputConnection onCreateInputConnection (EditorInfo outAttrs) | |||
| { | |||
| outAttrs.actionLabel = ""; | |||
| outAttrs.hintText = ""; | |||
| outAttrs.initialCapsMode = 0; | |||
| outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; | |||
| outAttrs.label = ""; | |||
| outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI; | |||
| outAttrs.inputType = InputType.TYPE_NULL; | |||
| return new BaseInputConnection (this, false); | |||
| } | |||
| //============================================================================== | |||
| @Override | |||
| protected void onSizeChanged (int w, int h, int oldw, int oldh) | |||
| { | |||
| super.onSizeChanged (w, h, oldw, oldh); | |||
| if (host != 0) | |||
| viewSizeChanged (host); | |||
| } | |||
| @Override | |||
| protected void onLayout (boolean changed, int left, int top, int right, int bottom) | |||
| { | |||
| } | |||
| private native void viewSizeChanged (long host); | |||
| @Override | |||
| public void onFocusChange (View v, boolean hasFocus) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| if (v == this) | |||
| focusChanged (host, hasFocus); | |||
| } | |||
| private native void focusChanged (long host, boolean hasFocus); | |||
| public void setViewName (String newName) | |||
| { | |||
| } | |||
| public void setSystemUiVisibilityCompat (int visibility) | |||
| { | |||
| Method systemUIVisibilityMethod = null; | |||
| try | |||
| { | |||
| systemUIVisibilityMethod = this.getClass ().getMethod ("setSystemUiVisibility", int.class); | |||
| } catch (SecurityException e) | |||
| { | |||
| return; | |||
| } catch (NoSuchMethodException e) | |||
| { | |||
| return; | |||
| } | |||
| if (systemUIVisibilityMethod == null) return; | |||
| try | |||
| { | |||
| systemUIVisibilityMethod.invoke (this, visibility); | |||
| } catch (java.lang.IllegalArgumentException e) | |||
| { | |||
| } catch (java.lang.IllegalAccessException e) | |||
| { | |||
| } catch (java.lang.reflect.InvocationTargetException e) | |||
| { | |||
| } | |||
| } | |||
| public boolean isVisible () | |||
| { | |||
| return getVisibility () == VISIBLE; | |||
| } | |||
| public void setVisible (boolean b) | |||
| { | |||
| setVisibility (b ? VISIBLE : INVISIBLE); | |||
| } | |||
| public boolean containsPoint (int x, int y) | |||
| { | |||
| return true; //xxx needs to check overlapping views | |||
| } | |||
| //============================================================================== | |||
| private native void handleAppPaused (long host); | |||
| private native void handleAppResumed (long host); | |||
| @Override | |||
| public void onActivityPaused (Activity activity) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| handleAppPaused (host); | |||
| } | |||
| @Override | |||
| public void onActivityStopped (Activity activity) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivitySaveInstanceState (Activity activity, Bundle bundle) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityDestroyed (Activity activity) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityCreated (Activity activity, Bundle bundle) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityStarted (Activity activity) | |||
| { | |||
| } | |||
| @Override | |||
| public void onActivityResumed (Activity activity) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| // Ensure that navigation/status bar visibility is correctly restored. | |||
| handleAppResumed (host); | |||
| } | |||
| } | |||
| @@ -1,107 +1,107 @@ | |||
| package com.roli.juce; | |||
| import android.graphics.Bitmap; | |||
| import android.net.http.SslError; | |||
| import android.os.Message; | |||
| import android.webkit.WebResourceResponse; | |||
| import android.webkit.WebView; | |||
| import android.webkit.WebViewClient; | |||
| import android.webkit.SslErrorHandler; | |||
| import android.webkit.WebChromeClient; | |||
| //============================================================================== | |||
| public class JuceWebView | |||
| { | |||
| static public class Client extends WebViewClient | |||
| { | |||
| public Client (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| public void hostDeleted () | |||
| { | |||
| synchronized (hostLock) | |||
| { | |||
| host = 0; | |||
| } | |||
| } | |||
| public void onPageFinished (WebView view, String url) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| webViewPageLoadFinished (host, view, url); | |||
| } | |||
| public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| webViewReceivedSslError (host, view, handler, error); | |||
| } | |||
| public void onPageStarted (WebView view, String url, Bitmap favicon) | |||
| { | |||
| if (host != 0) | |||
| webViewPageLoadStarted (host, view, url); | |||
| } | |||
| public WebResourceResponse shouldInterceptRequest (WebView view, String url) | |||
| { | |||
| synchronized (hostLock) | |||
| { | |||
| if (host != 0) | |||
| { | |||
| boolean shouldLoad = webViewPageLoadStarted (host, view, url); | |||
| if (shouldLoad) | |||
| return null; | |||
| } | |||
| } | |||
| return new WebResourceResponse ("text/html", null, null); | |||
| } | |||
| private native boolean webViewPageLoadStarted (long host, WebView view, String url); | |||
| private native void webViewPageLoadFinished (long host, WebView view, String url); | |||
| private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error); | |||
| private long host; | |||
| private final Object hostLock = new Object (); | |||
| } | |||
| static public class ChromeClient extends WebChromeClient | |||
| { | |||
| public ChromeClient (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onCloseWindow (WebView window) | |||
| { | |||
| webViewCloseWindowRequest (host, window); | |||
| } | |||
| @Override | |||
| public boolean onCreateWindow (WebView view, boolean isDialog, | |||
| boolean isUserGesture, Message resultMsg) | |||
| { | |||
| webViewCreateWindowRequest (host, view); | |||
| return false; | |||
| } | |||
| private native void webViewCloseWindowRequest (long host, WebView view); | |||
| private native void webViewCreateWindowRequest (long host, WebView view); | |||
| private long host; | |||
| private final Object hostLock = new Object (); | |||
| } | |||
| } | |||
| package com.roli.juce; | |||
| import android.graphics.Bitmap; | |||
| import android.net.http.SslError; | |||
| import android.os.Message; | |||
| import android.webkit.WebResourceResponse; | |||
| import android.webkit.WebView; | |||
| import android.webkit.WebViewClient; | |||
| import android.webkit.SslErrorHandler; | |||
| import android.webkit.WebChromeClient; | |||
| //============================================================================== | |||
| public class JuceWebView | |||
| { | |||
| static public class Client extends WebViewClient | |||
| { | |||
| public Client (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| public void hostDeleted () | |||
| { | |||
| synchronized (hostLock) | |||
| { | |||
| host = 0; | |||
| } | |||
| } | |||
| public void onPageFinished (WebView view, String url) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| webViewPageLoadFinished (host, view, url); | |||
| } | |||
| public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) | |||
| { | |||
| if (host == 0) | |||
| return; | |||
| webViewReceivedSslError (host, view, handler, error); | |||
| } | |||
| public void onPageStarted (WebView view, String url, Bitmap favicon) | |||
| { | |||
| if (host != 0) | |||
| webViewPageLoadStarted (host, view, url); | |||
| } | |||
| public WebResourceResponse shouldInterceptRequest (WebView view, String url) | |||
| { | |||
| synchronized (hostLock) | |||
| { | |||
| if (host != 0) | |||
| { | |||
| boolean shouldLoad = webViewPageLoadStarted (host, view, url); | |||
| if (shouldLoad) | |||
| return null; | |||
| } | |||
| } | |||
| return new WebResourceResponse ("text/html", null, null); | |||
| } | |||
| private native boolean webViewPageLoadStarted (long host, WebView view, String url); | |||
| private native void webViewPageLoadFinished (long host, WebView view, String url); | |||
| private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error); | |||
| private long host; | |||
| private final Object hostLock = new Object (); | |||
| } | |||
| static public class ChromeClient extends WebChromeClient | |||
| { | |||
| public ChromeClient (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onCloseWindow (WebView window) | |||
| { | |||
| webViewCloseWindowRequest (host, window); | |||
| } | |||
| @Override | |||
| public boolean onCreateWindow (WebView view, boolean isDialog, | |||
| boolean isUserGesture, Message resultMsg) | |||
| { | |||
| webViewCreateWindowRequest (host, view); | |||
| return false; | |||
| } | |||
| private native void webViewCloseWindowRequest (long host, WebView view); | |||
| private native void webViewCreateWindowRequest (long host, WebView view); | |||
| private long host; | |||
| private final Object hostLock = new Object (); | |||
| } | |||
| } | |||
| @@ -1,56 +1,56 @@ | |||
| package com.roli.juce; | |||
| import android.content.Context; | |||
| import android.graphics.Canvas; | |||
| import android.view.SurfaceView; | |||
| public class JuceOpenGLView extends SurfaceView | |||
| { | |||
| private long host = 0; | |||
| JuceOpenGLView (Context context, long nativeThis) | |||
| { | |||
| super (context); | |||
| host = nativeThis; | |||
| } | |||
| public void cancel () | |||
| { | |||
| host = 0; | |||
| } | |||
| //============================================================================== | |||
| @Override | |||
| protected void onAttachedToWindow () | |||
| { | |||
| super.onAttachedToWindow (); | |||
| if (host != 0) | |||
| onAttchedWindowNative (host); | |||
| } | |||
| @Override | |||
| protected void onDetachedFromWindow () | |||
| { | |||
| if (host != 0) | |||
| onDetachedFromWindowNative (host); | |||
| super.onDetachedFromWindow (); | |||
| } | |||
| @Override | |||
| protected void dispatchDraw (Canvas canvas) | |||
| { | |||
| super.dispatchDraw (canvas); | |||
| if (host != 0) | |||
| onDrawNative (host, canvas); | |||
| } | |||
| //============================================================================== | |||
| private native void onAttchedWindowNative (long nativeThis); | |||
| private native void onDetachedFromWindowNative (long nativeThis); | |||
| private native void onDrawNative (long nativeThis, Canvas canvas); | |||
| } | |||
| package com.roli.juce; | |||
| import android.content.Context; | |||
| import android.graphics.Canvas; | |||
| import android.view.SurfaceView; | |||
| public class JuceOpenGLView extends SurfaceView | |||
| { | |||
| private long host = 0; | |||
| JuceOpenGLView (Context context, long nativeThis) | |||
| { | |||
| super (context); | |||
| host = nativeThis; | |||
| } | |||
| public void cancel () | |||
| { | |||
| host = 0; | |||
| } | |||
| //============================================================================== | |||
| @Override | |||
| protected void onAttachedToWindow () | |||
| { | |||
| super.onAttachedToWindow (); | |||
| if (host != 0) | |||
| onAttchedWindowNative (host); | |||
| } | |||
| @Override | |||
| protected void onDetachedFromWindow () | |||
| { | |||
| if (host != 0) | |||
| onDetachedFromWindowNative (host); | |||
| super.onDetachedFromWindow (); | |||
| } | |||
| @Override | |||
| protected void dispatchDraw (Canvas canvas) | |||
| { | |||
| super.dispatchDraw (canvas); | |||
| if (host != 0) | |||
| onDrawNative (host, canvas); | |||
| } | |||
| //============================================================================== | |||
| private native void onAttchedWindowNative (long nativeThis); | |||
| private native void onDetachedFromWindowNative (long nativeThis); | |||
| private native void onDrawNative (long nativeThis, Canvas canvas); | |||
| } | |||
| @@ -1,65 +1,65 @@ | |||
| package com.roli.juce; | |||
| import android.hardware.camera2.CameraCaptureSession; | |||
| import android.hardware.camera2.CaptureRequest; | |||
| import android.hardware.camera2.TotalCaptureResult; | |||
| import android.hardware.camera2.CaptureFailure; | |||
| import android.hardware.camera2.CaptureResult; | |||
| public class CameraCaptureSessionCaptureCallback extends CameraCaptureSession.CaptureCallback | |||
| { | |||
| private native void cameraCaptureSessionCaptureCompleted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result); | |||
| private native void cameraCaptureSessionCaptureFailed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureFailure failure); | |||
| private native void cameraCaptureSessionCaptureProgressed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult); | |||
| private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber); | |||
| private native void cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId); | |||
| private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber); | |||
| CameraCaptureSessionCaptureCallback (long hostToUse, boolean shouldBePreview) | |||
| { | |||
| host = hostToUse; | |||
| preview = shouldBePreview; | |||
| } | |||
| @Override | |||
| public void onCaptureCompleted (CameraCaptureSession session, CaptureRequest request, | |||
| TotalCaptureResult result) | |||
| { | |||
| cameraCaptureSessionCaptureCompleted (host, preview, session, request, result); | |||
| } | |||
| @Override | |||
| public void onCaptureFailed (CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) | |||
| { | |||
| cameraCaptureSessionCaptureFailed (host, preview, session, request, failure); | |||
| } | |||
| @Override | |||
| public void onCaptureProgressed (CameraCaptureSession session, CaptureRequest request, | |||
| CaptureResult partialResult) | |||
| { | |||
| cameraCaptureSessionCaptureProgressed (host, preview, session, request, partialResult); | |||
| } | |||
| @Override | |||
| public void onCaptureSequenceAborted (CameraCaptureSession session, int sequenceId) | |||
| { | |||
| cameraCaptureSessionCaptureSequenceAborted (host, preview, session, sequenceId); | |||
| } | |||
| @Override | |||
| public void onCaptureSequenceCompleted (CameraCaptureSession session, int sequenceId, long frameNumber) | |||
| { | |||
| cameraCaptureSessionCaptureSequenceCompleted (host, preview, session, sequenceId, frameNumber); | |||
| } | |||
| @Override | |||
| public void onCaptureStarted (CameraCaptureSession session, CaptureRequest request, long timestamp, | |||
| long frameNumber) | |||
| { | |||
| cameraCaptureSessionCaptureStarted (host, preview, session, request, timestamp, frameNumber); | |||
| } | |||
| private long host; | |||
| private boolean preview; | |||
| } | |||
| package com.roli.juce; | |||
| import android.hardware.camera2.CameraCaptureSession; | |||
| import android.hardware.camera2.CaptureRequest; | |||
| import android.hardware.camera2.TotalCaptureResult; | |||
| import android.hardware.camera2.CaptureFailure; | |||
| import android.hardware.camera2.CaptureResult; | |||
| public class CameraCaptureSessionCaptureCallback extends CameraCaptureSession.CaptureCallback | |||
| { | |||
| private native void cameraCaptureSessionCaptureCompleted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result); | |||
| private native void cameraCaptureSessionCaptureFailed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureFailure failure); | |||
| private native void cameraCaptureSessionCaptureProgressed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult); | |||
| private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber); | |||
| private native void cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId); | |||
| private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber); | |||
| CameraCaptureSessionCaptureCallback (long hostToUse, boolean shouldBePreview) | |||
| { | |||
| host = hostToUse; | |||
| preview = shouldBePreview; | |||
| } | |||
| @Override | |||
| public void onCaptureCompleted (CameraCaptureSession session, CaptureRequest request, | |||
| TotalCaptureResult result) | |||
| { | |||
| cameraCaptureSessionCaptureCompleted (host, preview, session, request, result); | |||
| } | |||
| @Override | |||
| public void onCaptureFailed (CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) | |||
| { | |||
| cameraCaptureSessionCaptureFailed (host, preview, session, request, failure); | |||
| } | |||
| @Override | |||
| public void onCaptureProgressed (CameraCaptureSession session, CaptureRequest request, | |||
| CaptureResult partialResult) | |||
| { | |||
| cameraCaptureSessionCaptureProgressed (host, preview, session, request, partialResult); | |||
| } | |||
| @Override | |||
| public void onCaptureSequenceAborted (CameraCaptureSession session, int sequenceId) | |||
| { | |||
| cameraCaptureSessionCaptureSequenceAborted (host, preview, session, sequenceId); | |||
| } | |||
| @Override | |||
| public void onCaptureSequenceCompleted (CameraCaptureSession session, int sequenceId, long frameNumber) | |||
| { | |||
| cameraCaptureSessionCaptureSequenceCompleted (host, preview, session, sequenceId, frameNumber); | |||
| } | |||
| @Override | |||
| public void onCaptureStarted (CameraCaptureSession session, CaptureRequest request, long timestamp, | |||
| long frameNumber) | |||
| { | |||
| cameraCaptureSessionCaptureStarted (host, preview, session, request, timestamp, frameNumber); | |||
| } | |||
| private long host; | |||
| private boolean preview; | |||
| } | |||
| @@ -1,53 +1,53 @@ | |||
| package com.roli.juce; | |||
| import android.hardware.camera2.CameraCaptureSession; | |||
| public class CameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback | |||
| { | |||
| private native void cameraCaptureSessionActive (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionClosed (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionConfigureFailed (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionConfigured (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionReady (long host, CameraCaptureSession session); | |||
| CameraCaptureSessionStateCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onActive (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionActive (host, session); | |||
| } | |||
| @Override | |||
| public void onClosed (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionClosed (host, session); | |||
| } | |||
| @Override | |||
| public void onConfigureFailed (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionConfigureFailed (host, session); | |||
| } | |||
| @Override | |||
| public void onConfigured (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionConfigured (host, session); | |||
| } | |||
| @Override | |||
| public void onReady (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionReady (host, session); | |||
| } | |||
| private long host; | |||
| } | |||
| package com.roli.juce; | |||
| import android.hardware.camera2.CameraCaptureSession; | |||
| public class CameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback | |||
| { | |||
| private native void cameraCaptureSessionActive (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionClosed (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionConfigureFailed (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionConfigured (long host, CameraCaptureSession session); | |||
| private native void cameraCaptureSessionReady (long host, CameraCaptureSession session); | |||
| CameraCaptureSessionStateCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onActive (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionActive (host, session); | |||
| } | |||
| @Override | |||
| public void onClosed (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionClosed (host, session); | |||
| } | |||
| @Override | |||
| public void onConfigureFailed (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionConfigureFailed (host, session); | |||
| } | |||
| @Override | |||
| public void onConfigured (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionConfigured (host, session); | |||
| } | |||
| @Override | |||
| public void onReady (CameraCaptureSession session) | |||
| { | |||
| cameraCaptureSessionReady (host, session); | |||
| } | |||
| private long host; | |||
| } | |||
| @@ -1,43 +1,42 @@ | |||
| package com.roli.juce; | |||
| import android.hardware.camera2.CameraDevice; | |||
| public class CameraDeviceStateCallback extends CameraDevice.StateCallback | |||
| { | |||
| private native void cameraDeviceStateClosed (long host, CameraDevice camera); | |||
| private native void cameraDeviceStateDisconnected (long host, CameraDevice camera); | |||
| private native void cameraDeviceStateError (long host, CameraDevice camera, int error); | |||
| private native void cameraDeviceStateOpened (long host, CameraDevice camera); | |||
| CameraDeviceStateCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onClosed (CameraDevice camera) | |||
| { | |||
| cameraDeviceStateClosed (host, camera); | |||
| } | |||
| @Override | |||
| public void onDisconnected (CameraDevice camera) | |||
| { | |||
| cameraDeviceStateDisconnected (host, camera); | |||
| } | |||
| @Override | |||
| public void onError (CameraDevice camera, int error) | |||
| { | |||
| cameraDeviceStateError (host, camera, error); | |||
| } | |||
| @Override | |||
| public void onOpened (CameraDevice camera) | |||
| { | |||
| cameraDeviceStateOpened (host, camera); | |||
| } | |||
| private long host; | |||
| } | |||
| package com.roli.juce; | |||
| import android.hardware.camera2.CameraDevice; | |||
| public class CameraDeviceStateCallback extends CameraDevice.StateCallback | |||
| { | |||
| private native void cameraDeviceStateClosed (long host, CameraDevice camera); | |||
| private native void cameraDeviceStateDisconnected (long host, CameraDevice camera); | |||
| private native void cameraDeviceStateError (long host, CameraDevice camera, int error); | |||
| private native void cameraDeviceStateOpened (long host, CameraDevice camera); | |||
| CameraDeviceStateCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onClosed (CameraDevice camera) | |||
| { | |||
| cameraDeviceStateClosed (host, camera); | |||
| } | |||
| @Override | |||
| public void onDisconnected (CameraDevice camera) | |||
| { | |||
| cameraDeviceStateDisconnected (host, camera); | |||
| } | |||
| @Override | |||
| public void onError (CameraDevice camera, int error) | |||
| { | |||
| cameraDeviceStateError (host, camera, error); | |||
| } | |||
| @Override | |||
| public void onOpened (CameraDevice camera) | |||
| { | |||
| cameraDeviceStateOpened (host, camera); | |||
| } | |||
| private long host; | |||
| } | |||
| @@ -1,24 +1,24 @@ | |||
| package com.roli.juce; | |||
| import android.view.OrientationEventListener; | |||
| import android.content.Context; | |||
| public class JuceOrientationEventListener extends OrientationEventListener | |||
| { | |||
| private native void deviceOrientationChanged (long host, int orientation); | |||
| public JuceOrientationEventListener (long hostToUse, Context context, int rate) | |||
| { | |||
| super (context, rate); | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onOrientationChanged (int orientation) | |||
| { | |||
| deviceOrientationChanged (host, orientation); | |||
| } | |||
| private long host; | |||
| } | |||
| package com.roli.juce; | |||
| import android.view.OrientationEventListener; | |||
| import android.content.Context; | |||
| public class JuceOrientationEventListener extends OrientationEventListener | |||
| { | |||
| private native void deviceOrientationChanged (long host, int orientation); | |||
| public JuceOrientationEventListener (long hostToUse, Context context, int rate) | |||
| { | |||
| super (context, rate); | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onOrientationChanged (int orientation) | |||
| { | |||
| deviceOrientationChanged (host, orientation); | |||
| } | |||
| private long host; | |||
| } | |||
| @@ -1,53 +1,53 @@ | |||
| package com.roli.juce; | |||
| import android.media.session.MediaController; | |||
| import android.media.session.MediaSession; | |||
| import android.media.MediaMetadata; | |||
| import android.media.session.PlaybackState; | |||
| import java.util.List; | |||
| //============================================================================== | |||
| public class MediaControllerCallback extends MediaController.Callback | |||
| { | |||
| private native void mediaControllerAudioInfoChanged (long host, MediaController.PlaybackInfo info); | |||
| private native void mediaControllerMetadataChanged (long host, MediaMetadata metadata); | |||
| private native void mediaControllerPlaybackStateChanged (long host, PlaybackState state); | |||
| private native void mediaControllerSessionDestroyed (long host); | |||
| MediaControllerCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onAudioInfoChanged (MediaController.PlaybackInfo info) | |||
| { | |||
| mediaControllerAudioInfoChanged (host, info); | |||
| } | |||
| @Override | |||
| public void onMetadataChanged (MediaMetadata metadata) | |||
| { | |||
| mediaControllerMetadataChanged (host, metadata); | |||
| } | |||
| @Override | |||
| public void onPlaybackStateChanged (PlaybackState state) | |||
| { | |||
| mediaControllerPlaybackStateChanged (host, state); | |||
| } | |||
| @Override | |||
| public void onQueueChanged (List<MediaSession.QueueItem> queue) | |||
| { | |||
| } | |||
| @Override | |||
| public void onSessionDestroyed () | |||
| { | |||
| mediaControllerSessionDestroyed (host); | |||
| } | |||
| private long host; | |||
| } | |||
| package com.roli.juce; | |||
| import android.media.session.MediaController; | |||
| import android.media.session.MediaSession; | |||
| import android.media.MediaMetadata; | |||
| import android.media.session.PlaybackState; | |||
| import java.util.List; | |||
| //============================================================================== | |||
| public class MediaControllerCallback extends MediaController.Callback | |||
| { | |||
| private native void mediaControllerAudioInfoChanged (long host, MediaController.PlaybackInfo info); | |||
| private native void mediaControllerMetadataChanged (long host, MediaMetadata metadata); | |||
| private native void mediaControllerPlaybackStateChanged (long host, PlaybackState state); | |||
| private native void mediaControllerSessionDestroyed (long host); | |||
| MediaControllerCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onAudioInfoChanged (MediaController.PlaybackInfo info) | |||
| { | |||
| mediaControllerAudioInfoChanged (host, info); | |||
| } | |||
| @Override | |||
| public void onMetadataChanged (MediaMetadata metadata) | |||
| { | |||
| mediaControllerMetadataChanged (host, metadata); | |||
| } | |||
| @Override | |||
| public void onPlaybackStateChanged (PlaybackState state) | |||
| { | |||
| mediaControllerPlaybackStateChanged (host, state); | |||
| } | |||
| @Override | |||
| public void onQueueChanged (List<MediaSession.QueueItem> queue) | |||
| { | |||
| } | |||
| @Override | |||
| public void onSessionDestroyed () | |||
| { | |||
| mediaControllerSessionDestroyed (host); | |||
| } | |||
| private long host; | |||
| } | |||
| @@ -1,78 +1,78 @@ | |||
| package com.roli.juce; | |||
| import android.media.session.MediaSession; | |||
| import java.lang.String; | |||
| import android.os.Bundle; | |||
| import android.content.Intent; | |||
| import java.util.List; | |||
| //============================================================================== | |||
| public class MediaSessionCallback extends MediaSession.Callback | |||
| { | |||
| private native void mediaSessionPause (long host); | |||
| private native void mediaSessionPlay (long host); | |||
| private native void mediaSessionPlayFromMediaId (long host, String mediaId, Bundle extras); | |||
| private native void mediaSessionSeekTo (long host, long pos); | |||
| private native void mediaSessionStop (long host); | |||
| MediaSessionCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onPause () | |||
| { | |||
| mediaSessionPause (host); | |||
| } | |||
| @Override | |||
| public void onPlay () | |||
| { | |||
| mediaSessionPlay (host); | |||
| } | |||
| @Override | |||
| public void onPlayFromMediaId (String mediaId, Bundle extras) | |||
| { | |||
| mediaSessionPlayFromMediaId (host, mediaId, extras); | |||
| } | |||
| @Override | |||
| public void onSeekTo (long pos) | |||
| { | |||
| mediaSessionSeekTo (host, pos); | |||
| } | |||
| @Override | |||
| public void onStop () | |||
| { | |||
| mediaSessionStop (host); | |||
| } | |||
| @Override | |||
| public void onFastForward () {} | |||
| @Override | |||
| public boolean onMediaButtonEvent (Intent mediaButtonIntent) | |||
| { | |||
| return true; | |||
| } | |||
| @Override | |||
| public void onRewind () {} | |||
| @Override | |||
| public void onSkipToNext () {} | |||
| @Override | |||
| public void onSkipToPrevious () {} | |||
| @Override | |||
| public void onSkipToQueueItem (long id) {} | |||
| private long host; | |||
| } | |||
| package com.roli.juce; | |||
| import android.media.session.MediaSession; | |||
| import java.lang.String; | |||
| import android.os.Bundle; | |||
| import android.content.Intent; | |||
| import java.util.List; | |||
| //============================================================================== | |||
| public class MediaSessionCallback extends MediaSession.Callback | |||
| { | |||
| private native void mediaSessionPause (long host); | |||
| private native void mediaSessionPlay (long host); | |||
| private native void mediaSessionPlayFromMediaId (long host, String mediaId, Bundle extras); | |||
| private native void mediaSessionSeekTo (long host, long pos); | |||
| private native void mediaSessionStop (long host); | |||
| MediaSessionCallback (long hostToUse) | |||
| { | |||
| host = hostToUse; | |||
| } | |||
| @Override | |||
| public void onPause () | |||
| { | |||
| mediaSessionPause (host); | |||
| } | |||
| @Override | |||
| public void onPlay () | |||
| { | |||
| mediaSessionPlay (host); | |||
| } | |||
| @Override | |||
| public void onPlayFromMediaId (String mediaId, Bundle extras) | |||
| { | |||
| mediaSessionPlayFromMediaId (host, mediaId, extras); | |||
| } | |||
| @Override | |||
| public void onSeekTo (long pos) | |||
| { | |||
| mediaSessionSeekTo (host, pos); | |||
| } | |||
| @Override | |||
| public void onStop () | |||
| { | |||
| mediaSessionStop (host); | |||
| } | |||
| @Override | |||
| public void onFastForward () {} | |||
| @Override | |||
| public boolean onMediaButtonEvent (Intent mediaButtonIntent) | |||
| { | |||
| return true; | |||
| } | |||
| @Override | |||
| public void onRewind () {} | |||
| @Override | |||
| public void onSkipToNext () {} | |||
| @Override | |||
| public void onSkipToPrevious () {} | |||
| @Override | |||
| public void onSkipToQueueItem (long id) {} | |||
| private long host; | |||
| } | |||
| @@ -1,37 +1,37 @@ | |||
| package com.roli.juce; | |||
| import android.database.ContentObserver; | |||
| import android.app.Activity; | |||
| import android.net.Uri; | |||
| //============================================================================== | |||
| public class SystemVolumeObserver extends ContentObserver | |||
| { | |||
| private native void mediaSessionSystemVolumeChanged (long host); | |||
| SystemVolumeObserver (Activity activityToUse, long hostToUse) | |||
| { | |||
| super (null); | |||
| activity = activityToUse; | |||
| host = hostToUse; | |||
| } | |||
| void setEnabled (boolean shouldBeEnabled) | |||
| { | |||
| if (shouldBeEnabled) | |||
| activity.getApplicationContext ().getContentResolver ().registerContentObserver (android.provider.Settings.System.CONTENT_URI, true, this); | |||
| else | |||
| activity.getApplicationContext ().getContentResolver ().unregisterContentObserver (this); | |||
| } | |||
| @Override | |||
| public void onChange (boolean selfChange, Uri uri) | |||
| { | |||
| if (uri.toString ().startsWith ("content://settings/system/volume_music")) | |||
| mediaSessionSystemVolumeChanged (host); | |||
| } | |||
| private Activity activity; | |||
| private long host; | |||
| } | |||
| package com.roli.juce; | |||
| import android.database.ContentObserver; | |||
| import android.app.Activity; | |||
| import android.net.Uri; | |||
| //============================================================================== | |||
| public class SystemVolumeObserver extends ContentObserver | |||
| { | |||
| private native void mediaSessionSystemVolumeChanged (long host); | |||
| SystemVolumeObserver (Activity activityToUse, long hostToUse) | |||
| { | |||
| super (null); | |||
| activity = activityToUse; | |||
| host = hostToUse; | |||
| } | |||
| void setEnabled (boolean shouldBeEnabled) | |||
| { | |||
| if (shouldBeEnabled) | |||
| activity.getApplicationContext ().getContentResolver ().registerContentObserver (android.provider.Settings.System.CONTENT_URI, true, this); | |||
| else | |||
| activity.getApplicationContext ().getContentResolver ().unregisterContentObserver (this); | |||
| } | |||
| @Override | |||
| public void onChange (boolean selfChange, Uri uri) | |||
| { | |||
| if (uri.toString ().startsWith ("content://settings/system/volume_music")) | |||
| mediaSessionSystemVolumeChanged (host); | |||
| } | |||
| private Activity activity; | |||
| private long host; | |||
| } | |||