mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Add camera support for iOS and Android.
This commit is contained in:
parent
bac6996d98
commit
772185f2b0
75 changed files with 6619 additions and 421 deletions
|
|
@ -4,6 +4,33 @@ JUCE breaking changes
|
|||
Develop
|
||||
=======
|
||||
|
||||
Change
|
||||
------
|
||||
CameraDevice::Listener::imageReceived() has been replaced by a new function
|
||||
CameraDevice::takeStillPicture(). The callback passed in takeStillPicture()
|
||||
will always be triggered on the message thread.
|
||||
|
||||
Possible Issues
|
||||
---------------
|
||||
The code handling image capture needs to be adjusted to work well on a message
|
||||
thread. This means that you should not perform any lengthy operations in your
|
||||
callback, as this will stall your UI.
|
||||
|
||||
Workaround
|
||||
----------
|
||||
Use CameraDevice::takeStillPicture() instead of old listener callback. Pass
|
||||
your lambda or other std::function compliant object to takeStillPicture which
|
||||
will be called for you when the capture has finished. If you want to perform
|
||||
any time consuming operation upon receiving the picture, schedule it on a
|
||||
separate worker thread.
|
||||
|
||||
Rationale
|
||||
---------
|
||||
The old Listener interface was not working in a typical listener pattern. It
|
||||
feels more natural to request still picture capture with a dedicated function.
|
||||
This is also more compliant with async mobile APIs.
|
||||
|
||||
|
||||
Change
|
||||
------
|
||||
JUCE no longer supports OS X deployment targets earlier than 10.7.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ SET(BINARY_NAME "juce_jni")
|
|||
add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")
|
||||
set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression")
|
||||
|
||||
add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_roli_juce_demorunner_DemoRunner" "-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/roli/juce/demorunner/DemoRunner\"" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSNAME=com_roli_juce_demorunner_SharingContentProvider" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSPATH=\"com/roli/juce/demorunner/SharingContentProvider\"" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.3.1" "-DJUCE_APP_VERSION_HEX=0x50301")
|
||||
add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_juce_demorunner_DemoRunner" "-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/juce/demorunner/DemoRunner\"" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSNAME=com_juce_demorunner_SharingContentProvider" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSPATH=\"com/juce/demorunner/SharingContentProvider\"" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.3.1" "-DJUCE_APP_VERSION_HEX=0x50301")
|
||||
|
||||
include_directories( AFTER
|
||||
"../../../JuceLibraryCode"
|
||||
|
|
@ -546,6 +546,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"
|
||||
"../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SortedSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.h"
|
||||
|
|
@ -1465,6 +1466,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_video/capture/juce_CameraDevice.cpp"
|
||||
"../../../../../modules/juce_video/capture/juce_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_android_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_ios_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_mac_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_mac_Video.h"
|
||||
"../../../../../modules/juce_video/native/juce_win32_CameraDevice.h"
|
||||
|
|
@ -2008,6 +2010,7 @@ set_source_files_properties("../../../../../modules/juce_core/containers/juce_Pr
|
|||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SortedSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
|
@ -2927,6 +2930,7 @@ set_source_files_properties("../../../../../modules/juce_product_unlocking/juce_
|
|||
set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_android_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_ios_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_Video.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_win32_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ android {
|
|||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.roli.juce.demorunner"
|
||||
applicationId "com.juce.demorunner"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 23
|
||||
externalNativeBuild {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="5.3.1"
|
||||
package="com.roli.juce.demorunner">
|
||||
package="com.juce.demorunner">
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
|
||||
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
|
@ -9,18 +9,19 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-feature android:glEsVersion="0x00030000" android:required="true"/>
|
||||
<application android:label="@string/app_name" android:icon="@drawable/icon" android:hardwareAccelerated="false">
|
||||
<activity android:name="DemoRunner" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:screenOrientation="userLandscape" android:launchMode="singleTask" android:hardwareAccelerated="true">
|
||||
android:screenOrientation="unspecified" android:launchMode="singleTask" android:hardwareAccelerated="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<provider android:name="com.roli.juce.demorunner.SharingContentProvider" android:authorities="com.roli.juce.demorunner.sharingcontentprovider"
|
||||
<provider android:name="com.juce.demorunner.SharingContentProvider" android:authorities="com.juce.demorunner.sharingcontentprovider"
|
||||
android:grantUriPermissions="true" android:exported="false"/>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import android.content.Intent;
|
|||
import android.content.res.Configuration;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.camera2.*;
|
||||
import android.net.http.SslError;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -119,6 +120,7 @@ public class DemoRunner extends Activity
|
|||
private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2;
|
||||
private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3;
|
||||
private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4;
|
||||
private static final int JUCE_PERMISSIONS_CAMERA = 5;
|
||||
|
||||
private static String getAndroidPermissionName (int permissionID)
|
||||
{
|
||||
|
|
@ -129,6 +131,7 @@ public class DemoRunner extends Activity
|
|||
// use string value as this is not defined in SDKs < 16
|
||||
case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE";
|
||||
case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
case JUCE_PERMISSIONS_CAMERA: return Manifest.permission.CAMERA;
|
||||
}
|
||||
|
||||
// unknown permission ID!
|
||||
|
|
@ -1205,6 +1208,7 @@ public class DemoRunner extends Activity
|
|||
setVolumeControlStream (AudioManager.STREAM_MUSIC);
|
||||
|
||||
permissionCallbackPtrMap = new HashMap<Integer, Long>();
|
||||
appPausedResumedListeners = new HashMap<Long, AppPausedResumedListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1221,6 +1225,11 @@ public class DemoRunner extends Activity
|
|||
{
|
||||
suspendApp();
|
||||
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appPaused();
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down
|
||||
|
|
@ -1236,12 +1245,10 @@ public class DemoRunner extends Activity
|
|||
super.onResume();
|
||||
resumeApp();
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
for (int i = 0; i < viewHolder.getChildCount(); ++i)
|
||||
{
|
||||
if (viewHolder.getChildAt (i) instanceof ComponentPeerView)
|
||||
((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();
|
||||
}
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appResumed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1368,11 +1375,14 @@ public class DemoRunner extends Activity
|
|||
{
|
||||
ComponentPeerView v = new ComponentPeerView (this, opaque, host);
|
||||
viewHolder.addView (v);
|
||||
addAppPausedResumedListener (v, host);
|
||||
return v;
|
||||
}
|
||||
|
||||
public final void deleteView (ComponentPeerView view)
|
||||
{
|
||||
removeAppPausedResumedListener (view, view.host);
|
||||
|
||||
view.host = 0;
|
||||
|
||||
ViewGroup group = (ViewGroup) (view.getParent());
|
||||
|
|
@ -1590,9 +1600,28 @@ public class DemoRunner extends Activity
|
|||
|
||||
public native void alertDismissed (long callback, int id);
|
||||
|
||||
//==============================================================================
|
||||
public interface AppPausedResumedListener
|
||||
{
|
||||
void appPaused();
|
||||
void appResumed();
|
||||
}
|
||||
|
||||
private Map<Long, AppPausedResumedListener> appPausedResumedListeners;
|
||||
|
||||
public void addAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.put (new Long (listenerHost), l);
|
||||
}
|
||||
|
||||
public void removeAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.remove (new Long (listenerHost));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public final class ComponentPeerView extends ViewGroup
|
||||
implements View.OnFocusChangeListener
|
||||
implements View.OnFocusChangeListener, AppPausedResumedListener
|
||||
{
|
||||
public ComponentPeerView (Context context, boolean opaque_, long host)
|
||||
{
|
||||
|
|
@ -1940,13 +1969,25 @@ public class DemoRunner extends Activity
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
private native void handleAppPaused (long host);
|
||||
private native void handleAppResumed (long host);
|
||||
|
||||
@Override
|
||||
public void appPaused()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
handleAppPaused (host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appResumed()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
handleAppResumed (host);
|
||||
}
|
||||
}
|
||||
|
|
@ -2616,6 +2657,179 @@ public class DemoRunner extends Activity
|
|||
private final Object hostLock = new Object();
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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 cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId);
|
||||
private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber);
|
||||
private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request,
|
||||
long timestamp, 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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
public static final String getLocaleValue (boolean isRegion)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@
|
|||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
|
||||
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner;
|
||||
SDKROOT_ppc = macosx10.5;
|
||||
USE_HEADERMAP = NO; }; name = Debug; };
|
||||
69330F27DD2C71609336C7D2 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
|
|
@ -296,7 +296,7 @@
|
|||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
|
||||
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner;
|
||||
SDKROOT_ppc = macosx10.5;
|
||||
USE_HEADERMAP = NO; }; name = Release; };
|
||||
C01EC82F42B640CA1E54AD53 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<key>CFBundleIconFile</key>
|
||||
<string>Icon.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.roli.juce.demorunner</string>
|
||||
<string>com.juce.demorunner</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>DemoRunner</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
|
|
|
|||
|
|
@ -772,6 +772,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2836,6 +2839,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_product_unlocking\juce_product_unlocking.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -1141,6 +1141,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4821,6 +4824,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -772,6 +772,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2836,6 +2839,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_product_unlocking\juce_product_unlocking.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -1141,6 +1141,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4821,6 +4824,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -772,6 +772,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2836,6 +2839,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_product_unlocking\juce_product_unlocking.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -1141,6 +1141,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4821,6 +4824,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
6A61CBB4E39BFD392D97528F = {isa = PBXBuildFile; fileRef = 61AE09C749B007B70A265D9B; };
|
||||
0B0CE6D5062E5C02A41F24BC = {isa = PBXBuildFile; fileRef = 873F9DD54978E601102353B4; };
|
||||
5E4310B3F6BB639875D3E9B8 = {isa = PBXBuildFile; fileRef = 49ECA8B998B339A083674A22; };
|
||||
AE7FB2AC3885F4BF53A5DDA1 = {isa = PBXBuildFile; fileRef = 7983C452610C1638B7E78F12; };
|
||||
1FB200F4AE3E4E7CDFF629BB = {isa = PBXBuildFile; fileRef = 24D74AF1C95BEF957DC4FA77; };
|
||||
AC783ECD84496E0B77911EEE = {isa = PBXBuildFile; fileRef = 34F1320BC5C23702C08DF9F0; };
|
||||
B1981F62F6A91FD2F579A198 = {isa = PBXBuildFile; fileRef = 23CD1A3F9067C3A0ECE7BB67; };
|
||||
|
|
@ -92,6 +93,7 @@
|
|||
6C5E26B4D28F8450435B8AE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
72129757D2A553B90A7157C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
|
||||
76A157A111866670A4678F04 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
7983C452610C1638B7E78F12 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
|
||||
7A5AAE9EE573FC6105CC4AAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SettingsContent.h; path = ../../Source/UI/SettingsContent.h; sourceTree = "SOURCE_ROOT"; };
|
||||
8135645508EEFDBDCDF2ADC6 = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = DemoRunner/Images.xcassets; sourceTree = "SOURCE_ROOT"; };
|
||||
831A01C745C905F5715CD822 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_blocks_basics.cpp"; path = "../../JuceLibraryCode/include_juce_blocks_basics.cpp"; sourceTree = "SOURCE_ROOT"; };
|
||||
|
|
@ -209,6 +211,7 @@
|
|||
61AE09C749B007B70A265D9B,
|
||||
873F9DD54978E601102353B4,
|
||||
49ECA8B998B339A083674A22,
|
||||
7983C452610C1638B7E78F12,
|
||||
24D74AF1C95BEF957DC4FA77,
|
||||
34F1320BC5C23702C08DF9F0,
|
||||
23CD1A3F9067C3A0ECE7BB67,
|
||||
|
|
@ -256,7 +259,7 @@
|
|||
INFOPLIST_PREPROCESS = NO;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner;
|
||||
USE_HEADERMAP = NO; }; name = Debug; };
|
||||
69330F27DD2C71609336C7D2 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
|
|
@ -293,7 +296,7 @@
|
|||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
LLVM_LTO = YES;
|
||||
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner;
|
||||
USE_HEADERMAP = NO; }; name = Release; };
|
||||
C01EC82F42B640CA1E54AD53 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
|
|
@ -428,6 +431,7 @@
|
|||
6A61CBB4E39BFD392D97528F,
|
||||
0B0CE6D5062E5C02A41F24BC,
|
||||
5E4310B3F6BB639875D3E9B8,
|
||||
AE7FB2AC3885F4BF53A5DDA1,
|
||||
1FB200F4AE3E4E7CDFF629BB,
|
||||
AC783ECD84496E0B77911EEE,
|
||||
B1981F62F6A91FD2F579A198,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@
|
|||
<true/>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>This is an audio app which requires audio input. If you do not have a USB audio interface connected it will use the microphone.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>This app requires camera usage to function properly.</string>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.roli.juce.demorunner</string>
|
||||
<string>com.juce.demorunner</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>DemoRunner</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
|
|
@ -39,6 +41,7 @@
|
|||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<JUCERPROJECT name="DemoRunner" projectType="guiapp" jucerVersion="5.3.1" defines="JUCE_DEMO_RUNNER=1 JUCE_UNIT_TESTS=1"
|
||||
bundleIdentifier="com.roli.juce.demorunner" version="5.3.1" companyName="ROLI Ltd."
|
||||
bundleIdentifier="com.juce.demorunner" version="5.3.1" companyName="ROLI Ltd."
|
||||
companyCopyright="Copyright (c) 2018 - ROLI Ltd." companyWebsite="https://www.juce.com/"
|
||||
companyEmail="info@juce.com" id="yj7xMM">
|
||||
companyEmail="info@juce.com" id="yj7xMM" reportAppUsage="1">
|
||||
<MAINGROUP id="G8kbr7" name="DemoRunner">
|
||||
<GROUP id="{20E3F84A-29E9-D5FF-4559-1A9E4A70CD60}" name="Source">
|
||||
<GROUP id="{272A692A-6AFE-68BD-C8E8-63B3D62245B1}" name="Demos">
|
||||
|
|
@ -88,10 +88,10 @@
|
|||
</MODULEPATHS>
|
||||
</LINUX_MAKE>
|
||||
<ANDROIDSTUDIO targetFolder="Builds/Android" androidSDKPath="" androidNDKPath=""
|
||||
androidMinimumSDK="23" androidScreenOrientation="landscape" microphonePermissionNeeded="1"
|
||||
androidBluetoothNeeded="1" androidExternalReadNeeded="1" androidExternalWriteNeeded="1"
|
||||
androidMinimumSDK="23" microphonePermissionNeeded="1" androidBluetoothNeeded="1"
|
||||
androidExternalReadNeeded="1" androidExternalWriteNeeded="1"
|
||||
androidEnableContentSharing="1" androidExtraAssetsFolder="../Assets"
|
||||
smallIcon="YyqWd2" bigIcon="YyqWd2">
|
||||
smallIcon="YyqWd2" bigIcon="YyqWd2" cameraPermissionNeeded="1">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION isDebug="1" name="Debug" androidArchitectures="armeabi x86"/>
|
||||
<CONFIGURATION isDebug="0" name="Release"/>
|
||||
|
|
@ -119,10 +119,10 @@
|
|||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</ANDROIDSTUDIO>
|
||||
<XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="landscape" iPadScreenOrientation="landscape"
|
||||
UISupportsDocumentBrowser="1" microphonePermissionNeeded="1"
|
||||
iCloudPermissions="1" UIFileSharingEnabled="1" customXcodeResourceFolders="../Assets"
|
||||
smallIcon="YyqWd2" bigIcon="YyqWd2" extraCompilerFlags="-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code">
|
||||
<XCODE_IPHONE targetFolder="Builds/iOS" UISupportsDocumentBrowser="1" microphonePermissionNeeded="1"
|
||||
cameraPermissionNeeded="1" iCloudPermissions="1" UIFileSharingEnabled="1"
|
||||
customXcodeResourceFolders="../Assets" smallIcon="YyqWd2" bigIcon="YyqWd2"
|
||||
extraCompilerFlags="-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wno-ignored-qualifiers -Wunreachable-code">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION isDebug="1" name="Debug"/>
|
||||
<CONFIGURATION isDebug="0" name="Release"/>
|
||||
|
|
|
|||
|
|
@ -156,6 +156,10 @@
|
|||
//#define JUCE_PLUGINHOST_AU 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_LADSPA
|
||||
//#define JUCE_PLUGINHOST_LADSPA 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_utils flags:
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "../../../GUI/AnimationAppDemo.h"
|
||||
#include "../../../GUI/AnimationDemo.h"
|
||||
#include "../../../GUI/BouncingBallWavetableDemo.h"
|
||||
#if JUCE_MAC || JUCE_WINDOWS
|
||||
#if JUCE_USE_CAMERA && ! JUCE_LINUX
|
||||
#include "../../../GUI/CameraDemo.h"
|
||||
#endif
|
||||
#if ! JUCE_ANDROID
|
||||
|
|
@ -73,7 +73,7 @@ void registerDemos_Two() noexcept
|
|||
REGISTER_DEMO (AnimationAppDemo, GUI, false)
|
||||
REGISTER_DEMO (AnimationDemo, GUI, false)
|
||||
REGISTER_DEMO (BouncingBallWavetableDemo, GUI, false)
|
||||
#if JUCE_MAC || JUCE_WINDOWS
|
||||
#if JUCE_USE_CAMERA && ! JUCE_LINUX
|
||||
REGISTER_DEMO (CameraDemo, GUI, true)
|
||||
#endif
|
||||
#if ! JUCE_ANDROID
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ private:
|
|||
|
||||
#if JUCE_IOS || JUCE_ANDROID
|
||||
setFullScreen (true);
|
||||
Desktop::getInstance().setOrientationsEnabled (Desktop::rotatedClockwise | Desktop::rotatedAntiClockwise);
|
||||
#else
|
||||
setBounds ((int) (0.1f * getParentWidth()),
|
||||
(int) (0.1f * getParentHeight()),
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
dependencies: juce_core, juce_cryptography, juce_data_structures, juce_events,
|
||||
juce_graphics, juce_gui_basics, juce_gui_extra, juce_video
|
||||
exporters: xcode_mac, vs2017, linux_make
|
||||
exporters: xcode_mac, vs2017, androidstudio, xcode_iphone
|
||||
|
||||
moduleFlags: JUCE_USE_CAMERA=1
|
||||
|
||||
|
|
@ -49,15 +49,18 @@
|
|||
#include "../Assets/DemoUtilities.h"
|
||||
|
||||
//==============================================================================
|
||||
class CameraDemo : public Component,
|
||||
private CameraDevice::Listener,
|
||||
private AsyncUpdater
|
||||
class CameraDemo : public Component
|
||||
{
|
||||
public:
|
||||
CameraDemo()
|
||||
{
|
||||
setOpaque (true);
|
||||
|
||||
#if JUCE_ANDROID
|
||||
// Android requires exclusive access to the audio device when recording videos.
|
||||
audioDeviceManager.closeAudioDevice();
|
||||
#endif
|
||||
|
||||
addAndMakeVisible (cameraSelectorComboBox);
|
||||
updateCameraList();
|
||||
cameraSelectorComboBox.setSelectedId (1);
|
||||
|
|
@ -76,6 +79,21 @@ public:
|
|||
cameraSelectorComboBox.setSelectedId (2);
|
||||
|
||||
setSize (500, 500);
|
||||
|
||||
#if JUCE_IOS || JUCE_ANDROID
|
||||
setPortraitOrientationEnabled (true);
|
||||
#endif
|
||||
}
|
||||
|
||||
~CameraDemo()
|
||||
{
|
||||
#if JUCE_IOS || JUCE_ANDROID
|
||||
setPortraitOrientationEnabled (false);
|
||||
#endif
|
||||
|
||||
#if JUCE_ANDROID
|
||||
audioDeviceManager.restartLastAudioDevice();
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -101,26 +119,66 @@ public:
|
|||
recordMovieButton.setBounds (top.removeFromLeft (recordMovieButton.getWidth()));
|
||||
|
||||
r.removeFromTop (4);
|
||||
auto previewArea = r.removeFromTop (r.getHeight() / 2);
|
||||
auto previewArea = shouldUseLandscapeLayout() ? r.removeFromLeft (r.getWidth() / 2)
|
||||
: r.removeFromTop (r.getHeight() / 2);
|
||||
|
||||
if (cameraPreviewComp.get() != nullptr)
|
||||
cameraPreviewComp->setBounds (previewArea);
|
||||
|
||||
r.removeFromTop (4);
|
||||
if (shouldUseLandscapeLayout())
|
||||
r.removeFromLeft (4);
|
||||
else
|
||||
r.removeFromTop (4);
|
||||
|
||||
lastSnapshot.setBounds (r);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// if this PIP is running inside the demo runner, we'll use the shared device manager instead
|
||||
#ifndef JUCE_DEMO_RUNNER
|
||||
AudioDeviceManager audioDeviceManager;
|
||||
#else
|
||||
AudioDeviceManager& audioDeviceManager { getSharedAudioDeviceManager (0, 2) };
|
||||
#endif
|
||||
|
||||
std::unique_ptr<CameraDevice> cameraDevice;
|
||||
std::unique_ptr<Component> cameraPreviewComp;
|
||||
ImageComponent lastSnapshot;
|
||||
|
||||
ComboBox cameraSelectorComboBox { "Camera" };
|
||||
TextButton snapshotButton { "Take a snapshot" };
|
||||
#if ! JUCE_ANDROID && ! JUCE_IOS
|
||||
TextButton recordMovieButton { "Record a movie (to your desktop)..." };
|
||||
#else
|
||||
TextButton recordMovieButton { "Record a movie" };
|
||||
#endif
|
||||
bool recordingMovie = false;
|
||||
File recordingFile;
|
||||
bool contentSharingPending = false;
|
||||
|
||||
void setPortraitOrientationEnabled (bool shouldBeEnabled)
|
||||
{
|
||||
auto allowedOrientations = Desktop::getInstance().getOrientationsEnabled();
|
||||
|
||||
if (shouldBeEnabled)
|
||||
allowedOrientations |= Desktop::upright;
|
||||
else
|
||||
allowedOrientations &= ~Desktop::upright;
|
||||
|
||||
Desktop::getInstance().setOrientationsEnabled (allowedOrientations);
|
||||
}
|
||||
|
||||
bool shouldUseLandscapeLayout() const noexcept
|
||||
{
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
auto orientation = Desktop::getInstance().getCurrentOrientation();
|
||||
return orientation == Desktop::rotatedClockwise || orientation == Desktop::rotatedAntiClockwise;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void updateCameraList()
|
||||
{
|
||||
|
|
@ -137,25 +195,68 @@ private:
|
|||
void cameraChanged()
|
||||
{
|
||||
// This is called when the user chooses a camera from the drop-down list.
|
||||
cameraDevice .reset();
|
||||
#if JUCE_IOS
|
||||
// On iOS, when switching camera, open the new camera first, so that it can
|
||||
// share the underlying camera session with the old camera. Otherwise, the
|
||||
// session would have to be closed first, which can take several seconds.
|
||||
if (cameraSelectorComboBox.getSelectedId() == 1)
|
||||
cameraDevice.reset();
|
||||
#else
|
||||
cameraDevice.reset();
|
||||
#endif
|
||||
cameraPreviewComp.reset();
|
||||
recordingMovie = false;
|
||||
|
||||
if (cameraSelectorComboBox.getSelectedId() > 1)
|
||||
{
|
||||
// Try to open the user's choice of camera..
|
||||
cameraDevice.reset (CameraDevice::openDevice (cameraSelectorComboBox.getSelectedId() - 2));
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
openCameraAsync();
|
||||
#else
|
||||
cameraDeviceOpenResult (CameraDevice::openDevice (cameraSelectorComboBox.getSelectedId() - 2), {});
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
snapshotButton .setEnabled (cameraDevice != nullptr && ! contentSharingPending);
|
||||
recordMovieButton.setEnabled (cameraDevice != nullptr && ! contentSharingPending);
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
// and if it worked, create a preview component for it..
|
||||
if (cameraDevice.get() != nullptr)
|
||||
{
|
||||
cameraPreviewComp.reset (cameraDevice->createViewerComponent());
|
||||
addAndMakeVisible (cameraPreviewComp.get());
|
||||
}
|
||||
void openCameraAsync()
|
||||
{
|
||||
SafePointer<CameraDemo> safeThis (this);
|
||||
|
||||
CameraDevice::openDeviceAsync (cameraSelectorComboBox.getSelectedId() - 2,
|
||||
[safeThis] (CameraDevice* device, const String& error) mutable
|
||||
{
|
||||
if (safeThis)
|
||||
safeThis->cameraDeviceOpenResult (device, error);
|
||||
});
|
||||
}
|
||||
|
||||
void cameraDeviceOpenResult (CameraDevice* device, const String& error)
|
||||
{
|
||||
// If camera opening worked, create a preview component for it..
|
||||
cameraDevice.reset (device);
|
||||
|
||||
if (cameraDevice.get() != nullptr)
|
||||
{
|
||||
#if JUCE_ANDROID
|
||||
SafePointer<CameraDemo> safeThis (this);
|
||||
cameraDevice->onErrorOccurred = [safeThis] (const String& error) mutable { if (safeThis) safeThis->errorOccurred (error); };
|
||||
#endif
|
||||
cameraPreviewComp.reset (cameraDevice->createViewerComponent());
|
||||
addAndMakeVisible (cameraPreviewComp.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Camera open failed",
|
||||
"Camera open failed, reason: " + error);
|
||||
}
|
||||
|
||||
snapshotButton .setEnabled (cameraDevice.get() != nullptr);
|
||||
recordMovieButton.setEnabled (cameraDevice.get() != nullptr);
|
||||
snapshotButton .setEnabled (cameraDevice.get() != nullptr && ! contentSharingPending);
|
||||
recordMovieButton.setEnabled (cameraDevice.get() != nullptr && ! contentSharingPending);
|
||||
resized();
|
||||
}
|
||||
|
||||
|
|
@ -169,10 +270,20 @@ private:
|
|||
// Start recording to a file on the user's desktop..
|
||||
recordingMovie = true;
|
||||
|
||||
auto file = File::getSpecialLocation (File::userDesktopDirectory)
|
||||
.getNonexistentChildFile ("JuceCameraDemo", CameraDevice::getFileExtension());
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
recordingFile = File::getSpecialLocation (File::tempDirectory)
|
||||
#else
|
||||
recordingFile = File::getSpecialLocation (File::userDesktopDirectory)
|
||||
#endif
|
||||
.getNonexistentChildFile ("JuceCameraVideoDemo", CameraDevice::getFileExtension());
|
||||
|
||||
cameraDevice->startRecordingToFile (file);
|
||||
#if JUCE_ANDROID
|
||||
// Android does not support taking pictures while recording video.
|
||||
snapshotButton.setEnabled (false);
|
||||
#endif
|
||||
|
||||
cameraSelectorComboBox.setEnabled (false);
|
||||
cameraDevice->startRecordingToFile (recordingFile);
|
||||
recordMovieButton.setButtonText ("Stop Recording");
|
||||
}
|
||||
else
|
||||
|
|
@ -180,40 +291,99 @@ private:
|
|||
// Already recording, so stop...
|
||||
recordingMovie = false;
|
||||
cameraDevice->stopRecording();
|
||||
#if ! JUCE_ANDROID && ! JUCE_IOS
|
||||
recordMovieButton.setButtonText ("Start recording (to a file on your desktop)");
|
||||
#else
|
||||
recordMovieButton.setButtonText ("Record a movie");
|
||||
#endif
|
||||
cameraSelectorComboBox.setEnabled (true);
|
||||
|
||||
#if JUCE_ANDROID
|
||||
snapshotButton.setEnabled (true);
|
||||
#endif
|
||||
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
URL url (recordingFile);
|
||||
|
||||
snapshotButton .setEnabled (false);
|
||||
recordMovieButton.setEnabled (false);
|
||||
contentSharingPending = true;
|
||||
|
||||
SafePointer<CameraDemo> safeThis (this);
|
||||
|
||||
juce::ContentSharer::getInstance()->shareFiles ({url},
|
||||
[safeThis] (bool success, const String&) mutable
|
||||
{
|
||||
if (safeThis)
|
||||
safeThis->sharingFinished (success, false);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void takeSnapshot()
|
||||
{
|
||||
// When the user clicks the snapshot button, we'll attach ourselves to
|
||||
// the camera as a listener, and wait for an image to arrive...
|
||||
cameraDevice->addListener (this);
|
||||
SafePointer<CameraDemo> safeThis (this);
|
||||
cameraDevice->takeStillPicture ([safeThis] (const Image& image) mutable { safeThis->imageReceived (image); });
|
||||
}
|
||||
|
||||
// This is called by the camera device when a new image arrives
|
||||
void imageReceived (const Image& image) override
|
||||
void imageReceived (const Image& image)
|
||||
{
|
||||
// In this app we just want to take one image, so as soon as this happens,
|
||||
// we'll unregister ourselves as a listener.
|
||||
if (cameraDevice.get() != nullptr)
|
||||
cameraDevice->removeListener (this);
|
||||
if (! image.isValid())
|
||||
return;
|
||||
|
||||
// This callback won't be on the message thread, so to get the image back to
|
||||
// the message thread, we'll stash a pointer to it (which is reference-counted in
|
||||
// a thead-safe way), and trigger an async callback which will then display the
|
||||
// new image..
|
||||
incomingImage = image;
|
||||
triggerAsyncUpdate();
|
||||
lastSnapshot.setImage (image);
|
||||
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
auto imageFile = File::getSpecialLocation (File::tempDirectory).getNonexistentChildFile ("JuceCameraPhotoDemo", ".jpg");
|
||||
|
||||
if (auto stream = std::unique_ptr<OutputStream> (imageFile.createOutputStream()))
|
||||
{
|
||||
if (JPEGImageFormat().writeImageToStream (image, *stream))
|
||||
{
|
||||
URL url (imageFile);
|
||||
|
||||
snapshotButton .setEnabled (false);
|
||||
recordMovieButton.setEnabled (false);
|
||||
contentSharingPending = true;
|
||||
|
||||
SafePointer<CameraDemo> safeThis (this);
|
||||
|
||||
juce::ContentSharer::getInstance()->shareFiles ({url},
|
||||
[safeThis] (bool success, const String&) mutable
|
||||
{
|
||||
if (safeThis)
|
||||
safeThis->sharingFinished (success, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Image incomingImage;
|
||||
|
||||
void handleAsyncUpdate() override
|
||||
void errorOccurred (const String& error)
|
||||
{
|
||||
if (incomingImage.isValid())
|
||||
lastSnapshot.setImage (incomingImage);
|
||||
AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon,
|
||||
"Camera Device Error",
|
||||
"An error has occurred: " + error + " Camera will be closed.");
|
||||
|
||||
cameraDevice.reset();
|
||||
|
||||
cameraSelectorComboBox.setSelectedId (1);
|
||||
snapshotButton .setEnabled (false);
|
||||
recordMovieButton.setEnabled (false);
|
||||
}
|
||||
|
||||
void sharingFinished (bool success, bool isCapture)
|
||||
{
|
||||
AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon,
|
||||
isCapture ? "Image sharing result" : "Video sharing result",
|
||||
success ? "Success!" : "Failed!");
|
||||
|
||||
contentSharingPending = false;
|
||||
snapshotButton .setEnabled (true);
|
||||
recordMovieButton.setEnabled (true);
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CameraDemo)
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"
|
||||
"../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SortedSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.h"
|
||||
|
|
@ -1566,6 +1567,7 @@ set_source_files_properties("../../../../../modules/juce_core/containers/juce_Pr
|
|||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SortedSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import android.content.Intent;
|
|||
import android.content.res.Configuration;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.camera2.*;
|
||||
import android.net.http.SslError;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -119,6 +120,7 @@ public class AudioPerformanceTest extends Activity
|
|||
private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2;
|
||||
private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3;
|
||||
private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4;
|
||||
private static final int JUCE_PERMISSIONS_CAMERA = 5;
|
||||
|
||||
private static String getAndroidPermissionName (int permissionID)
|
||||
{
|
||||
|
|
@ -129,6 +131,7 @@ public class AudioPerformanceTest extends Activity
|
|||
// use string value as this is not defined in SDKs < 16
|
||||
case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE";
|
||||
case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
case JUCE_PERMISSIONS_CAMERA: return Manifest.permission.CAMERA;
|
||||
}
|
||||
|
||||
// unknown permission ID!
|
||||
|
|
@ -1205,6 +1208,7 @@ public class AudioPerformanceTest extends Activity
|
|||
setVolumeControlStream (AudioManager.STREAM_MUSIC);
|
||||
|
||||
permissionCallbackPtrMap = new HashMap<Integer, Long>();
|
||||
appPausedResumedListeners = new HashMap<Long, AppPausedResumedListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1221,6 +1225,11 @@ public class AudioPerformanceTest extends Activity
|
|||
{
|
||||
suspendApp();
|
||||
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appPaused();
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down
|
||||
|
|
@ -1236,12 +1245,10 @@ public class AudioPerformanceTest extends Activity
|
|||
super.onResume();
|
||||
resumeApp();
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
for (int i = 0; i < viewHolder.getChildCount(); ++i)
|
||||
{
|
||||
if (viewHolder.getChildAt (i) instanceof ComponentPeerView)
|
||||
((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();
|
||||
}
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appResumed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1368,11 +1375,14 @@ public class AudioPerformanceTest extends Activity
|
|||
{
|
||||
ComponentPeerView v = new ComponentPeerView (this, opaque, host);
|
||||
viewHolder.addView (v);
|
||||
addAppPausedResumedListener (v, host);
|
||||
return v;
|
||||
}
|
||||
|
||||
public final void deleteView (ComponentPeerView view)
|
||||
{
|
||||
removeAppPausedResumedListener (view, view.host);
|
||||
|
||||
view.host = 0;
|
||||
|
||||
ViewGroup group = (ViewGroup) (view.getParent());
|
||||
|
|
@ -1590,9 +1600,28 @@ public class AudioPerformanceTest extends Activity
|
|||
|
||||
public native void alertDismissed (long callback, int id);
|
||||
|
||||
//==============================================================================
|
||||
public interface AppPausedResumedListener
|
||||
{
|
||||
void appPaused();
|
||||
void appResumed();
|
||||
}
|
||||
|
||||
private Map<Long, AppPausedResumedListener> appPausedResumedListeners;
|
||||
|
||||
public void addAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.put (new Long (listenerHost), l);
|
||||
}
|
||||
|
||||
public void removeAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.remove (new Long (listenerHost));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public final class ComponentPeerView extends ViewGroup
|
||||
implements View.OnFocusChangeListener
|
||||
implements View.OnFocusChangeListener, AppPausedResumedListener
|
||||
{
|
||||
public ComponentPeerView (Context context, boolean opaque_, long host)
|
||||
{
|
||||
|
|
@ -1940,13 +1969,25 @@ public class AudioPerformanceTest extends Activity
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
private native void handleAppPaused (long host);
|
||||
private native void handleAppResumed (long host);
|
||||
|
||||
@Override
|
||||
public void appPaused()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
handleAppPaused (host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appResumed()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
handleAppResumed (host);
|
||||
}
|
||||
}
|
||||
|
|
@ -2616,6 +2657,175 @@ public class AudioPerformanceTest extends Activity
|
|||
private final Object hostLock = new Object();
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
public static final String getLocaleValue (boolean isRegion)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -596,6 +596,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -817,6 +817,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -147,6 +147,10 @@
|
|||
//#define JUCE_PLUGINHOST_AU 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_LADSPA
|
||||
//#define JUCE_PLUGINHOST_LADSPA 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_utils flags:
|
||||
|
||||
|
|
|
|||
|
|
@ -415,6 +415,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"
|
||||
"../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SortedSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.h"
|
||||
|
|
@ -1250,6 +1251,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_video/capture/juce_CameraDevice.cpp"
|
||||
"../../../../../modules/juce_video/capture/juce_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_android_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_ios_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_mac_CameraDevice.h"
|
||||
"../../../../../modules/juce_video/native/juce_mac_Video.h"
|
||||
"../../../../../modules/juce_video/native/juce_win32_CameraDevice.h"
|
||||
|
|
@ -1653,6 +1655,7 @@ set_source_files_properties("../../../../../modules/juce_core/containers/juce_Pr
|
|||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SortedSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
|
@ -2488,6 +2491,7 @@ set_source_files_properties("../../../../../modules/juce_opengl/juce_opengl.h" P
|
|||
set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_android_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_ios_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_Video.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_video/native/juce_win32_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import android.content.Intent;
|
|||
import android.content.res.Configuration;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.camera2.*;
|
||||
import android.net.http.SslError;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -119,6 +120,7 @@ public class AudioPluginHost extends Activity
|
|||
private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2;
|
||||
private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3;
|
||||
private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4;
|
||||
private static final int JUCE_PERMISSIONS_CAMERA = 5;
|
||||
|
||||
private static String getAndroidPermissionName (int permissionID)
|
||||
{
|
||||
|
|
@ -129,6 +131,7 @@ public class AudioPluginHost extends Activity
|
|||
// use string value as this is not defined in SDKs < 16
|
||||
case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE";
|
||||
case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
case JUCE_PERMISSIONS_CAMERA: return Manifest.permission.CAMERA;
|
||||
}
|
||||
|
||||
// unknown permission ID!
|
||||
|
|
@ -1205,6 +1208,7 @@ public class AudioPluginHost extends Activity
|
|||
setVolumeControlStream (AudioManager.STREAM_MUSIC);
|
||||
|
||||
permissionCallbackPtrMap = new HashMap<Integer, Long>();
|
||||
appPausedResumedListeners = new HashMap<Long, AppPausedResumedListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1221,6 +1225,11 @@ public class AudioPluginHost extends Activity
|
|||
{
|
||||
suspendApp();
|
||||
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appPaused();
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down
|
||||
|
|
@ -1236,12 +1245,10 @@ public class AudioPluginHost extends Activity
|
|||
super.onResume();
|
||||
resumeApp();
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
for (int i = 0; i < viewHolder.getChildCount(); ++i)
|
||||
{
|
||||
if (viewHolder.getChildAt (i) instanceof ComponentPeerView)
|
||||
((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();
|
||||
}
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appResumed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1368,11 +1375,14 @@ public class AudioPluginHost extends Activity
|
|||
{
|
||||
ComponentPeerView v = new ComponentPeerView (this, opaque, host);
|
||||
viewHolder.addView (v);
|
||||
addAppPausedResumedListener (v, host);
|
||||
return v;
|
||||
}
|
||||
|
||||
public final void deleteView (ComponentPeerView view)
|
||||
{
|
||||
removeAppPausedResumedListener (view, view.host);
|
||||
|
||||
view.host = 0;
|
||||
|
||||
ViewGroup group = (ViewGroup) (view.getParent());
|
||||
|
|
@ -1590,9 +1600,28 @@ public class AudioPluginHost extends Activity
|
|||
|
||||
public native void alertDismissed (long callback, int id);
|
||||
|
||||
//==============================================================================
|
||||
public interface AppPausedResumedListener
|
||||
{
|
||||
void appPaused();
|
||||
void appResumed();
|
||||
}
|
||||
|
||||
private Map<Long, AppPausedResumedListener> appPausedResumedListeners;
|
||||
|
||||
public void addAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.put (new Long (listenerHost), l);
|
||||
}
|
||||
|
||||
public void removeAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.remove (new Long (listenerHost));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public final class ComponentPeerView extends ViewGroup
|
||||
implements View.OnFocusChangeListener
|
||||
implements View.OnFocusChangeListener, AppPausedResumedListener
|
||||
{
|
||||
public ComponentPeerView (Context context, boolean opaque_, long host)
|
||||
{
|
||||
|
|
@ -1940,13 +1969,25 @@ public class AudioPluginHost extends Activity
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
private native void handleAppPaused (long host);
|
||||
private native void handleAppResumed (long host);
|
||||
|
||||
@Override
|
||||
public void appPaused()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
handleAppPaused (host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appResumed()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
handleAppResumed (host);
|
||||
}
|
||||
}
|
||||
|
|
@ -2616,6 +2657,175 @@ public class AudioPluginHost extends Activity
|
|||
private final Object hostLock = new Object();
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
public static final String getLocaleValue (boolean isRegion)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -601,6 +601,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2433,6 +2436,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -874,6 +874,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4062,6 +4065,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -601,6 +601,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2433,6 +2436,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -874,6 +874,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4062,6 +4065,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -601,6 +601,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2433,6 +2436,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -874,6 +874,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4062,6 +4065,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -164,6 +164,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -403,6 +403,7 @@ add_library( ${BINARY_NAME}
|
|||
"../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"
|
||||
"../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SortedSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_SparseSet.h"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
|
||||
"../../../../../modules/juce_core/containers/juce_Variant.h"
|
||||
|
|
@ -1645,6 +1646,7 @@ set_source_files_properties("../../../../../modules/juce_core/containers/juce_Pr
|
|||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SortedSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2;
|
||||
private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3;
|
||||
private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4;
|
||||
private static final int JUCE_PERMISSIONS_CAMERA = 5;
|
||||
|
||||
private static String getAndroidPermissionName (int permissionID)
|
||||
{
|
||||
|
|
@ -123,6 +124,7 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
// use string value as this is not defined in SDKs < 16
|
||||
case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE";
|
||||
case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
case JUCE_PERMISSIONS_CAMERA: return Manifest.permission.CAMERA;
|
||||
}
|
||||
|
||||
// unknown permission ID!
|
||||
|
|
@ -273,6 +275,7 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
setVolumeControlStream (AudioManager.STREAM_MUSIC);
|
||||
|
||||
permissionCallbackPtrMap = new HashMap<Integer, Long>();
|
||||
appPausedResumedListeners = new HashMap<Long, AppPausedResumedListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -289,6 +292,11 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
{
|
||||
suspendApp();
|
||||
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appPaused();
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down
|
||||
|
|
@ -304,12 +312,10 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
super.onResume();
|
||||
resumeApp();
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
for (int i = 0; i < viewHolder.getChildCount(); ++i)
|
||||
{
|
||||
if (viewHolder.getChildAt (i) instanceof ComponentPeerView)
|
||||
((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();
|
||||
}
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appResumed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -436,11 +442,14 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
{
|
||||
ComponentPeerView v = new ComponentPeerView (this, opaque, host);
|
||||
viewHolder.addView (v);
|
||||
addAppPausedResumedListener (v, host);
|
||||
return v;
|
||||
}
|
||||
|
||||
public final void deleteView (ComponentPeerView view)
|
||||
{
|
||||
removeAppPausedResumedListener (view, view.host);
|
||||
|
||||
view.host = 0;
|
||||
|
||||
ViewGroup group = (ViewGroup) (view.getParent());
|
||||
|
|
@ -658,9 +667,28 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
|
||||
public native void alertDismissed (long callback, int id);
|
||||
|
||||
//==============================================================================
|
||||
public interface AppPausedResumedListener
|
||||
{
|
||||
void appPaused();
|
||||
void appResumed();
|
||||
}
|
||||
|
||||
private Map<Long, AppPausedResumedListener> appPausedResumedListeners;
|
||||
|
||||
public void addAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.put (new Long (listenerHost), l);
|
||||
}
|
||||
|
||||
public void removeAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.remove (new Long (listenerHost));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public final class ComponentPeerView extends ViewGroup
|
||||
implements View.OnFocusChangeListener
|
||||
implements View.OnFocusChangeListener, AppPausedResumedListener
|
||||
{
|
||||
public ComponentPeerView (Context context, boolean opaque_, long host)
|
||||
{
|
||||
|
|
@ -1008,13 +1036,25 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
private native void handleAppPaused (long host);
|
||||
private native void handleAppResumed (long host);
|
||||
|
||||
@Override
|
||||
public void appPaused()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
handleAppPaused (host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appResumed()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
handleAppResumed (host);
|
||||
}
|
||||
}
|
||||
|
|
@ -1656,6 +1696,7 @@ public class JUCENetworkGraphicsDemo extends Activity
|
|||
private final Object hostLock = new Object();
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
public static final String getLocaleValue (boolean isRegion)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -596,6 +596,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -847,6 +847,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -596,6 +596,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -847,6 +847,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -150,6 +150,10 @@
|
|||
//#define JUCE_PLUGINHOST_AU 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_LADSPA
|
||||
//#define JUCE_PLUGINHOST_LADSPA 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_utils flags:
|
||||
|
||||
|
|
|
|||
|
|
@ -276,6 +276,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -541,6 +541,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -276,6 +276,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -541,6 +541,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -276,6 +276,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -541,6 +541,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public:
|
|||
ValueWithDefault androidJavaLibs, androidRepositories, androidDependencies, androidScreenOrientation, androidActivityClass,
|
||||
androidActivitySubClassName, androidActivityBaseClassName, androidManifestCustomXmlElements, androidVersionCode,
|
||||
androidMinimumSDK, androidTheme, androidSharedLibraries, androidStaticLibraries, androidExtraAssetsFolder,
|
||||
androidOboeRepositoryPath, androidInternetNeeded, androidMicNeeded, androidBluetoothNeeded, androidExternalReadPermission,
|
||||
androidOboeRepositoryPath, androidInternetNeeded, androidMicNeeded, androidCameraNeeded, androidBluetoothNeeded, androidExternalReadPermission,
|
||||
androidExternalWritePermission, androidInAppBillingPermission, androidVibratePermission,androidOtherPermissions,
|
||||
androidEnableRemoteNotifications, androidRemoteNotificationsConfigFile, androidEnableContentSharing, androidKeyStore,
|
||||
androidKeyStorePass, androidKeyAlias, androidKeyAliasPass, gradleVersion, gradleToolchain, androidPluginVersion, buildToolsVersion;
|
||||
|
|
@ -128,6 +128,7 @@ public:
|
|||
androidOboeRepositoryPath (settings, Ids::androidOboeRepositoryPath, getUndoManager()),
|
||||
androidInternetNeeded (settings, Ids::androidInternetNeeded, getUndoManager(), true),
|
||||
androidMicNeeded (settings, Ids::microphonePermissionNeeded, getUndoManager(), false),
|
||||
androidCameraNeeded (settings, Ids::cameraPermissionNeeded, getUndoManager(), false),
|
||||
androidBluetoothNeeded (settings, Ids::androidBluetoothNeeded, getUndoManager(), true),
|
||||
androidExternalReadPermission (settings, Ids::androidExternalReadNeeded, getUndoManager(), true),
|
||||
androidExternalWritePermission (settings, Ids::androidExternalWriteNeeded, getUndoManager(), true),
|
||||
|
|
@ -920,6 +921,9 @@ private:
|
|||
props.add (new ChoicePropertyComponent (androidMicNeeded, "Audio Input Required"),
|
||||
"If enabled, this will set the android.permission.RECORD_AUDIO flag in the manifest.");
|
||||
|
||||
props.add (new ChoicePropertyComponent (androidCameraNeeded, "Camera Required"),
|
||||
"If enabled, this will set the android.permission.CAMERA flag in the manifest.");
|
||||
|
||||
props.add (new ChoicePropertyComponent (androidBluetoothNeeded, "Bluetooth permissions Required"),
|
||||
"If enabled, this will set the android.permission.BLUETOOTH and android.permission.BLUETOOTH_ADMIN flag in the manifest. This is required for Bluetooth MIDI on Android.");
|
||||
|
||||
|
|
@ -1034,25 +1038,92 @@ private:
|
|||
|
||||
createDirectoryOrThrow (targetFolder);
|
||||
|
||||
auto activityCode = getActivityCode (javaSourceFolder, className, package);
|
||||
|
||||
auto javaDestFile = targetFolder.getChildFile (className + ".java");
|
||||
overwriteFileIfDifferentOrThrow (javaDestFile, activityCode);
|
||||
}
|
||||
|
||||
String getActivityCode (const File& javaSourceFolder, const String& className, const String& package) const
|
||||
{
|
||||
auto runtimePermissionsCode = getRuntimePermissionsCode (javaSourceFolder, className);
|
||||
auto midiCode = getMidiCode (javaSourceFolder, className);
|
||||
auto webViewCode = getWebViewCode (javaSourceFolder);
|
||||
auto cameraCode = getCameraCode (javaSourceFolder);
|
||||
|
||||
String juceMidiCode, juceMidiImports, juceRuntimePermissionsCode;
|
||||
auto javaSourceFile = javaSourceFolder.getChildFile ("JuceAppActivity.java");
|
||||
auto javaSourceLines = StringArray::fromLines (javaSourceFile.loadFileAsString());
|
||||
|
||||
{
|
||||
MemoryOutputStream newFile;
|
||||
|
||||
for (auto& line : javaSourceLines)
|
||||
{
|
||||
if (line.contains ("$$JuceAndroidMidiImports$$"))
|
||||
newFile << midiCode.imports;
|
||||
else if (line.contains ("$$JuceAndroidMidiCode$$"))
|
||||
newFile << midiCode.main;
|
||||
else if (line.contains ("$$JuceAndroidRuntimePermissionsCode$$"))
|
||||
newFile << runtimePermissionsCode;
|
||||
else if (line.contains ("$$JuceAndroidWebViewImports$$"))
|
||||
newFile << webViewCode.imports;
|
||||
else if (line.contains ("$$JuceAndroidWebViewNativeCode$$"))
|
||||
newFile << webViewCode.native;
|
||||
else if (line.contains ("$$JuceAndroidWebViewCode$$"))
|
||||
newFile << webViewCode.main;
|
||||
else if (line.contains ("$$JuceAndroidCameraImports$$"))
|
||||
newFile << cameraCode.imports;
|
||||
else if (line.contains ("$$JuceAndroidCameraCode$$"))
|
||||
newFile << cameraCode.main;
|
||||
else
|
||||
newFile << line.replace ("$$JuceAppActivityBaseClass$$", androidActivityBaseClassName.get().toString())
|
||||
.replace ("JuceAppActivity", className)
|
||||
.replace ("package com.juce;", "package " + package + ";") << newLine;
|
||||
}
|
||||
|
||||
javaSourceLines = StringArray::fromLines (newFile.toString());
|
||||
}
|
||||
|
||||
while (javaSourceLines.size() > 2
|
||||
&& javaSourceLines[javaSourceLines.size() - 1].trim().isEmpty()
|
||||
&& javaSourceLines[javaSourceLines.size() - 2].trim().isEmpty())
|
||||
javaSourceLines.remove (javaSourceLines.size() - 1);
|
||||
|
||||
return javaSourceLines.joinIntoString (newLine);
|
||||
}
|
||||
|
||||
String getRuntimePermissionsCode (const File& javaSourceFolder, const String& className) const
|
||||
{
|
||||
if (static_cast<int> (androidMinimumSDK.get()) >= 23)
|
||||
{
|
||||
auto javaRuntimePermissions = javaSourceFolder.getChildFile ("AndroidRuntimePermissions.java");
|
||||
return javaRuntimePermissions.loadFileAsString().replace ("JuceAppActivity", className);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
struct MidiCode
|
||||
{
|
||||
String imports;
|
||||
String main;
|
||||
};
|
||||
|
||||
MidiCode getMidiCode (const File& javaSourceFolder, const String& className) const
|
||||
{
|
||||
String juceMidiCode, juceMidiImports;
|
||||
|
||||
juceMidiImports << newLine;
|
||||
|
||||
if (static_cast<int> (androidMinimumSDK.get()) >= 23)
|
||||
{
|
||||
auto javaAndroidMidi = javaSourceFolder.getChildFile ("AndroidMidi.java");
|
||||
auto javaRuntimePermissions = javaSourceFolder.getChildFile ("AndroidRuntimePermissions.java");
|
||||
|
||||
juceMidiImports << "import android.media.midi.*;" << newLine
|
||||
<< "import android.bluetooth.*;" << newLine
|
||||
<< "import android.bluetooth.le.*;" << newLine;
|
||||
|
||||
juceMidiCode = javaAndroidMidi.loadFileAsString().replace ("JuceAppActivity", className);
|
||||
|
||||
juceRuntimePermissionsCode = javaRuntimePermissions.loadFileAsString().replace ("JuceAppActivity", className);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1061,6 +1132,18 @@ private:
|
|||
.replace ("JuceAppActivity", className);
|
||||
}
|
||||
|
||||
return { juceMidiImports, juceMidiCode };
|
||||
}
|
||||
|
||||
struct WebViewCode
|
||||
{
|
||||
String imports;
|
||||
String native;
|
||||
String main;
|
||||
};
|
||||
|
||||
WebViewCode getWebViewCode (const File& javaSourceFolder) const
|
||||
{
|
||||
String juceWebViewImports, juceWebViewCodeNative, juceWebViewCode;
|
||||
|
||||
if (static_cast<int> (androidMinimumSDK.get()) >= 23)
|
||||
|
|
@ -1106,41 +1189,32 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
auto javaSourceFile = javaSourceFolder.getChildFile ("JuceAppActivity.java");
|
||||
auto javaSourceLines = StringArray::fromLines (javaSourceFile.loadFileAsString());
|
||||
return { juceWebViewImports, juceWebViewCodeNative, juceWebViewCode };
|
||||
}
|
||||
|
||||
struct CameraCode
|
||||
{
|
||||
String imports;
|
||||
String main;
|
||||
};
|
||||
|
||||
CameraCode getCameraCode (const File& javaSourceFolder) const
|
||||
{
|
||||
String juceCameraImports, juceCameraCode;
|
||||
|
||||
if (static_cast<int> (androidMinimumSDK.get()) >= 21)
|
||||
juceCameraImports << "import android.hardware.camera2.*;" << newLine;
|
||||
|
||||
auto javaCameraFile = javaSourceFolder.getChildFile ("AndroidCamera.java");
|
||||
auto juceCameraCodeAll = javaCameraFile.loadFileAsString();
|
||||
|
||||
if (static_cast<int> (androidMinimumSDK.get()) >= 21)
|
||||
{
|
||||
MemoryOutputStream newFile;
|
||||
|
||||
for (auto& line : javaSourceLines)
|
||||
{
|
||||
if (line.contains ("$$JuceAndroidMidiImports$$"))
|
||||
newFile << juceMidiImports;
|
||||
else if (line.contains ("$$JuceAndroidMidiCode$$"))
|
||||
newFile << juceMidiCode;
|
||||
else if (line.contains ("$$JuceAndroidRuntimePermissionsCode$$"))
|
||||
newFile << juceRuntimePermissionsCode;
|
||||
else if (line.contains ("$$JuceAndroidWebViewImports$$"))
|
||||
newFile << juceWebViewImports;
|
||||
else if (line.contains ("$$JuceAndroidWebViewNativeCode$$"))
|
||||
newFile << juceWebViewCodeNative;
|
||||
else if (line.contains ("$$JuceAndroidWebViewCode$$"))
|
||||
newFile << juceWebViewCode;
|
||||
else
|
||||
newFile << line.replace ("$$JuceAppActivityBaseClass$$", androidActivityBaseClassName.get().toString())
|
||||
.replace ("JuceAppActivity", className)
|
||||
.replace ("package com.juce;", "package " + package + ";") << newLine;
|
||||
}
|
||||
|
||||
javaSourceLines = StringArray::fromLines (newFile.toString());
|
||||
juceCameraCode << juceCameraCodeAll.fromFirstOccurrenceOf ("$$CameraApi21", false, false)
|
||||
.upToFirstOccurrenceOf ("CameraApi21$$", false, false);
|
||||
}
|
||||
|
||||
while (javaSourceLines.size() > 2
|
||||
&& javaSourceLines[javaSourceLines.size() - 1].trim().isEmpty()
|
||||
&& javaSourceLines[javaSourceLines.size() - 2].trim().isEmpty())
|
||||
javaSourceLines.remove (javaSourceLines.size() - 1);
|
||||
|
||||
overwriteFileIfDifferentOrThrow (javaDestFile, javaSourceLines.joinIntoString (newLine));
|
||||
return { juceCameraImports, juceCameraCode };
|
||||
}
|
||||
|
||||
void copyAdditionalJavaFiles (const File& sourceFolder, const File& targetFolder) const
|
||||
|
|
@ -1882,6 +1956,9 @@ private:
|
|||
if (androidMicNeeded.get())
|
||||
s.add ("android.permission.RECORD_AUDIO");
|
||||
|
||||
if (androidCameraNeeded.get())
|
||||
s.add ("android.permission.CAMERA");
|
||||
|
||||
if (androidBluetoothNeeded.get())
|
||||
{
|
||||
s.add ("android.permission.BLUETOOTH");
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ public:
|
|||
microphonePermissionNeededValue (settings, Ids::microphonePermissionNeeded, getUndoManager()),
|
||||
microphonePermissionsTextValue (settings, Ids::microphonePermissionsText, getUndoManager(),
|
||||
"This is an audio app which requires audio input. If you do not have a USB audio interface connected it will use the microphone."),
|
||||
cameraPermissionNeededValue (settings, Ids::cameraPermissionNeeded, getUndoManager()),
|
||||
cameraPermissionTextValue (settings, Ids::cameraPermissionText, getUndoManager(),
|
||||
"This app requires camera usage to function properly."),
|
||||
uiFileSharingEnabledValue (settings, Ids::UIFileSharingEnabled, getUndoManager()),
|
||||
uiSupportsDocumentBrowserValue (settings, Ids::UISupportsDocumentBrowser, getUndoManager()),
|
||||
uiStatusBarHiddenValue (settings, Ids::UIStatusBarHidden, getUndoManager()),
|
||||
|
|
@ -124,6 +127,9 @@ public:
|
|||
bool isMicrophonePermissionEnabled() const { return microphonePermissionNeededValue.get(); }
|
||||
String getMicrophonePermissionsTextString() const { return microphonePermissionsTextValue.get(); }
|
||||
|
||||
bool isCameraPermissionEnabled() const { return cameraPermissionNeededValue.get(); }
|
||||
String getCameraPermissionTextString() const { return cameraPermissionTextValue.get(); }
|
||||
|
||||
bool isInAppPurchasesEnabled() const { return iosInAppPurchasesValue.get(); }
|
||||
bool isBackgroundAudioEnabled() const { return iosBackgroundAudioValue.get(); }
|
||||
bool isBackgroundBleEnabled() const { return iosBackgroundBleValue.get(); }
|
||||
|
|
@ -236,6 +242,14 @@ public:
|
|||
props.add (new TextPropertyComponentWithEnablement (microphonePermissionsTextValue, microphonePermissionNeededValue,
|
||||
"Microphone Access Text", 1024, false),
|
||||
"A short description of why your app requires microphone access.");
|
||||
|
||||
props.add (new ChoicePropertyComponent (cameraPermissionNeededValue, "Camera Access"),
|
||||
"Enable this to allow your app to use the camera. "
|
||||
"The user of your app will be prompted to grant camera access permissions.");
|
||||
|
||||
props.add (new TextPropertyComponentWithEnablement (cameraPermissionTextValue, cameraPermissionNeededValue,
|
||||
"Camera Access Text", 1024, false),
|
||||
"A short description of why your app requires camera access.");
|
||||
}
|
||||
else if (projectType.isGUIApplication())
|
||||
{
|
||||
|
|
@ -1280,9 +1294,13 @@ public:
|
|||
if (owner.iOS)
|
||||
{
|
||||
addPlistDictionaryKeyBool (dict, "LSRequiresIPhoneOS", true);
|
||||
|
||||
if (owner.isMicrophonePermissionEnabled())
|
||||
addPlistDictionaryKey (dict, "NSMicrophoneUsageDescription", owner.getMicrophonePermissionsTextString());
|
||||
|
||||
if (owner.isCameraPermissionEnabled())
|
||||
addPlistDictionaryKey (dict, "NSCameraUsageDescription", owner.getCameraPermissionTextString());
|
||||
|
||||
if (type != AudioUnitv3PlugIn)
|
||||
addPlistDictionaryKeyBool (dict, "UIViewControllerBasedStatusBarAppearance", false);
|
||||
}
|
||||
|
|
@ -1682,7 +1700,8 @@ private:
|
|||
|
||||
ValueWithDefault customPListValue, pListPrefixHeaderValue, pListPreprocessValue, extraFrameworksValue, postbuildCommandValue,
|
||||
prebuildCommandValue, duplicateAppExResourcesFolderValue, iosDeviceFamilyValue, iPhoneScreenOrientationValue,
|
||||
iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue, microphonePermissionNeededValue, microphonePermissionsTextValue,
|
||||
iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue,
|
||||
microphonePermissionNeededValue, microphonePermissionsTextValue, cameraPermissionNeededValue, cameraPermissionTextValue,
|
||||
uiFileSharingEnabledValue, uiSupportsDocumentBrowserValue, uiStatusBarHiddenValue, documentExtensionsValue, iosInAppPurchasesValue,
|
||||
iosBackgroundAudioValue, iosBackgroundBleValue, iosPushNotificationsValue, iosAppGroupsValue, iCloudPermissionsValue,
|
||||
iosDevelopmentTeamIDValue, iosAppGroupsIDValue, keepCustomXcodeSchemesValue, useHeaderMapValue;
|
||||
|
|
@ -2299,6 +2318,9 @@ private:
|
|||
if (iOS && isPushNotificationsEnabled())
|
||||
xcodeFrameworks.addIfNotAlreadyThere ("UserNotifications");
|
||||
|
||||
if (isiOS() && project.getConfigFlag ("JUCE_USE_CAMERA").get())
|
||||
xcodeFrameworks.addIfNotAlreadyThere ("ImageIO");
|
||||
|
||||
xcodeFrameworks.addTokens (getExtraFrameworksString(), ",;", "\"'");
|
||||
xcodeFrameworks.trim();
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,8 @@ namespace Ids
|
|||
DECLARE_ID (overwriteOnSave);
|
||||
DECLARE_ID (microphonePermissionNeeded);
|
||||
DECLARE_ID (microphonePermissionsText);
|
||||
DECLARE_ID (cameraPermissionNeeded);
|
||||
DECLARE_ID (cameraPermissionText);
|
||||
DECLARE_ID (androidJavaLibs);
|
||||
DECLARE_ID (androidRepositories);
|
||||
DECLARE_ID (androidDependencies);
|
||||
|
|
|
|||
|
|
@ -628,6 +628,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2638,6 +2641,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_product_unlocking\juce_product_unlocking.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -949,6 +949,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4467,6 +4470,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@
|
|||
//#define JUCE_PLUGINHOST_AU 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_LADSPA
|
||||
//#define JUCE_PLUGINHOST_LADSPA 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_utils flags:
|
||||
|
||||
|
|
|
|||
|
|
@ -595,6 +595,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
|
@ -2420,6 +2423,7 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/>
|
||||
|
|
|
|||
|
|
@ -844,6 +844,9 @@
|
|||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_PropertySet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_SparseSet.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_Variant.cpp">
|
||||
<Filter>JUCE Modules\juce_core\containers</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -4011,6 +4014,9 @@
|
|||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h">
|
||||
<Filter>JUCE Modules\juce_video\native</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -150,6 +150,10 @@
|
|||
//#define JUCE_PLUGINHOST_AU 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_LADSPA
|
||||
//#define JUCE_PLUGINHOST_LADSPA 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_utils flags:
|
||||
|
||||
|
|
|
|||
|
|
@ -221,22 +221,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
static StringArray javaStringArrayToJuce (jobjectArray jStrings)
|
||||
{
|
||||
StringArray retval;
|
||||
|
||||
JNIEnv* env = getEnv();
|
||||
const int count = env->GetArrayLength (jStrings);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
LocalRef<jstring> string ((jstring) env->GetObjectArrayElement (jStrings, i));
|
||||
retval.add (juceString (string));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
GlobalRef deviceManager;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,10 @@ public:
|
|||
readExternalStorage = 3,
|
||||
|
||||
/** Permission to write to external storage such as SD cards */
|
||||
writeExternalStorage = 4
|
||||
writeExternalStorage = 4,
|
||||
|
||||
/** Permission to use camera */
|
||||
camera = 5
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
169
modules/juce_core/native/java/AndroidCamera.java
Normal file
169
modules/juce_core/native/java/AndroidCamera.java
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
$$CameraApi21
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
CameraApi21$$
|
||||
|
|
@ -30,6 +30,7 @@ import android.content.Intent;
|
|||
import android.content.res.Configuration;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
$$JuceAndroidCameraImports$$ // If you get an error here, you need to re-save your project with the Projucer!
|
||||
import android.net.http.SslError;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -114,6 +115,7 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2;
|
||||
private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3;
|
||||
private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4;
|
||||
private static final int JUCE_PERMISSIONS_CAMERA = 5;
|
||||
|
||||
private static String getAndroidPermissionName (int permissionID)
|
||||
{
|
||||
|
|
@ -124,6 +126,7 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
// use string value as this is not defined in SDKs < 16
|
||||
case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE";
|
||||
case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
case JUCE_PERMISSIONS_CAMERA: return Manifest.permission.CAMERA;
|
||||
}
|
||||
|
||||
// unknown permission ID!
|
||||
|
|
@ -191,6 +194,7 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
setVolumeControlStream (AudioManager.STREAM_MUSIC);
|
||||
|
||||
permissionCallbackPtrMap = new HashMap<Integer, Long>();
|
||||
appPausedResumedListeners = new HashMap<Long, AppPausedResumedListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -207,6 +211,11 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
{
|
||||
suspendApp();
|
||||
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appPaused();
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down
|
||||
|
|
@ -222,12 +231,10 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
super.onResume();
|
||||
resumeApp();
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
for (int i = 0; i < viewHolder.getChildCount(); ++i)
|
||||
{
|
||||
if (viewHolder.getChildAt (i) instanceof ComponentPeerView)
|
||||
((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();
|
||||
}
|
||||
Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]);
|
||||
|
||||
for (Long k : keys)
|
||||
appPausedResumedListeners.get (k).appResumed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -354,11 +361,14 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
{
|
||||
ComponentPeerView v = new ComponentPeerView (this, opaque, host);
|
||||
viewHolder.addView (v);
|
||||
addAppPausedResumedListener (v, host);
|
||||
return v;
|
||||
}
|
||||
|
||||
public final void deleteView (ComponentPeerView view)
|
||||
{
|
||||
removeAppPausedResumedListener (view, view.host);
|
||||
|
||||
view.host = 0;
|
||||
|
||||
ViewGroup group = (ViewGroup) (view.getParent());
|
||||
|
|
@ -576,9 +586,28 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
|
||||
public native void alertDismissed (long callback, int id);
|
||||
|
||||
//==============================================================================
|
||||
public interface AppPausedResumedListener
|
||||
{
|
||||
void appPaused();
|
||||
void appResumed();
|
||||
}
|
||||
|
||||
private Map<Long, AppPausedResumedListener> appPausedResumedListeners;
|
||||
|
||||
public void addAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.put (new Long (listenerHost), l);
|
||||
}
|
||||
|
||||
public void removeAppPausedResumedListener (AppPausedResumedListener l, long listenerHost)
|
||||
{
|
||||
appPausedResumedListeners.remove (new Long (listenerHost));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public final class ComponentPeerView extends ViewGroup
|
||||
implements View.OnFocusChangeListener
|
||||
implements View.OnFocusChangeListener, AppPausedResumedListener
|
||||
{
|
||||
public ComponentPeerView (Context context, boolean opaque_, long host)
|
||||
{
|
||||
|
|
@ -926,13 +955,25 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
private native void handleAppPaused (long host);
|
||||
private native void handleAppResumed (long host);
|
||||
|
||||
@Override
|
||||
public void appPaused()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
handleAppPaused (host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appResumed()
|
||||
{
|
||||
if (host == 0)
|
||||
return;
|
||||
|
||||
// Ensure that navigation/status bar visibility is correctly restored.
|
||||
handleAppResumed (host);
|
||||
}
|
||||
}
|
||||
|
|
@ -1569,6 +1610,8 @@ $$JuceAndroidWebViewNativeCode$$ // If you get an error here, you need to re-sav
|
|||
private final Object hostLock = new Object();
|
||||
}
|
||||
|
||||
$$JuceAndroidCameraCode$$ // If you get an error here, you need to re-save your project with the Projucer!
|
||||
|
||||
//==============================================================================
|
||||
public static final String getLocaleValue (boolean isRegion)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -163,39 +163,6 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
namespace
|
||||
{
|
||||
inline String juceString (JNIEnv* env, jstring s)
|
||||
{
|
||||
if (s == 0)
|
||||
return {};
|
||||
|
||||
const char* const utf8 = env->GetStringUTFChars (s, nullptr);
|
||||
CharPointer_UTF8 utf8CP (utf8);
|
||||
const String result (utf8CP);
|
||||
env->ReleaseStringUTFChars (s, utf8);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline String juceString (jstring s)
|
||||
{
|
||||
return juceString (getEnv(), s);
|
||||
}
|
||||
|
||||
inline LocalRef<jstring> javaString (const String& s)
|
||||
{
|
||||
return LocalRef<jstring> (getEnv()->NewStringUTF (s.toUTF8()));
|
||||
}
|
||||
|
||||
inline LocalRef<jstring> javaStringFromChar (const juce_wchar c)
|
||||
{
|
||||
char utf8[8] = { 0 };
|
||||
CharPointer_UTF8 (utf8).write (c);
|
||||
return LocalRef<jstring> (getEnv()->NewStringUTF (utf8));
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class JNIClassBase
|
||||
{
|
||||
|
|
@ -287,6 +254,7 @@ extern AndroidSystem android;
|
|||
METHOD (deleteView, "deleteView", "(L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;)V") \
|
||||
METHOD (createNativeSurfaceView, "createNativeSurfaceView", "(J)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$NativeSurfaceView;") \
|
||||
METHOD (finish, "finish", "()V") \
|
||||
METHOD (getWindowManager, "getWindowManager", "()Landroid/view/WindowManager;") \
|
||||
METHOD (setRequestedOrientation, "setRequestedOrientation", "(I)V") \
|
||||
METHOD (getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \
|
||||
METHOD (setClipboardContent, "setClipboardContent", "(Ljava/lang/String;)V") \
|
||||
|
|
@ -329,14 +297,21 @@ extern AndroidSystem android;
|
|||
METHOD (startActivity, "startActivity", "(Landroid/content/Intent;)V") \
|
||||
METHOD (startActivityForResult, "startActivityForResult", "(Landroid/content/Intent;I)V") \
|
||||
METHOD (getContentResolver, "getContentResolver", "()Landroid/content/ContentResolver;") \
|
||||
METHOD (addAppPausedResumedListener, "addAppPausedResumedListener", "(L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$AppPausedResumedListener;J)V") \
|
||||
METHOD (removeAppPausedResumedListener, "removeAppPausedResumedListener", "(L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$AppPausedResumedListener;J)V")
|
||||
|
||||
DECLARE_JNI_CLASS (JuceAppActivity, JUCE_ANDROID_ACTIVITY_CLASSPATH);
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (createBitmap, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;") \
|
||||
METHOD (setPixel, "setPixel", "(III)V")
|
||||
STATICMETHOD (createBitmap, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;") \
|
||||
STATICMETHOD (createBitmapFrom, "createBitmap", "(Landroid/graphics/Bitmap;IIIILandroid/graphics/Matrix;Z)Landroid/graphics/Bitmap;") \
|
||||
METHOD (compress, "compress", "(Landroid/graphics/Bitmap$CompressFormat;ILjava/io/OutputStream;)Z") \
|
||||
METHOD (getHeight, "getHeight", "()I") \
|
||||
METHOD (getWidth, "getWidth", "()I") \
|
||||
METHOD (recycle, "recycle", "()V") \
|
||||
METHOD (setPixel, "setPixel", "(III)V")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidBitmap, "android/graphics/Bitmap");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
|
@ -347,6 +322,12 @@ DECLARE_JNI_CLASS (AndroidBitmap, "android/graphics/Bitmap");
|
|||
DECLARE_JNI_CLASS (AndroidBitmapConfig, "android/graphics/Bitmap$Config");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (decodeByteArray, "decodeByteArray", "([BII)Landroid/graphics/Bitmap;")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidBitmapFactory, "android/graphics/BitmapFactory");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (dumpReferenceTables, "dumpReferenceTables", "()V")
|
||||
|
||||
|
|
@ -355,6 +336,31 @@ DECLARE_JNI_CLASS (AndroidBitmapConfig, "android/graphics/Bitmap$Config");
|
|||
|
||||
#define JUCE_LOG_JNI_REFERENCES_TABLE getEnv()->CallStaticVoidMethod (AndroidDebug, AndroidDebug.dumpReferenceTables);
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (getRotation, "getRotation", "()I")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidDisplay, "android/view/Display");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "()V") \
|
||||
METHOD (constructorWithLooper, "<init>", "(Landroid/os/Looper;)V") \
|
||||
METHOD (post, "post", "(Ljava/lang/Runnable;)Z") \
|
||||
METHOD (postDelayed, "postDelayed", "(Ljava/lang/Runnable;J)Z") \
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidHandler, "android/os/Handler");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "(Ljava/lang/String;)V") \
|
||||
METHOD (getLooper, "getLooper", "()Landroid/os/Looper;") \
|
||||
METHOD (join, "join", "()V") \
|
||||
METHOD (quitSafely, "quitSafely", "()Z") \
|
||||
METHOD (start, "start", "()V")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidHandlerThread, "android/os/HandlerThread");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (createChooser, "createChooser", "(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;") \
|
||||
METHOD (addCategory, "addCategory", "(Ljava/lang/String;)Landroid/content/Intent;") \
|
||||
|
|
@ -382,8 +388,11 @@ DECLARE_JNI_CLASS (AndroidIntent, "android/content/Intent");
|
|||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "()V") \
|
||||
METHOD (setValues, "setValues", "([F)V") \
|
||||
METHOD (constructor, "<init>", "()V") \
|
||||
METHOD (postRotate, "postRotate", "(FFF)Z") \
|
||||
METHOD (postScale, "postScale", "(FFFF)Z") \
|
||||
METHOD (postTranslate, "postTranslate", "(FF)Z") \
|
||||
METHOD (setValues, "setValues", "([F)V")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidMatrix, "android/graphics/Matrix");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
|
@ -417,6 +426,12 @@ DECLARE_JNI_CLASS (AndroidPaint, "android/graphics/Paint");
|
|||
DECLARE_JNI_CLASS (AndroidPendingIntent, "android/app/PendingIntent");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (toString, "toString", "()Ljava/lang/String;")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidRange, "android/util/Range");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "(IIII)V") \
|
||||
FIELD (left, "left", "I") \
|
||||
|
|
@ -424,7 +439,7 @@ DECLARE_JNI_CLASS (AndroidPendingIntent, "android/app/PendingIntent");
|
|||
FIELD (top, "top", "I") \
|
||||
FIELD (bottom, "bottom", "I") \
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidRectClass, "android/graphics/Rect");
|
||||
DECLARE_JNI_CLASS (AndroidRect, "android/graphics/Rect");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
|
|
@ -434,6 +449,13 @@ DECLARE_JNI_CLASS (AndroidRectClass, "android/graphics/Rect");
|
|||
DECLARE_JNI_CLASS (AndroidResources, "android/content/res/Resources")
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (getHeight, "getHeight", "()I") \
|
||||
METHOD (getWidth, "getWidth", "()I")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidSize, "android/util/Size");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (parse, "parse", "(Ljava/lang/String;)Landroid/net/Uri;") \
|
||||
METHOD (toString, "toString", "()Ljava/lang/String;")
|
||||
|
|
@ -465,6 +487,12 @@ DECLARE_JNI_CLASS (AndroidView, "android/view/View");
|
|||
DECLARE_JNI_CLASS (AndroidViewGroup, "android/view/ViewGroup")
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (getDefaultDisplay, "getDefaultDisplay", "()Landroid/view/Display;")
|
||||
|
||||
DECLARE_JNI_CLASS (AndroidWindowManager, "android/view/WindowManager");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "(I)V") \
|
||||
|
|
@ -477,6 +505,7 @@ DECLARE_JNI_CLASS (JavaArrayList, "java/util/ArrayList");
|
|||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (valueOf, "valueOf", "(Z)Ljava/lang/Boolean;") \
|
||||
METHOD (booleanValue, "booleanValue", "()Z")
|
||||
|
||||
DECLARE_JNI_CLASS (JavaBoolean, "java/lang/Boolean");
|
||||
|
|
@ -507,6 +536,13 @@ DECLARE_JNI_CLASS (JavaBoolean, "java/lang/Boolean");
|
|||
DECLARE_JNI_CLASS (JavaBundle, "android/os/Bundle");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (get, "get", "([B)Ljava/nio/ByteBuffer;") \
|
||||
METHOD (remaining, "remaining", "()I")
|
||||
|
||||
DECLARE_JNI_CLASS (JavaByteBuffer, "java/nio/ByteBuffer");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (toString, "toString", "()Ljava/lang/String;")
|
||||
|
||||
|
|
@ -514,6 +550,7 @@ DECLARE_JNI_CLASS (JavaCharSequence, "java/lang/CharSequence");
|
|||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (forName, "forName", "(Ljava/lang/String;)Ljava/lang/Class;") \
|
||||
METHOD (getName, "getName", "()Ljava/lang/String;") \
|
||||
METHOD (getModifiers, "getModifiers", "()I") \
|
||||
METHOD (isAnnotation, "isAnnotation", "()Z") \
|
||||
|
|
@ -571,7 +608,8 @@ DECLARE_JNI_CLASS (JavaHashMap, "java/util/HashMap");
|
|||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
STATICMETHOD (parseInt, "parseInt", "(Ljava/lang/String;I)I") \
|
||||
STATICMETHOD (valueOf, "valueOf", "(I)Ljava/lang/Integer;")
|
||||
STATICMETHOD (valueOf, "valueOf", "(I)Ljava/lang/Integer;") \
|
||||
METHOD (intValue, "intValue", "()I")
|
||||
|
||||
DECLARE_JNI_CLASS (JavaInteger, "java/lang/Integer");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
|
@ -583,6 +621,13 @@ DECLARE_JNI_CLASS (JavaInteger, "java/lang/Integer");
|
|||
DECLARE_JNI_CLASS (JavaIterator, "java/util/Iterator");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (get, "get", "(I)Ljava/lang/Object;") \
|
||||
METHOD (size, "size", "()I")
|
||||
|
||||
DECLARE_JNI_CLASS (JavaList, "java/util/List");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (constructor, "<init>", "(J)V")
|
||||
|
||||
|
|
@ -633,6 +678,71 @@ DECLARE_JNI_CLASS (JavaSet, "java/util/Set");
|
|||
DECLARE_JNI_CLASS (JavaString, "java/lang/String");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
//==============================================================================
|
||||
namespace
|
||||
{
|
||||
inline String juceString (JNIEnv* env, jstring s)
|
||||
{
|
||||
if (s == 0)
|
||||
return {};
|
||||
|
||||
const char* const utf8 = env->GetStringUTFChars (s, nullptr);
|
||||
CharPointer_UTF8 utf8CP (utf8);
|
||||
const String result (utf8CP);
|
||||
env->ReleaseStringUTFChars (s, utf8);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline String juceString (jstring s)
|
||||
{
|
||||
return juceString (getEnv(), s);
|
||||
}
|
||||
|
||||
inline LocalRef<jstring> javaString (const String& s)
|
||||
{
|
||||
return LocalRef<jstring> (getEnv()->NewStringUTF (s.toUTF8()));
|
||||
}
|
||||
|
||||
inline LocalRef<jstring> javaStringFromChar (const juce_wchar c)
|
||||
{
|
||||
char utf8[8] = { 0 };
|
||||
CharPointer_UTF8 (utf8).write (c);
|
||||
return LocalRef<jstring> (getEnv()->NewStringUTF (utf8));
|
||||
}
|
||||
|
||||
inline LocalRef<jobjectArray> juceStringArrayToJava (const StringArray& juceArray)
|
||||
{
|
||||
auto* env = getEnv();
|
||||
|
||||
LocalRef<jobjectArray> result (env->NewObjectArray ((jsize) juceArray.size(),
|
||||
JavaString,
|
||||
javaString ("").get()));
|
||||
|
||||
for (int i = 0; i < juceArray.size(); ++i)
|
||||
env->SetObjectArrayElement (result, i, javaString (juceArray [i]).get());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline StringArray javaStringArrayToJuce (const LocalRef<jobjectArray>& javaArray)
|
||||
{
|
||||
if (javaArray.get() == nullptr)
|
||||
return {};
|
||||
|
||||
auto* env = getEnv();
|
||||
|
||||
StringArray result;
|
||||
|
||||
for (int i = 0; i < env->GetArrayLength (javaArray.get()); ++i)
|
||||
{
|
||||
LocalRef<jstring> javaString ((jstring) env->GetObjectArrayElement (javaArray.get(), i));
|
||||
result.add (juceString (javaString.get()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class AndroidInterfaceImplementer;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,14 +23,6 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
#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
|
||||
{
|
||||
|
|
@ -58,14 +50,14 @@ namespace Android
|
|||
|
||||
struct Handler
|
||||
{
|
||||
Handler() : nativeHandler (getEnv()->NewObject (JNIHandler, JNIHandler.constructor)) {}
|
||||
Handler() : nativeHandler (getEnv()->NewObject (AndroidHandler, AndroidHandler.constructor)) {}
|
||||
~Handler() { clearSingletonInstance(); }
|
||||
|
||||
JUCE_DECLARE_SINGLETON (Handler, false)
|
||||
|
||||
bool post (jobject runnable)
|
||||
{
|
||||
return (getEnv()->CallBooleanMethod (nativeHandler.get(), JNIHandler.post, runnable) != 0);
|
||||
return (getEnv()->CallBooleanMethod (nativeHandler.get(), AndroidHandler.post, runnable) != 0);
|
||||
}
|
||||
|
||||
GlobalRef nativeHandler;
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ public:
|
|||
|
||||
void initialise (JNIEnv* const env)
|
||||
{
|
||||
rect = GlobalRef (env->NewObject (AndroidRectClass, AndroidRectClass.constructor, 0, 0, 0, 0));
|
||||
rect = GlobalRef (env->NewObject (AndroidRect, AndroidRect.constructor, 0, 0, 0, 0));
|
||||
|
||||
paint = GlobalRef (GraphicsHelpers::createPaint (Graphics::highResamplingQuality));
|
||||
const LocalRef<jobject> ignored (paint.callObjectMethod (AndroidPaint.setTypeface, typeface.get()));
|
||||
|
|
@ -298,10 +298,10 @@ public:
|
|||
|
||||
env->DeleteLocalRef (matrix);
|
||||
|
||||
const int left = env->GetIntField (rect.get(), AndroidRectClass.left);
|
||||
const int top = env->GetIntField (rect.get(), AndroidRectClass.top);
|
||||
const int right = env->GetIntField (rect.get(), AndroidRectClass.right);
|
||||
const int bottom = env->GetIntField (rect.get(), AndroidRectClass.bottom);
|
||||
const int left = env->GetIntField (rect.get(), AndroidRect.left);
|
||||
const int top = env->GetIntField (rect.get(), AndroidRect.top);
|
||||
const int right = env->GetIntField (rect.get(), AndroidRect.right);
|
||||
const int bottom = env->GetIntField (rect.get(), AndroidRect.bottom);
|
||||
|
||||
const Rectangle<int> bounds (left, top, right - left, bottom - top);
|
||||
|
||||
|
|
|
|||
|
|
@ -486,7 +486,7 @@ public:
|
|||
{
|
||||
ignoreUnused (selection, selectionArgs, sortOrder);
|
||||
|
||||
StringArray requestedColumns = javaStringArrayToJuceStringArray (projection);
|
||||
StringArray requestedColumns = javaStringArrayToJuce (projection);
|
||||
StringArray supportedColumns = getSupportedColumns();
|
||||
|
||||
StringArray resultColumns;
|
||||
|
|
@ -501,7 +501,7 @@ public:
|
|||
if (resultColumns.isEmpty())
|
||||
return nullptr;
|
||||
|
||||
auto resultJavaColumns = juceStringArrayToJavaStringArray (resultColumns);
|
||||
auto resultJavaColumns = juceStringArrayToJava (resultColumns);
|
||||
|
||||
auto* env = getEnv();
|
||||
|
||||
|
|
@ -550,7 +550,7 @@ public:
|
|||
if (extension.isEmpty())
|
||||
return nullptr;
|
||||
|
||||
return juceStringArrayToJavaStringArray (filterMimeTypes (getMimeTypesForFileExtension (extension),
|
||||
return juceStringArrayToJava (filterMimeTypes (getMimeTypesForFileExtension (extension),
|
||||
juceString (mimeTypeFilter.get())));
|
||||
}
|
||||
|
||||
|
|
@ -683,40 +683,6 @@ private:
|
|||
return { index, filename, prepareFilesThread->getFilePaths()[index.getIntValue()] };
|
||||
}
|
||||
|
||||
static LocalRef<jobjectArray> juceStringArrayToJavaStringArray (const StringArray& juceArray)
|
||||
{
|
||||
auto* env = getEnv();
|
||||
|
||||
auto javaArray = LocalRef<jobjectArray> (env->NewObjectArray ((jsize) juceArray.size(),
|
||||
JavaString,
|
||||
javaString ("").get()));
|
||||
|
||||
for (int i = 0; i < juceArray.size(); ++i)
|
||||
env->SetObjectArrayElement (javaArray, i, javaString (juceArray [i]).get());
|
||||
|
||||
return javaArray;
|
||||
}
|
||||
|
||||
static StringArray javaStringArrayToJuceStringArray (const LocalRef<jobjectArray>& javaArray)
|
||||
{
|
||||
if (javaArray.get() == 0)
|
||||
return {};
|
||||
|
||||
auto* env = getEnv();
|
||||
|
||||
const int size = env->GetArrayLength (javaArray.get());
|
||||
|
||||
StringArray juceArray;
|
||||
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
auto javaString = LocalRef<jstring> ((jstring) env->GetObjectArrayElement (javaArray.get(), i));
|
||||
juceArray.add (juceString (javaString.get()));
|
||||
}
|
||||
|
||||
return juceArray;
|
||||
}
|
||||
|
||||
static StringArray getSupportedColumns()
|
||||
{
|
||||
return StringArray ("_display_name", "_size");
|
||||
|
|
|
|||
|
|
@ -560,6 +560,8 @@ public:
|
|||
Component::unfocusAllComponents();
|
||||
}
|
||||
|
||||
void handleAppPausedCallback() {}
|
||||
|
||||
void handleAppResumedCallback()
|
||||
{
|
||||
if (Component* kiosk = Desktop::getInstance().getKioskModeComponent())
|
||||
|
|
@ -630,10 +632,10 @@ public:
|
|||
void handlePaintCallback (JNIEnv* env, jobject canvas, jobject paint)
|
||||
{
|
||||
jobject rect = env->CallObjectMethod (canvas, CanvasMinimal.getClipBounds);
|
||||
const int left = env->GetIntField (rect, AndroidRectClass.left);
|
||||
const int top = env->GetIntField (rect, AndroidRectClass.top);
|
||||
const int right = env->GetIntField (rect, AndroidRectClass.right);
|
||||
const int bottom = env->GetIntField (rect, AndroidRectClass.bottom);
|
||||
const int left = env->GetIntField (rect, AndroidRect.left);
|
||||
const int top = env->GetIntField (rect, AndroidRect.top);
|
||||
const int right = env->GetIntField (rect, AndroidRect.right);
|
||||
const int bottom = env->GetIntField (rect, AndroidRect.bottom);
|
||||
env->DeleteLocalRef (rect);
|
||||
|
||||
const Rectangle<int> clip (left, top, right - left, bottom - top);
|
||||
|
|
@ -810,6 +812,7 @@ JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject /*view*/,
|
|||
JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc))
|
||||
JUCE_VIEW_CALLBACK (void, handleBackButton, (JNIEnv* env, jobject /*view*/, jlong host), handleBackButtonCallback())
|
||||
JUCE_VIEW_CALLBACK (void, handleKeyboardHidden, (JNIEnv* env, jobject /*view*/, jlong host), handleKeyboardHiddenCallback())
|
||||
JUCE_VIEW_CALLBACK (void, handleAppPaused, (JNIEnv* env, jobject /*view*/, jlong host), handleAppPausedCallback())
|
||||
JUCE_VIEW_CALLBACK (void, handleAppResumed, (JNIEnv* env, jobject /*view*/, jlong host), handleAppResumedCallback())
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -819,18 +822,6 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void*)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (getRotation, "getRotation", "()I")
|
||||
|
||||
DECLARE_JNI_CLASS (Display, "android/view/Display");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
||||
METHOD (getDefaultDisplay, "getDefaultDisplay", "()Landroid/view/Display;")
|
||||
|
||||
DECLARE_JNI_CLASS (WindowManager, "android/view/WindowManager");
|
||||
#undef JNI_CLASS_MEMBERS
|
||||
|
||||
bool Desktop::canUseSemiTransparentWindows() noexcept
|
||||
{
|
||||
return true;
|
||||
|
|
@ -857,11 +848,11 @@ Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
|
|||
|
||||
if (windowManager.get() != 0)
|
||||
{
|
||||
LocalRef<jobject> display = LocalRef<jobject> (env->CallObjectMethod (windowManager, WindowManager.getDefaultDisplay));
|
||||
LocalRef<jobject> display = LocalRef<jobject> (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay));
|
||||
|
||||
if (display.get() != 0)
|
||||
{
|
||||
int rotation = env->CallIntMethod (display, Display.getRotation);
|
||||
int rotation = env->CallIntMethod (display, AndroidDisplay.getRotation);
|
||||
|
||||
switch (rotation)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1427,8 +1427,8 @@ struct PushNotifications::Pimpl
|
|||
propertiesDynamicObject->setProperty ("clickAction", juceString (clickAction.get()));
|
||||
propertiesDynamicObject->setProperty ("bodyLocalizationKey", juceString (bodyLocalizationKey.get()));
|
||||
propertiesDynamicObject->setProperty ("titleLocalizationKey", juceString (titleLocalizationKey.get()));
|
||||
propertiesDynamicObject->setProperty ("bodyLocalizationArgs", jobjectArrayToStringArray (bodyLocalizationArgs));
|
||||
propertiesDynamicObject->setProperty ("titleLocalizationArgs", jobjectArrayToStringArray (titleLocalizationArgs));
|
||||
propertiesDynamicObject->setProperty ("bodyLocalizationArgs", javaStringArrayToJuce (bodyLocalizationArgs));
|
||||
propertiesDynamicObject->setProperty ("titleLocalizationArgs", javaStringArrayToJuce (titleLocalizationArgs));
|
||||
propertiesDynamicObject->setProperty ("link", link.get() != 0 ? juceString ((jstring) env->CallObjectMethod (link, AndroidUri.toString)) : String());
|
||||
}
|
||||
|
||||
|
|
@ -1436,23 +1436,6 @@ struct PushNotifications::Pimpl
|
|||
|
||||
return n;
|
||||
}
|
||||
|
||||
static StringArray jobjectArrayToStringArray (const LocalRef<jobjectArray>& array)
|
||||
{
|
||||
if (array == 0)
|
||||
return {};
|
||||
|
||||
auto* env = getEnv();
|
||||
|
||||
const int size = env->GetArrayLength (array.get());
|
||||
|
||||
StringArray stringArray;
|
||||
|
||||
for (int i = 0; i < size; ++i)
|
||||
stringArray.add (juceString ((jstring) env->GetObjectArrayElement (array.get(), (jsize) i)));
|
||||
|
||||
return stringArray;
|
||||
}
|
||||
#endif
|
||||
|
||||
void setupChannels (const Array<ChannelGroup>& groups, const Array<Channel>& channels)
|
||||
|
|
|
|||
|
|
@ -27,22 +27,129 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
#if JUCE_MAC || JUCE_IOS
|
||||
#if JUCE_MAC
|
||||
#include "../native/juce_mac_CameraDevice.h"
|
||||
#elif JUCE_WINDOWS
|
||||
#include "../native/juce_win32_CameraDevice.h"
|
||||
#elif JUCE_IOS
|
||||
#if JUCE_CLANG
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
||||
#endif
|
||||
|
||||
#include "../native/juce_ios_CameraDevice.h"
|
||||
|
||||
#if JUCE_CLANG
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#elif JUCE_ANDROID
|
||||
#include "../native/juce_android_CameraDevice.h"
|
||||
#endif
|
||||
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
//==============================================================================
|
||||
class CameraDevice::CameraFactory
|
||||
{
|
||||
public:
|
||||
static CameraFactory& getInstance()
|
||||
{
|
||||
static CameraFactory factory;
|
||||
return factory;
|
||||
}
|
||||
|
||||
void openCamera (int index, OpenCameraResultCallback resultCallback,
|
||||
int minWidth, int minHeight, int maxWidth, int maxHeight, bool useHighQuality)
|
||||
{
|
||||
auto cameraId = getAvailableDevices()[index];
|
||||
|
||||
if (getCameraIndex (cameraId) != -1)
|
||||
{
|
||||
// You are trying to open the same camera twice.
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<CameraDevice> device (new CameraDevice (cameraId, index,
|
||||
minWidth, minHeight, maxWidth,
|
||||
maxHeight, useHighQuality));
|
||||
|
||||
camerasToOpen.add ({ nextRequestId++,
|
||||
std::unique_ptr<CameraDevice> (device.release()),
|
||||
resultCallback });
|
||||
|
||||
auto& pendingOpen = camerasToOpen.getReference (camerasToOpen.size() - 1);
|
||||
|
||||
pendingOpen.device->pimpl->open ([this](const String& deviceId, const String& error)
|
||||
{
|
||||
int index = getCameraIndex (deviceId);
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
auto& pendingOpen = camerasToOpen.getReference (index);
|
||||
|
||||
if (error.isEmpty())
|
||||
pendingOpen.resultCallback (pendingOpen.device.release(), error);
|
||||
else
|
||||
pendingOpen.resultCallback (nullptr, error);
|
||||
|
||||
int id = pendingOpen.requestId;
|
||||
|
||||
MessageManager::callAsync ([this, id]() { removeRequestWithId (id); });
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
int getCameraIndex (const String& cameraId) const
|
||||
{
|
||||
for (int i = 0; i < camerasToOpen.size(); ++i)
|
||||
{
|
||||
auto& pendingOpen = camerasToOpen.getReference (i);
|
||||
|
||||
if (pendingOpen.device->pimpl->getCameraId() == cameraId)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void removeRequestWithId (int id)
|
||||
{
|
||||
for (int i = camerasToOpen.size(); --i >= 0;)
|
||||
{
|
||||
if (camerasToOpen.getReference (i).requestId == id)
|
||||
{
|
||||
camerasToOpen.remove (i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PendingCameraOpen
|
||||
{
|
||||
int requestId;
|
||||
std::unique_ptr<CameraDevice> device;
|
||||
OpenCameraResultCallback resultCallback;
|
||||
};
|
||||
|
||||
Array<PendingCameraOpen> camerasToOpen;
|
||||
static int nextRequestId;
|
||||
};
|
||||
|
||||
int CameraDevice::CameraFactory::nextRequestId = 0;
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
CameraDevice::CameraDevice (const String& nm, int index, int minWidth, int minHeight, int maxWidth, int maxHeight, bool useHighQuality)
|
||||
: name (nm), pimpl (new Pimpl (name, index, minWidth, minHeight, maxWidth, maxHeight, useHighQuality))
|
||||
: name (nm), pimpl (new Pimpl (*this, name, index, minWidth, minHeight, maxWidth, maxHeight, useHighQuality))
|
||||
{
|
||||
}
|
||||
|
||||
CameraDevice::~CameraDevice()
|
||||
{
|
||||
jassert (juce::MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
stopRecording();
|
||||
pimpl.reset();
|
||||
}
|
||||
|
|
@ -52,6 +159,11 @@ Component* CameraDevice::createViewerComponent()
|
|||
return new ViewerComponent (*this);
|
||||
}
|
||||
|
||||
void CameraDevice::takeStillPicture (std::function<void (const Image&)> pictureTakenCallback)
|
||||
{
|
||||
pimpl->takeStillPicture (pictureTakenCallback);
|
||||
}
|
||||
|
||||
void CameraDevice::startRecordingToFile (const File& file, int quality)
|
||||
{
|
||||
stopRecording();
|
||||
|
|
@ -68,18 +180,6 @@ void CameraDevice::stopRecording()
|
|||
pimpl->stopRecording();
|
||||
}
|
||||
|
||||
void CameraDevice::addListener (Listener* listenerToAdd)
|
||||
{
|
||||
if (listenerToAdd != nullptr)
|
||||
pimpl->addListener (listenerToAdd);
|
||||
}
|
||||
|
||||
void CameraDevice::removeListener (Listener* listenerToRemove)
|
||||
{
|
||||
if (listenerToRemove != nullptr)
|
||||
pimpl->removeListener (listenerToRemove);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
StringArray CameraDevice::getAvailableDevices()
|
||||
{
|
||||
|
|
@ -94,12 +194,44 @@ CameraDevice* CameraDevice::openDevice (int index,
|
|||
int maxWidth, int maxHeight,
|
||||
bool useHighQuality)
|
||||
{
|
||||
jassert (juce::MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
#if ! JUCE_ANDROID && ! JUCE_IOS
|
||||
std::unique_ptr<CameraDevice> d (new CameraDevice (getAvailableDevices() [index], index,
|
||||
minWidth, minHeight, maxWidth, maxHeight, useHighQuality));
|
||||
if (d != nullptr && d->pimpl->openedOk())
|
||||
return d.release();
|
||||
#else
|
||||
ignoreUnused (index, minWidth, minHeight);
|
||||
ignoreUnused (maxWidth, maxHeight, useHighQuality);
|
||||
|
||||
// Use openDeviceAsync to open a camera device on iOS or Android.
|
||||
jassertfalse;
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CameraDevice::openDeviceAsync (int index, OpenCameraResultCallback resultCallback,
|
||||
int minWidth, int minHeight, int maxWidth, int maxHeight, bool useHighQuality)
|
||||
{
|
||||
jassert (juce::MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
if (resultCallback == nullptr)
|
||||
{
|
||||
// A valid callback must be passed.
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
CameraFactory::getInstance().openCamera (index, static_cast<OpenCameraResultCallback&&> (resultCallback),
|
||||
minWidth, minHeight, maxWidth, maxHeight, useHighQuality);
|
||||
#else
|
||||
auto* device = openDevice (index, minWidth, minHeight, maxWidth, maxHeight, useHighQuality);
|
||||
|
||||
resultCallback (device, device != nullptr ? String() : "Could not open camera device");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ namespace juce
|
|||
Controls any video capture devices that might be available.
|
||||
|
||||
Use getAvailableDevices() to list the devices that are attached to the
|
||||
system, then call openDevice to open one for use. Once you have a CameraDevice
|
||||
object, you can get a viewer component from it, and use its methods to
|
||||
stream to a file or capture still-frames.
|
||||
system, then call openDevice() or openDeviceAsync() to open one for use.
|
||||
Once you have a CameraDevice object, you can get a viewer component from it,
|
||||
and use its methods to stream to a file or capture still-frames.
|
||||
|
||||
@tags{Video}
|
||||
*/
|
||||
|
|
@ -50,17 +50,18 @@ public:
|
|||
//==============================================================================
|
||||
/** Returns a list of the available cameras on this machine.
|
||||
|
||||
You can open one of these devices by calling openDevice().
|
||||
You can open one of these devices by calling openDevice() or openDeviceAsync().
|
||||
*/
|
||||
static StringArray getAvailableDevices();
|
||||
|
||||
/** Opens a camera device.
|
||||
/** Synchronously opens a camera device. This function should not be used on iOS or
|
||||
Android, use openDeviceAsync() instead.
|
||||
|
||||
The index parameter indicates which of the items returned by getAvailableDevices()
|
||||
to open.
|
||||
|
||||
The size constraints allow the method to choose between different resolutions if
|
||||
the camera supports this. If the resolution cam't be specified (e.g. on the Mac)
|
||||
the camera supports this. If the resolution can't be specified (e.g. on the Mac)
|
||||
then these will be ignored.
|
||||
|
||||
On Mac, if highQuality is false, then the camera will be opened in preview mode
|
||||
|
|
@ -72,16 +73,62 @@ public:
|
|||
int maxWidth = 1024, int maxHeight = 768,
|
||||
bool highQuality = true);
|
||||
|
||||
using OpenCameraResultCallback = std::function<void (CameraDevice*, const String& /*error*/)>;
|
||||
|
||||
/** Asynchronously opens a camera device on iOS (iOS 7+) or Android (API 21+).
|
||||
On other platforms, the function will simply call openDevice(). Upon completion,
|
||||
resultCallback will be invoked with valid CameraDevice* and an empty error
|
||||
String on success, or nullptr CameraDevice and a non-empty error String on failure.
|
||||
|
||||
This is the preferred method of opening a camera device, because it works on all
|
||||
platforms, whereas synchronous openDevice() does not work on iOS & Android.
|
||||
|
||||
The index parameter indicates which of the items returned by getAvailableDevices()
|
||||
to open.
|
||||
|
||||
The size constraints allow the method to choose between different resolutions if
|
||||
the camera supports this. If the resolution can't be specified then these will be
|
||||
ignored.
|
||||
|
||||
On iOS, if you want to switch a device, it is more efficient to open a new device
|
||||
before closing the older one, because this way both devices can share the same
|
||||
underlying camera session. Otherwise, the session needs to be close first, and this
|
||||
is a lengthy process that can take several seconds.
|
||||
|
||||
The Android implementation currently supports a maximum recording resolution of
|
||||
1080p. Choosing a larger size will result in larger pictures taken, but the video
|
||||
will be capped at 1080p.
|
||||
*/
|
||||
static void openDeviceAsync (int deviceIndex,
|
||||
OpenCameraResultCallback resultCallback,
|
||||
int minWidth = 128, int minHeight = 64,
|
||||
int maxWidth = 1024, int maxHeight = 768,
|
||||
bool highQuality = true);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the name of this device */
|
||||
const String& getName() const noexcept { return name; }
|
||||
|
||||
/** Creates a component that can be used to display a preview of the
|
||||
video from this camera.
|
||||
|
||||
Note: while you can change the size of the preview component, the actual
|
||||
preview display may be smaller than the size requested, because the correct
|
||||
aspect ratio is maintained automatically.
|
||||
*/
|
||||
Component* createViewerComponent();
|
||||
|
||||
//==============================================================================
|
||||
/** Triggers a still picture capture. Upon completion, pictureTakenCallback will
|
||||
be invoked on a message thread.
|
||||
|
||||
On Android, before calling takeStillPicture(), you need to create a preview with
|
||||
createViewerComponent() and you need to make it visible on screen.
|
||||
|
||||
Android does not support simultaneous video recording and still picture capture.
|
||||
*/
|
||||
void takeStillPicture (std::function<void (const Image&)> pictureTakenCallback);
|
||||
|
||||
/** Starts recording video to the specified file.
|
||||
|
||||
You should use getFileExtension() to find out the correct extension to
|
||||
|
|
@ -95,6 +142,16 @@ public:
|
|||
|
||||
The quality parameter can be 0, 1, or 2, to indicate low, medium, or high. It may
|
||||
or may not be used, depending on the driver.
|
||||
|
||||
On Android, before calling startRecordingToFile(), you need to create a preview with
|
||||
createViewerComponent() and you need to make it visible on screen.
|
||||
|
||||
The Android camera also requires exclusive access to the audio device, so make sure
|
||||
you close any open audio devices with AudioDeviceManager::closeAudioDevice() first.
|
||||
|
||||
Android does not support simultaneous video recording and still picture capture.
|
||||
|
||||
@see AudioDeviceManager::closeAudioDevice, AudioDeviceManager::restartLastAudioDevice
|
||||
*/
|
||||
void startRecordingToFile (const File& file, int quality = 2);
|
||||
|
||||
|
|
@ -113,36 +170,9 @@ public:
|
|||
*/
|
||||
Time getTimeOfFirstRecordedFrame() const;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Receives callbacks with images from a CameraDevice.
|
||||
|
||||
@see CameraDevice::addListener
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
Listener() {}
|
||||
virtual ~Listener() {}
|
||||
|
||||
/** This method is called when a new image arrives.
|
||||
|
||||
This may be called by any thread, so be careful about thread-safety,
|
||||
and make sure that you process the data as quickly as possible to
|
||||
avoid glitching!
|
||||
*/
|
||||
virtual void imageReceived (const Image& image) = 0;
|
||||
};
|
||||
|
||||
/** Adds a listener to receive images from the camera.
|
||||
|
||||
Be very careful not to delete the listener without first removing it by calling
|
||||
removeListener().
|
||||
*/
|
||||
void addListener (Listener* listenerToAdd);
|
||||
|
||||
/** Removes a listener that was previously added with addListener(). */
|
||||
void removeListener (Listener* listenerToRemove);
|
||||
/** Set this callback to be notified whenever an error occurs. You may need to close
|
||||
and reopen the device to be able to use it further. */
|
||||
std::function<void (const String& /*error*/)> onErrorOccurred;
|
||||
|
||||
private:
|
||||
String name;
|
||||
|
|
@ -158,6 +188,32 @@ private:
|
|||
CameraDevice (const String& name, int index,
|
||||
int minWidth, int minHeight, int maxWidth, int maxHeight, bool highQuality);
|
||||
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
class CameraFactory;
|
||||
#endif
|
||||
|
||||
#if JUCE_ANDROID
|
||||
friend void juce_cameraDeviceStateClosed (int64);
|
||||
friend void juce_cameraDeviceStateDisconnected (int64);
|
||||
friend void juce_cameraDeviceStateError (int64, int);
|
||||
friend void juce_cameraDeviceStateOpened (int64, void*);
|
||||
|
||||
friend void juce_cameraCaptureSessionActive (int64, void*);
|
||||
friend void juce_cameraCaptureSessionClosed (int64, void*);
|
||||
friend void juce_cameraCaptureSessionConfigureFailed (int64, void*);
|
||||
friend void juce_cameraCaptureSessionConfigured (int64, void*);
|
||||
friend void juce_cameraCaptureSessionReady (int64, void*);
|
||||
|
||||
friend void juce_cameraCaptureSessionCaptureCompleted (int64, bool, void*, void*, void*);
|
||||
friend void juce_cameraCaptureSessionCaptureFailed (int64, bool, void*, void*, void*);
|
||||
friend void juce_cameraCaptureSessionCaptureProgressed (int64, bool, void*, void*, void*);
|
||||
friend void juce_cameraCaptureSessionCaptureSequenceAborted (int64, bool, void*, int);
|
||||
friend void juce_cameraCaptureSessionCaptureSequenceCompleted (int64, bool, void*, int, int64);
|
||||
friend void juce_cameraCaptureSessionCaptureStarted (int64, bool, void*, void*, int64, int64);
|
||||
|
||||
friend void juce_deviceOrientationChanged (int64, int);
|
||||
#endif
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CameraDevice)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -59,13 +59,23 @@
|
|||
|
||||
//=============================================================================
|
||||
/** Config: JUCE_USE_CAMERA
|
||||
Enables web-cam support using the CameraDevice class (Mac and Windows).
|
||||
Enables camera support using the CameraDevice class (Mac, Windows, iOS, Android).
|
||||
*/
|
||||
#ifndef JUCE_USE_CAMERA
|
||||
#define JUCE_USE_CAMERA 0
|
||||
#endif
|
||||
|
||||
#if ! (JUCE_MAC || JUCE_WINDOWS)
|
||||
#ifndef JUCE_CAMERA_LOG_ENABLED
|
||||
#define JUCE_CAMERA_LOG_ENABLED 0
|
||||
#endif
|
||||
|
||||
#if JUCE_CAMERA_LOG_ENABLED
|
||||
#define JUCE_CAMERA_LOG(x) DBG(x)
|
||||
#else
|
||||
#define JUCE_CAMERA_LOG(x) {}
|
||||
#endif
|
||||
|
||||
#if ! (JUCE_MAC || JUCE_WINDOWS || JUCE_IOS || JUCE_ANDROID)
|
||||
#undef JUCE_USE_CAMERA
|
||||
#endif
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1288
modules/juce_video/native/juce_ios_CameraDevice.h
Normal file
1288
modules/juce_video/native/juce_ios_CameraDevice.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -26,8 +26,9 @@
|
|||
|
||||
struct CameraDevice::Pimpl
|
||||
{
|
||||
Pimpl (const String&, int /*index*/, int /*minWidth*/, int /*minHeight*/,
|
||||
Pimpl (CameraDevice& ownerToUse, const String&, int /*index*/, int /*minWidth*/, int /*minHeight*/,
|
||||
int /*maxWidth*/, int /*maxHeight*/, bool useHighQuality)
|
||||
: owner (ownerToUse)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
|
|
@ -42,11 +43,20 @@ struct CameraDevice::Pimpl
|
|||
static DelegateClass cls;
|
||||
callbackDelegate = (id<AVCaptureFileOutputRecordingDelegate>) [cls.createInstance() init];
|
||||
DelegateClass::setOwner (callbackDelegate, this);
|
||||
|
||||
SEL runtimeErrorSel = NSSelectorFromString (nsStringLiteral ("captureSessionRuntimeError:"));
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver: callbackDelegate
|
||||
selector: runtimeErrorSel
|
||||
name: AVCaptureSessionRuntimeErrorNotification
|
||||
object: session];
|
||||
}
|
||||
}
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: callbackDelegate];
|
||||
|
||||
[session stopRunning];
|
||||
removeImageCapture();
|
||||
removeMovieCapture();
|
||||
|
|
@ -113,6 +123,19 @@ struct CameraDevice::Pimpl
|
|||
refreshConnections();
|
||||
}
|
||||
|
||||
void takeStillPicture (std::function<void (const Image&)> pictureTakenCallbackToUse)
|
||||
{
|
||||
if (pictureTakenCallbackToUse == nullptr)
|
||||
{
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
pictureTakenCallback = static_cast<std::function<void (const Image&)>&&> (pictureTakenCallbackToUse);
|
||||
|
||||
triggerImageCapture();
|
||||
}
|
||||
|
||||
void startRecordingToFile (const File& file, int /*quality*/)
|
||||
{
|
||||
stopRecording();
|
||||
|
|
@ -150,21 +173,10 @@ struct CameraDevice::Pimpl
|
|||
return nil;
|
||||
}
|
||||
|
||||
void handleImageCapture (const void* data, size_t size)
|
||||
void handleImageCapture (const Image& image)
|
||||
{
|
||||
auto image = ImageFileFormat::loadFrom (data, size);
|
||||
|
||||
const ScopedLock sl (listenerLock);
|
||||
|
||||
if (! listeners.isEmpty())
|
||||
{
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
if (auto* l = listeners[i])
|
||||
l->imageReceived (image);
|
||||
|
||||
if (! listeners.isEmpty())
|
||||
triggerImageCapture();
|
||||
}
|
||||
if (pictureTakenCallback != nullptr)
|
||||
pictureTakenCallback (image);
|
||||
}
|
||||
|
||||
void triggerImageCapture()
|
||||
|
|
@ -174,33 +186,25 @@ struct CameraDevice::Pimpl
|
|||
if (auto* videoConnection = getVideoConnection())
|
||||
{
|
||||
[imageOutput captureStillImageAsynchronouslyFromConnection: videoConnection
|
||||
completionHandler: ^(CMSampleBufferRef sampleBuffer, NSError*)
|
||||
completionHandler: ^(CMSampleBufferRef sampleBuffer, NSError* error)
|
||||
{
|
||||
auto buffer = CMSampleBufferGetDataBuffer (sampleBuffer);
|
||||
size_t size = CMBlockBufferGetDataLength (buffer);
|
||||
jassert (CMBlockBufferIsRangeContiguous (buffer, 0, size)); // TODO: need to add code to handle this if it happens
|
||||
char* data = nullptr;
|
||||
CMBlockBufferGetDataPointer (buffer, 0, &size, nullptr, &data);
|
||||
handleImageCapture (data, size);
|
||||
if (error != nil)
|
||||
{
|
||||
JUCE_CAMERA_LOG ("Still picture capture failed, error: " + nsStringToJuce (error.localizedDescription));
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation: sampleBuffer];
|
||||
|
||||
auto image = ImageFileFormat::loadFrom (imageData.bytes, (size_t) imageData.length);
|
||||
|
||||
WeakReference<Pimpl> weakRef (this);
|
||||
MessageManager::callAsync ([weakRef, image]() mutable { if (weakRef != nullptr) weakRef->handleImageCapture (image); });
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
void addListener (CameraDevice::Listener* listenerToAdd)
|
||||
{
|
||||
const ScopedLock sl (listenerLock);
|
||||
listeners.addIfNotAlreadyThere (listenerToAdd);
|
||||
|
||||
if (listeners.size() == 1)
|
||||
triggerImageCapture();
|
||||
}
|
||||
|
||||
void removeListener (CameraDevice::Listener* listenerToRemove)
|
||||
{
|
||||
const ScopedLock sl (listenerLock);
|
||||
listeners.removeFirstMatchingValue (listenerToRemove);
|
||||
}
|
||||
|
||||
static StringArray getAvailableDevices()
|
||||
{
|
||||
StringArray results;
|
||||
|
|
@ -208,6 +212,15 @@ struct CameraDevice::Pimpl
|
|||
return results;
|
||||
}
|
||||
|
||||
void cameraSessionRuntimeError (const String& error)
|
||||
{
|
||||
JUCE_CAMERA_LOG ("cameraSessionRuntimeError(), error = " + error);
|
||||
|
||||
if (owner.onErrorOccurred != nullptr)
|
||||
owner.onErrorOccurred (error);
|
||||
}
|
||||
|
||||
CameraDevice& owner;
|
||||
AVCaptureView* captureView = nil;
|
||||
AVCaptureSession* session = nil;
|
||||
AVCaptureMovieFileOutput* fileOutput = nil;
|
||||
|
|
@ -218,8 +231,9 @@ struct CameraDevice::Pimpl
|
|||
Time firstPresentationTime;
|
||||
bool isRecording = false;
|
||||
|
||||
Array<CameraDevice::Listener*> listeners;
|
||||
CriticalSection listenerLock;
|
||||
std::function<void (const Image&)> pictureTakenCallback;
|
||||
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE (Pimpl)
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
|
|
@ -235,17 +249,29 @@ private:
|
|||
addMethod (@selector (captureOutput:didResumeRecordingToOutputFileAtURL: fromConnections:), didResumeRecordingToOutputFileAtURL, "v@:@@@");
|
||||
addMethod (@selector (captureOutput:willFinishRecordingToOutputFileAtURL:fromConnections:error:), willFinishRecordingToOutputFileAtURL, "v@:@@@@");
|
||||
|
||||
SEL runtimeErrorSel = NSSelectorFromString (nsStringLiteral ("captureSessionRuntimeError:"));
|
||||
addMethod (runtimeErrorSel, sessionRuntimeError, "v@:@");
|
||||
|
||||
registerClass();
|
||||
}
|
||||
|
||||
static void setOwner (id self, Pimpl* owner) { object_setInstanceVariable (self, "owner", owner); }
|
||||
static Pimpl* getOwner (id self) { return getIvar<Pimpl*> (self, "owner"); }
|
||||
static Pimpl& getOwner (id self) { return *getIvar<Pimpl*> (self, "owner"); }
|
||||
|
||||
private:
|
||||
static void didStartRecordingToOutputFileAtURL (id, SEL, AVCaptureFileOutput*, NSURL*, NSArray*) {}
|
||||
static void didPauseRecordingToOutputFileAtURL (id, SEL, AVCaptureFileOutput*, NSURL*, NSArray*) {}
|
||||
static void didResumeRecordingToOutputFileAtURL (id, SEL, AVCaptureFileOutput*, NSURL*, NSArray*) {}
|
||||
static void willFinishRecordingToOutputFileAtURL (id, SEL, AVCaptureFileOutput*, NSURL*, NSArray*, NSError*) {}
|
||||
|
||||
static void sessionRuntimeError (id self, SEL, NSNotification* notification)
|
||||
{
|
||||
JUCE_CAMERA_LOG (nsStringToJuce ([notification description]));
|
||||
|
||||
NSError* error = notification.userInfo[AVCaptureSessionErrorKey];
|
||||
auto errorString = error != nil ? nsStringToJuce (error.localizedDescription) : String();
|
||||
getOwner (self).cameraSessionRuntimeError (errorString);
|
||||
}
|
||||
};
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (Pimpl)
|
||||
|
|
|
|||
|
|
@ -49,10 +49,11 @@ static const CLSID CLSID_NullRenderer = { 0xC1F400A4, 0x3F08, 0x11d3, { 0x9F, 0
|
|||
|
||||
struct CameraDevice::Pimpl : public ChangeBroadcaster
|
||||
{
|
||||
Pimpl (const String&, int index,
|
||||
int minWidth, int minHeight,
|
||||
int maxWidth, int maxHeight, bool /*highQuality*/)
|
||||
: isRecording (false),
|
||||
Pimpl (CameraDevice& ownerToUse, const String&, int index,
|
||||
int minWidth, int minHeight, int maxWidth, int maxHeight,
|
||||
bool /*highQuality*/)
|
||||
: owner (ownerToUse),
|
||||
isRecording (false),
|
||||
openedSuccessfully (false),
|
||||
imageNeedsFlipping (false),
|
||||
width (0), height (0),
|
||||
|
|
@ -191,6 +192,22 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
|
||||
bool openedOk() const noexcept { return openedSuccessfully; }
|
||||
|
||||
void takeStillPicture (std::function<void (const Image&)> pictureTakenCallbackToUse)
|
||||
{
|
||||
{
|
||||
const ScopedLock sl (callbackLock);
|
||||
|
||||
jassert (pictureTakenCallbackToUse != nullptr);
|
||||
|
||||
if (pictureTakenCallbackToUse == nullptr)
|
||||
return;
|
||||
|
||||
pictureTakenCallback = static_cast<std::function<void (const Image&)>&&> (pictureTakenCallbackToUse);
|
||||
}
|
||||
|
||||
addUser();
|
||||
}
|
||||
|
||||
void startRecordingToFile (const File& file, int quality)
|
||||
{
|
||||
addUser();
|
||||
|
|
@ -212,32 +229,26 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
return firstRecordedTime;
|
||||
}
|
||||
|
||||
void addListener (CameraDevice::Listener* listenerToAdd)
|
||||
void notifyImageReceivedIfNeeded (const Image& image)
|
||||
{
|
||||
const ScopedLock sl (listenerLock);
|
||||
{
|
||||
const ScopedLock sl (callbackLock);
|
||||
|
||||
if (listeners.size() == 0)
|
||||
addUser();
|
||||
if (pictureTakenCallback == nullptr)
|
||||
return;
|
||||
}
|
||||
|
||||
listeners.addIfNotAlreadyThere (listenerToAdd);
|
||||
}
|
||||
WeakReference<Pimpl> weakRef (this);
|
||||
MessageManager::callAsync ([weakRef, image]() mutable
|
||||
{
|
||||
if (weakRef == nullptr)
|
||||
return;
|
||||
|
||||
void removeListener (CameraDevice::Listener* listenerToRemove)
|
||||
{
|
||||
const ScopedLock sl (listenerLock);
|
||||
listeners.removeAllInstancesOf (listenerToRemove);
|
||||
if (weakRef->pictureTakenCallback != nullptr)
|
||||
weakRef->pictureTakenCallback (image);
|
||||
|
||||
if (listeners.size() == 0)
|
||||
removeUser();
|
||||
}
|
||||
|
||||
void callListeners (const Image& image)
|
||||
{
|
||||
const ScopedLock sl (listenerLock);
|
||||
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
if (CameraDevice::Listener* const l = listeners[i])
|
||||
l->imageReceived (image);
|
||||
weakRef->pictureTakenCallback = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
void addUser()
|
||||
|
|
@ -294,8 +305,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
imageNeedsFlipping = true;
|
||||
}
|
||||
|
||||
if (listeners.size() > 0)
|
||||
callListeners (loadingImage);
|
||||
notifyImageReceivedIfNeeded (loadingImage);
|
||||
|
||||
sendChangeMessage();
|
||||
}
|
||||
|
|
@ -520,9 +530,9 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
JUCE_DECLARE_NON_COPYABLE (GrabberCallback)
|
||||
};
|
||||
|
||||
CameraDevice& owner;
|
||||
|
||||
ComSmartPtr<GrabberCallback> callback;
|
||||
Array<CameraDevice::Listener*> listeners;
|
||||
CriticalSection listenerLock;
|
||||
|
||||
bool isRecording, openedSuccessfully;
|
||||
int width, height;
|
||||
|
|
@ -547,6 +557,11 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
|
|||
bool recordNextFrameTime;
|
||||
int previewMaxFPS;
|
||||
|
||||
CriticalSection callbackLock;
|
||||
std::function<void (const Image&)> pictureTakenCallback;
|
||||
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE (Pimpl)
|
||||
|
||||
private:
|
||||
void getVideoSizes (IAMStreamConfig* const streamConfig)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
/** Tries to load a video from a local file.
|
||||
@returns am error if the file failed to be loaded correctly
|
||||
@returns an error if the file failed to be loaded correctly
|
||||
*/
|
||||
Result load (const File& file);
|
||||
|
||||
/** Tries to load a video from a URL.
|
||||
@returns am error if the file failed to be loaded correctly
|
||||
@returns an error if the file failed to be loaded correctly
|
||||
*/
|
||||
Result load (const URL& url);
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ public:
|
|||
File getCurrentVideoFile() const;
|
||||
|
||||
/** Returns the last URL that was loaded.
|
||||
If nothing is open, or if it was a file rather than a URL, this will return File().
|
||||
If nothing is open, or if it was a file rather than a URL, this will return URL().
|
||||
*/
|
||||
URL getCurrentVideoURL() const;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue